实践如下:
1.配置主库my.cnf
[mysqld]  
log-bin=mysql-testsyn-bin --主库二进制日志文件名的前缀  
binlog-do-db=wb      --要同步的数据库  
server-id = 1             --serverid和辅库不同即可  
修改为:




主库加帐号,10.51.178.1** 内网IP可以来访问,创建用户slave.拥有replication slave权限:
grant replication slave on *.* to "slave"@"10.51.178.1**" identified by "123FFFCCC6" with grant option;  
用PHPMyadmin看也就是这两项权限: GRANT  REPLICATION SLAVE ,不需要插入修改删除啥的,最小化。
查看主库状态:
show master status;  
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000007 |  1606516 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+


配置辅库:
server-id = 2  
master-host = 10.51.180.**  
master-user = slave    
master-password = 123FFFCCC6  
master-port = 3306  
master-connect-retry = 5  --重试间隔时间  
replicate-do-db = wb    --同步db


启动mysql ,查看辅库状态:
show slave status;

说明:
Slave_IO_Running:连接到主库,并读取主库的日志到本地,生成本地日志文件
Slave_SQL_Running:读取本地日志文件,并执行日志里的sql


把主库上的数据dump到辅库上
主库:10.51.180.**:
mysqldump --opt --master-data -uroot -p123FFFCCC6 > /home/mahaibo/dump-testsyn &

注意参数:--master-data

辅库:10.51.178.1**
先建立库:create database wb;

导入前停止同步:
stop slave    
mysql -uroot -p123FFFCCC6 wb < /home/mahaibo/dump-testsyn    
start slave;  
必须先停止stop slave,然后才能导入
操作指南如下:
【=====================================
首先,关闭辅助库同步:
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)

其次,从主机上导出sql并在辅机上执行和主机一样。

第三,清空主机上所有位置: reset master;
mysql> reset master;
Query OK, 0 rows affected (0.01 sec)

mysql> show master status\G;
*************************** 1. row ***************************
             File: mysql-bin.000001
         Position: 120
     Binlog_Do_DB: wb
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
辅机:
mysql> show slave status\G;
Read_Master_Log_Pos: 4

第四,清空辅库的bin-log位置:
mysql> reset slave;
Query OK, 0 rows affected (0.00 sec)

第五,打开辅库的slave同步线程:
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

第六,看到辅库和主库的Read_Master_Log_Pos= 120 ,如下:
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.51.180.220
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 120
==============================================】
4.在主库10.51.180.**上在wb.user表里插入一条数据:
insert into users (username,password) values ('test1','test1');

辅库上的users表里也相应的有了数据。

5.查看主库二进制日志文件内容:
show binlog events;



注意:
1.主辅库同步主要是通过二进制日志来实现同步的。
2.在启动辅库的时候必须先把数据同步,并删除日志目录下的:master.info文件。因为master.info记录了上次要连接主库的信息,如果不删除,即使my.cnf里进行了修改,也不起作用。因为读取的还是master.info文件里的信息。



MySQL运行时间长了之后,二进制日志会占用大量硬盘空间,清楚这些日志的命令如下:
show binary logs;
purge master logs before now();
mysql> purge master logs before now();
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000004 |     46653 |
+------------------+-----------+
1 row in set (0.00 sec)


reset master 将删除日志索引文件中记录的所有binlog文件,创建一个新的日志文件 起始值从000001 开始,然而purge binary log 命令并不会修改记录binlog的顺序的数值
上面还有一个没有清掉,得用这个就彻底清了,120:
mysql> reset master;
Query OK, 0 rows affected (0.00 sec)
mysql> reset master;
Query OK, 0 rows affected (0.01 sec)

mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       120 |
+------------------+-----------+
1 row in set (0.00 sec)

mysql> RESET SLAVE
    -> ;
Query OK, 0 rows affected (0.00 sec)

http://www.shangxueba.com/jingyan/1638441.html


————————————参考实践自如下链接————————————————————
http://blog.csdn.net/ljx0305/article/details/4371655
http://wenku.baidu.com/link?url=rK2b1ofBZnxgoQF5rW0JcjwU7Cn-WT6AuH_E29sOkgKDkEYeJQ6E5XGgt-NzAaYxuPzx25I_qJCB9Xe3F6QKTtILymCkKzFrEUi9rY_xtyO


新版本不支持master-host参数,[ERROR] /usr/local/mysql/bin/mysqld: unknown variable 'master-host=10.51.180.2**':
------解决方案--------------------
Mysql版本从5.1.7以后开始就不支持“master-host”类似的参数
在从库上执行如下命令;
change master to master_host='masterIP', master_user='slave', master_password='slvaePASS';
slave start;
切记:
此处是masterIP地址,不是slave地址,而登陆账号为slave账号密码
------解决方案--------------------
master-host=192.168.8.111
master-user=backup
master-password=backup
master-port=3306
master-connect-retry=60


这些参数 mysql5.5已经废弃了  

必须在slave上用change master to 来设置slave



server-id = 2
#master-host = 10.51.180.**  新版本废弃
#master-user = slave
#master-password = 123FFFCCC6
#master-port = 3306
#master-connect-retry = 5
replicate-do-db = wb

mysql> change master to master_host='10.51.180.**', master_user='slave', master_password='123FFFCCC6';
Query OK, 0 rows affected, 2 warnings (0.02 sec)


mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Connecting to master
                  Master_Host: 10.51.180.**
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File:
          Read_Master_Log_Pos: 4
               Relay_Log_File: mysql-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File:
             Slave_IO_Running: Connecting
            Slave_SQL_Running: Yes
              Replicate_Do_DB: wb
           .......
说明成功了,因为参数已经是Connecting和yes了:
Slave_IO_Running:连接到主库,并读取主库的日志到本地,生成本地日志文件
Slave_SQL_Running:读取本地日志文件,并执行日志里的sql

但此时还没有库,只是连接成功,于是,得从主库拉出数据,并停止辅库:
mysql> show databases; //slave没有wb表
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)

照猫画虎建一个wb库:
mysql> show create database mysql;
+----------+----------------------------------------------------------------+
| Database | Create Database                                                |
+----------+----------------------------------------------------------------+
| mysql    | CREATE DATABASE `mysql` /*!40100 DEFAULT CHARACTER SET utf8 */ |
+----------+----------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> CREATE DATABASE `wb` /*!40100 DEFAULT CHARACTER SET utf8 */ ;  
Query OK, 1 row affected (0.00 sec)

从master下的mysql里导出表及数据sql:
10.51.180.**
mysqldump -uroot -p wb > wb2slave.09.24.sql
scp上步导出的sql到slave目录里source导入:
scp root@10.51.180.**:/root/wb2slave.09.24.sql  ./
导入到刚才在slave建立的wb 库里:
mysql -uroot -p
mysql> use wb;
mysql> stop slave
Database changed
mysql> set names utf8;
Query OK, 0 rows affected (0.00 sec)
mysql> source /root/wb2slave.09.24.sql
Query OK, 0 rows affected (0.00 sec)
导入完成后,启动slave:
mysql>  start slave;
Query OK, 0 rows affected (0.00 sec)

清掉刚才导入之前的,主库里的bin-log:
mysql> PURGE MASTER LOGS BEFORE '2015-09-24 17:05:00';        
Query OK, 0 rows affected, 1 warning (0.00 sec)


mysql>  show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000008 |      1222 |
+------------------+-----------+
mysql-bin.000007没有了,mysql-bin.000008一个了。
其它清理方法如下:
清除3天前的 binlog
PURGE MASTER LOGS BEFORE DATE_SUB( NOW( ), INTERVAL 3 DAY);
清指定文件的bin-log:
PURGE MASTER LOGS TO 'mysql-bin.000008';

清理MySQL的bin-log二进制日志
Posted by zuzhihui in mysql on 2011/11/27 with No Comments
MySQL运行时间长了之后,二进制日志会占用大量硬盘空间,清楚这些日志的命令如下:
show binary logs;
purge master logs before now();


重置mysql主从同步(MySQL Reset Master-Slave Replication):
reset master;
mysql>  show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       120 |
+------------------+-----------+
http://www.shangxueba.com/jingyan/1638441.html

发现内外网不一致,加个外网:
Last_IO_Error: error connecting to master 'slave@10.51.180.220:3306' - retry-time: 60  retries: 1
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it

grant replication slave on *.* to "slave"@"10.51.180.*" identified by "123FFFCCC6" with grant option
grant replication slave on *.* to "slave"@"101.200.1.*" identified by "123FFFCCC6" with grant option
flush privileges;

一台服务器有内网ip和外网ip,如何通过iptables禁止访问本机的外网ip的某个端口,比如3306端口?

iptables防火墙 只允许某IP访问某端口、访问特定网站:
+++++++++++++++++主库:eth0 : 10.51.180.220++++++++++++++++++++++++++
让辅库IP10.51.178.1** 能访问到主的3306端口:
iptables -I INPUT -s 10.51.178.1** -p tcp --dport 3306 -j ACCEPT
写到开机启动里头 vi /etc/rc.local:
#开机就放开内部Mysql端口:让辅库内网IP能访问到该机器的3306备份端口
/usr/sbin/iptables -I INPUT -s 10.51.178.1** -p tcp --dport 3306 -j ACCEPT
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

http://www.sunzhenghua.com/msyql-grant-user-master-slave-replication-copy
参考:http://www.myexception.cn/mysql/387629.html
========================================================================

防火墙问题引起,Telnet 时出现,No route to host:
telnet :No route to host
telnet 10.51.180.** 3306
Trying 10.51.180.**...
telnet: connect to address 10.51.180.**: No route to host
[root@iZ258cfosv4Z ~]# telnet 10.51.180.** 3306
http://blog.sina.com.cn/s/blog_5022501501010pin.html

10.51.180.**       //在主库上关闭掉iptables即可。
/bin/systemctl stop  iptables.service

10.51.178.128
telnet 10.51.180.** 3306
Trying 10.51.180.**...
Connected to 10.51.180.**.
Escape character is '^]'.
测试连接:
mysql -uroot -h10.51.180.** -p
再测试这个,OK也就行了:
mysql -uslave -h10.51.180.** -p


show slave status\G;
Master_UUID: fef2f186-1fc5-11e5-9cb7-00163e0003e7
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it

change master to master_host='10.51.180.**', master_user='slave', master_password='123FFFCCC6';

Slave_IO_State: Waiting for master to send event
Master_Host: 10.51.180.**
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Read_Master_Log_Pos: 9687
Relay_Log_Pos: 820
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB: wb


_________________________________________________________________________________
Could not find first log file name in binary log index file'的解决办法
数据库主从出错:
Slave_IO_Running:  No 一方面原因是因为网络通信的问题也有可能是日志读取错误的问题。以下是日志出错问题的解决方案:

Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'

解决办法:
从机器停止slave
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)


mysql> reset master;
Query OK, 0 rows affected (0.00 sec)
mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       120 |
+------------------+-----------+

到master机器登陆mysql:
记录master的bin的位置,mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      120 | wb           |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

刷新日志:mysql> flush logs;
因为刷新日志file的位置会+1,即File变成为:mysqld-bin.000011

马上到slave执行
mysql> CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=120;                
Query OK, 0 rows affected (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\G;
mysql>  show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.51.180.**
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 120
               Relay_Log_File: mysql-relay-bin.000002
                Relay_Log_Pos: 283
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: wb
             Master_Server_Id: 1
                  Master_UUID: fef2f186-1fc5-11e5-9cb7-00163e0003e7
             Master_Info_File: /data/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind:

正常了。
diff 用过吗?老大让我a.log b.log 比较出相同,后将相同从a.log中去掉,然后显示出剩下的放入到文件x.log

==> a.log <==
1
3
2

==> b.log <==
5
4
2
3


sort a.log >> aa.log
sort b.log >> bb.log
diff aa.log bb.log |grep "<" >> x.log
//还好老大给出了这个比较方法。。

[code]diff aa.log bb.log 结果如何记忆?  <:表示a独特有的,>:表示b独特有的!


aa.log中有1在bb.log中没有,于是<1,同样:bb.log有4,5在aa.log中没有,于是:>4 >5  :
[~]# diff aa.log bb.log                  
1d0
< 1
3a3,4
> 4
> 5
[/code]
假设文件有5列,我想按照第3列排序应该怎么使用sort命令呢?
sort -k 3 yourfile.txt


我现在写shell统计遇到一个问题, 比如一个文件a里是
1,02
2,05
这种格式
另一个文件b里是
3,02
5,05
这种格式,我想让如果a b 逗号后面(02或05)的相同的话, 则把 b的 逗号前面的(3或5) 放在 a 对应的后面
怎么做啊?
awk -F, 'NR==FNR{a[$2]=$1}NR>FNR{print $0","a[$2]}' fileb filea





我们再来个示例:
文件:a.txt b.txt

cat a.txt
[root@vm19 diff]# cat a.txt
asp
php
jsp
csp
zzz

cat b.txt
[root@vm19 diff]# cat b.txt
jsp
php
asp
csp
java
c
python

排序a.txt b.txt
sort b.txt >>bbb.txt
sort a.txt >>aaa.txt

[root@vm19 diff]# cat aaa.txt
asp
csp
jsp
php
zzz



[root@vm19 diff]# cat bbb.txt
asp
c
csp
java
jsp
php
python
diff一下:

[root@vm19 diff]# diff bbb.txt aaa.txt
2d1
< c
4d2
< java
7c5
< python
---
> zzz



找出bbb.txt和aaa.txt中bbb.txt和aaa.txt中多余的程序语言
diff bbb.txt aaa.txt|grep -r "<"
[root@vm19 diff]# diff bbb.txt aaa.txt|grep -r "<"
< c
< java
< python
找出bbb.txt和aaa.txt中bbb.txt和aaa.txt比较中bbb.txt中没有的
[root@vm19 diff]# diff bbb.txt aaa.txt|grep -r ">"
> zzz


一个语句完成也行:但是注意取出空行空格:
diff <(sort -n a.txt) <(sort -n b.txt)

=============================================
PS技巧:
如何过滤掉 “< ”

diff a.txt b.txt |grep "<"|awk -F"< " '{print $2}' > ddd.txt


务必参考:http://www.jackxiang.com/post/3484/
1. 准备

创建一个测试表:


mysql> CREATE TABLE `t` (
`d1` int(10) unsigned NOT NULL default '0',
`d2` timestamp NOT NULL default CURRENT_TIMESTAMP,
`d3` datetime NOT NULL,
KEY `d2` (`d2`),
KEY `d1` (`d1`),
KEY `d3` (`d3`)
);


然后创建一个存储过程填充数据:



mysql> DELIMITER //
CREATE PROCEDURE INS_T()
BEGIN
SET @i=1;
WHILE 0<1
DO
SET @i=@i+1;
INSERT INTO t VALUES (1199116800+@i, FROM_UNIXTIME(1199116800+@i), FROM_UNIXTIME(1199116800+@i));
END WHILE;
END;//
DELIMITER ;


run stroe process:

call INS_T();
时间戳 1199116800 表示 2008-01-01 这个时间点。然后运行存储过程,大概填充几十万条记录后,中止执行,因为上面的存储过程是个死循环,所以需要人工中止(ctrl+c)。
删除存储过程:
DROP PROCEDURE test.INS_T;


查看存储过程:


SHOW CREATE PROCEDURE  test.INS_T;


来看看到底有多少条记录了,以及索引情况:

mysql> select count(*) from t;
+----------+
| count(*) |
+----------+
|   924707 |
+----------+
mysql> analyze table t;
+--------+---------+----------+-----------------------------+
| Table  | Op      | Msg_type | Msg_text                    |
+--------+---------+----------+-----------------------------+
| test.t | analyze | status   | Table is already up to date |
+--------+---------+----------+-----------------------------+
mysql> show index from t;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| t     |          1 | d2       |            1 | d2          | A         |      924707 |     NULL | NULL   |      | BTREE      |         |
| t     |          1 | d1       |            1 | d1          | A         |      924707 |     NULL | NULL   |      | BTREE      |         |
| t     |          1 | d3       |            1 | d3          | A         |      924707 |     NULL | NULL   |      | BTREE      |         |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+



2. 对比

2.1 只检索一条记录


mysql> explain select * from t where d1 = 1199579155;
+----+-------------+-------+------+---------------+------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref   | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+-------+------+-------+
|  1 | SIMPLE      | t     | ref  | d1            | d1   | 4       | const |    1 |       |
+----+-------------+-------+------+---------------+------+---------+-------+------+-------+
mysql> explain select * from t where d2 = '2008-01-06 08:25:55';
+----+-------------+-------+------+---------------+------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref   | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+-------+------+-------+
|  1 | SIMPLE      | t     | ref  | d2            | d2   | 4       | const |    1 |       |
+----+-------------+-------+------+---------------+------+---------+-------+------+-------+
mysql> explain select * from t where d3 = '2008-01-06 08:25:55';
+----+-------------+-------+------+---------------+------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref   | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+-------+------+-------+
|  1 | SIMPLE      | t     | ref  | d3            | d3   | 8       | const |    1 |       |
+----+-------------+-------+------+---------------+------+---------+-------+------+-------+


2.2 范围检索(我发现当大于时候根本没有用到索引,小于用到了)
mysql> explain select * from t where d1 <= 1199894400;
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | t     | range | d1            | d1   | 4       | NULL | 121961 | Using where |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
mysql> explain select * from t where d2 <= from_unixtime(1199894400);
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | t     | range | d2            | d2   | 4       | NULL | 121961 | Using where |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
mysql> explain select * from t where d3 <= from_unixtime(1199894400);
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | t     | range | d3            | d3   | 8       | NULL | 120625 | Using where |
+----+-------------+-------+-------+---------------+------+---------+------+--------+-------------+

小贴士:
explain select * from t where d2 <= from_unixtime(1199894400);   key_len :为4
explain select * from t where d3 <= from_unixtime(1199894400);   key_len :为8
效率体现出来了吧?呵呵!



话外音:当大于时候根本没有用到索引,如下:(和下面in和=关于索引的情况类似,但这个> 和< 的情况我还是不太清楚,呵呵)

mysql>  explain select * from t where d1 >= 1199894400;
+----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows    | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
|  1 | SIMPLE      | t     | ALL  | d1            | NULL | NULL    | NULL | 9871898 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+---------+-------------+


mysql> explain select * from t where d2 >= from_unixtime(1199894400);
+----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows    | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
|  1 | SIMPLE      | t     | ALL  | d2            | NULL | NULL    | NULL | 9871898 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+---------+-------------+

mysql> explain select * from t where d3 >= from_unixtime(1199894400);
+----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows    | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
|  1 | SIMPLE      | t     | ALL  | d3            | NULL | NULL    | NULL | 9871898 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+---------+-------------+





小结:从上面的2次对比中可以看到,对 d1 或 d2 字段检索时的索引长度都是 4,因为 TIMESTAMP 实际上是 4字节 的 INT 值。因此,实际应用中,基本上完全可以采用 TIMESTAMP 来代替另外2种类型了,并且 TIMESTAMP 还能支持自动更新成当前最新时间,何乐而不为呢?




in 和 = 在索引上的区别,建表:

CREATE TABLE `mytest` (
  `id` int(11) NOT NULL auto_increment,
  `uid` int(11) NOT NULL,
  `rstatus` int(11) default NULL,
  PRIMARY KEY  (`id`),
  KEY `uid` (`uid`)
) ENGINE=MyISAM AUTO_INCREMENT=16 DEFAULT CHARSET=utf8



EXPLAIN SELECT *
FROM `mytest`
FORCE INDEX ( uid )
WHERE uid =1
AND rstatus =1


发现用上了uid的索引,但这个in语句:

explain SELECT * FROM `mytest`  WHERE uid IN ( 1,2,7) and rstatus =1

没有用上uid索引。

为此:认为要建立联合索引?是的,不光是要建立联合索引,而且和顺序有关,如建立:
alter table mytest add index tt(uid,rstatus);
也没有用,这样后运行:

explain SELECT * FROM `mytest`  WHERE uid IN ( 1,2,7) and rstatus =1

也没有用到我们想要的tt索引,但是,我们将联合索引换个顺序:
alter table mytest add index tt(rstatus,uid);

执行:
explain SELECT * FROM `mytest`  WHERE uid IN ( 1,2,7) and rstatus =1
,就用到了我们的联合索引了!
如下说明:
1.in 和 = 在索引机制上的不同!
2.in 的mysql索引和顺序有关!
最后:我去掉联合索引,加入了强制用uid的索引:
但:
SELECT * FROM `mytest` force index(uid) WHERE uid IN ( 1,2,7) and rstatus =1
也就ok了!




来源:
http://imysql.cn/2008_07_17_timestamp_vs_int_and_datetime
修正了存储过程的代码!



附录:
  

描述

CREATE PROCEDURE
  

建立一个存放在MySQL数据库的表格的存储过程。

CREATE FUNCTION
  

建立一个用户自定义的函数,尤其是返回数据的存储过程。

ALTER PROCEDURE
  

更改用CREATE PROCEDURE 建立的预先指定的存储过程,其不会影响相关存储过程或存储功能。.

ALTER FUNCTION
  

更改用CREATE FUNCTION 建立的预先指定的存储过程,其不会影响相关存储过程或存储功能。.

DROP PROCEDURE
  

从MySQL的表格中删除一个或多个存储过程。

DROP FUNCTION
  

从MySQL的表格中删除一个或多个存储函数。

SHOW CREATE PROCEDURE
  

返回使用CREATE PROCEDURE 建立的预先指定的存储过程的文本。这一声明是SQL:2003规范的一个MySQL扩展。

SHOW CREATE FUNCTION
  

返回使用CREATE  FUNCTION建立的预先指定的存储过程的文本。这一声明是SQL:2003规范的一个MySQL扩展。

SHOW PROCEDURE STATUS
  

返回一个预先指定的存储过程的特性,包括名称、类型、建立者、建立日期、以及更改日期。这一声明是SQL:2003规范的一个MySQL扩展。

SHOW FUNCTION STATUS
  

返回一个预先指定的存储函数的特性,包括名称、类型、建立者、建立日期、以及更改日期。这一声明是SQL:2003规范的一个MySQL扩展。

CALL
  

调用一个使用CREATE PROCEDURE建立的预先指定的存储过程。

BEGIN ... END
  

包含一组执行的多声明。

DECLARE
  

用于指定当地变量、环境、处理器,以及指针。

SET
  

用于更改当地和全局服务器变量的值。

SELECT ... INTO
  

用于存储显示变量的纵列。

OPEN
  

用于打开一个指针。

FETCH
  

使用特定指针来获得下一列。

CLOSE
  

用于关闭和打开指针。

IF
  

一个An if-then-else-end if 声明。

CASE ... WHEN
  

一个 case声明的结构

LOOP
  

一个简单的循环结构;可以使用LEAVE 语句来退出。

LEAVE
  

用于退出IF,CASE,LOOP,REPEAT以及WHILE 语句。

ITERATE
  

用于重新开始循环。

REPEAT
  

在结束时测试的循环。

WHILE
  

在开始时测试的循环。

RETURNS
  

返回一个存储过程的值。




















1.Linux/FreeBSD下用C语言开发PHP的so扩展模块例解:
http://www.toplee.com/blog/56.html
2.扩展实战 ------ 获得ip的来源地址:
http://my.huhoo.net/archives/2008/02/php_ip.html#4_3_configure
3.Linux/FreeBSD下用C语言开发PHP的so扩展模块例解:(估计和1重复)
http://info.codepub.com/2008/08/info-21341-4.html
4.在linux下编写php扩展模块三(函数参数和返回值)
http://mydraft.cn/posts/22  //这篇文章对与参数的传入比较详细,不错!
5.php扩展开发学习笔记 3
http://syre.blogbus.com/logs/13318038.html


在Linux终端:export LANG=GBK;
在SecureCRT字符设置:默认
上传:gbk编码,和utf8编码都没有乱码问题。。。


在Linux终端:export LANG=en_US.utf8;
在SecureCRT字符设置:默认
上传:gbk编码,和utf8!   utf8 编码都没有乱码,但是gbk有问题。


最好是第一种为好,两种情况显示都ok。。。其余设置都有乱码问题,舍弃!

有人这样setting:
使用SecreCRT远程访问中文版Linux主机时,对于中文显示会有乱码。
设置SecureCRT设置:选项(Options)->会话选项(Session Options)->外观(Appearance)->字符(Character),选择UTF-8。

我的系统是 LANG="en_US.UTF-8",改完SecureCRT设置重新登录即可.

通常就可以了,因为Linux默认LANG就是UTF-8。如果不是,则设置一下/etc/sysconfig/i18n,将LANG设置支持UTF-8。
[root@localhost sysconfig]# more i18n
LANG="zh_CN.UTF-8"
SUPPORTED="zh_CN.UTF-8:zh_CN:zh:en_US.UTF-8:en_US:en"
SYSFONT="latarcyrheb-sun16"

重新登录就可以了!
之前我在一篇文章里面讲到把故人居网站升级为UTF8字符集,看过的也知道一些有关PHP和MySQL字符集的问题,通常情况下MySQL默认使用的字符集是latin1,如果我们的系统要使用utf8或者别的字符集,就需要对MySQL进行配置,并且在PHP程序中做一点处理,大致的方法如下:

1.修改my.ini (或者my.cnf)文件,在文件的[mysqld]中加入下面一行
character_set_server = utf8

由于MySQL的字符集和连接校对有分级,分别是操作系统级、数据库服务器级、数据库客户端级,这几个级别是从上往下包含的,我上面的那一行 character_set_server 参数实际上就是设置了全局的字符集,这样不管是MySQL数据存储、数据连接、结果返回都将是utf8,当然,如果您愿意,您也可以进行分别的设置,比如做如下设置
default-character-set = utf8
default-collation = utf8_general_ci
这样的设置可以设置一个默认字符集,在您的应用中如果没有特殊指定字符集,那将默认使用utf8作为字符集,并且使用utf8_general_ci作为连接校对的默认字符集;

简单的处理方法就是如我前面的那样,加入一行即可。

2.PHP程序中连接MySQL的时候,或者在执行mysql_query的时候,执行以下一行SQL语句
SET NAMES utf8
就是说在执行mysql_query之前,或者在完成mysql_connect()之后,执行 mysql_query(”SET NAMES utf8)

  有了前面的两个处理,您就可以正常的进行utf8字符集的数据库操作,不管在页面显示还是数据库中,字符都不会出现乱码。

  前面说到的方法是以前用到的常用方法,最近在MySQL的官方发现了这样一个参数 init_connect ,它的意思呢就是在MySQL启动的时候,自动执行init_connect 参数里面的SQL语句,支持用分号间隔的多个语句,于是我们可以把 SET NAMES utf8语句加到my.ini文件里面,在PHP程序里面就不用单独处理了,加入参数的方法很简单,就是在my.ini文件的 [mysqld] 段加入下面一行
init_connect = ‘SET NAMES utf8′

  不过这个方法有一个需要注意的地方,那就是该参数对于连接数据库的用户是超级用户组的用户将被忽略,那么在PHP程序中用来连接MySQL数据库的用户不能是SUPER组的用户,比如root用户就肯定不行,这样是为了避免该参数导致数据库致命错误,而无法使用任何一个用户连接上修改该项配置,之前我搞了两天都没有发现这样的问题,害我郁闷了很久。。。

有关MySQL的配置文件中用到的参数可以参考官方的文档 : http://dev.mysql.com/doc/refman/4.1/en/server-system-variables.html

  呵呵,让人又爱又恨的MySQL!
注意:
    出现你这样的原因是虽然你的WP设置了使用utf8,但是PHP在进行数据库连接的时候并没有使用utf8连接校验,这样插入到里面的数据存储方式虽然是 utf8,但是数据本身并不是utf8的,PHP读出来的时候使用的方法和插入一样,所以WP里面看到的并不会是乱码,相反在更加聪明的 phpmyadmin里面却看到了乱码,因为它使用了正确的utf8连接校验。

#!/bin/sh
#
# Created by xiangdong#
# To determine whether slave is running or not.
echo "Enter your Username"
read USERNAME
echo "Enter your password"
stty -echo
read PASSWD
stty echo
RESULT=`mysql -h10.69.3.198 -P4406 -u$USERNAME -p$PASSWD -A relation < sql_in.txt > sql_data_out.  
txt`

http://blog.chinaunix.net/u/29134/showart_970894.html

#!/bin/bash
# Tetris Game
# 10.21.2003 xhchen

#颜色定义
cRed=1
cGreen=2
cYellow=3
cBlue=4
cFuchsia=5
cCyan=6
cWhite=7
colorTable=($cRed $cGreen $cYellow $cBlue $cFuchsia $cCyan $cWhite)

#位置和大小
iLeft=3
iTop=2
((iTrayLeft = iLeft + 2))
((iTrayTop = iTop + 1))
((iTrayWidth = 10))
((iTrayHeight = 15))

#颜色设置
cBorder=$cGreen
cScore=$cFuchsia
cScoreValue=$cCyan

#控制信号
#改游戏使用两个进程,一个用于接收输入,一个用于游戏流程和显示界面;
#当前者接收到上下左右等按键时,通过向后者发送signal的方式通知后者。
sigRotate=25
sigLeft=26
sigRight=27
sigDown=28
sigAllDown=29
sigExit=30

#七中不同的方块的定义
#通过旋转,每种方块的显示的样式可能有几种
box0=(0 0 0 1 1 0 1 1)
box1=(0 2 1 2 2 2 3 2 1 0 1 1 1 2 1 3)
box2=(0 0 0 1 1 1 1 2 0 1 1 0 1 1 2 0)
box3=(0 1 0 2 1 0 1 1 0 0 1 0 1 1 2 1)
box4=(0 1 0 2 1 1 2 1 1 0 1 1 1 2 2 2 0 1 1 1 2 0 2 1 0 0 1 0 1 1 1 2)
box5=(0 1 1 1 2 1 2 2 1 0 1 1 1 2 2 0 0 0 0 1 1 1 2 1 0 2 1 0 1 1 1 2)
box6=(0 1 1 1 1 2 2 1 1 0 1 1 1 2 2 1 0 1 1 0 1 1 2 1 0 1 1 0 1 1 1 2)
#所有其中方块的定义都放到box变量中
box=(${box0[@]} ${box1[@]} ${box2[@]} ${box3[@]} ${box4[@]} ${box5[@]} ${box6[@]})
#各种方块旋转后可能的样式数目
countBox=(1 2 2 2 4 4 4)
#各种方块再box数组中的偏移
offsetBox=(0 1 3 5 7 11 15)

#每提高一个速度级需要积累的分数
iScoreEachLevel=50 #be greater than 7

#运行时数据
sig=0 #接收到的signal
iScore=0 #总分
iLevel=0 #速度级
boxNew=() #新下落的方块的位置定义
cBoxNew=0 #新下落的方块的颜色
iBoxNewType=0 #新下落的方块的种类
iBoxNewRotate=0 #新下落的方块的旋转角度
boxCur=() #当前方块的位置定义
cBoxCur=0 #当前方块的颜色
iBoxCurType=0 #当前方块的种类
iBoxCurRotate=0 #当前方块的旋转角度
boxCurX=-1 #当前方块的x坐标位置
boxCurY=-1 #当前方块的y坐标位置
iMap=() #背景方块图表

#初始化所有背景方块为-1, 表示没有方块
for ((i = 0; i < iTrayHeight * iTrayWidth; i++)); do iMap[$i]=-1; done


#接收输入的进程的主函数
function RunAsKeyReceiver()
{
local pidDisplayer key aKey sig cESC sTTY

pidDisplayer=$1
aKey=(0 0 0)

cESC=`echo -ne "\33"`
cSpace=`echo -ne "\40"`

#保存终端属性。在read -s读取终端键时,终端的属性会被暂时改变。
#如果在read -s时程序被不幸杀掉,可能会导致终端混乱,
#需要在程序退出时恢复终端属性。
sTTY=`stty -g`

#捕捉退出信号
trap "MyExit;" INT TERM
trap "MyExitNoSub;" $sigExit

#隐藏光标
echo -ne "\33[?25l"


while (( 1 ))
do
#读取输入。注-s不回显,-n读到一个字符立即返回
read -s -n 1 key

aKey[0]=${aKey[1]}
aKey[1]=${aKey[2]}
aKey[2]=$key
sig=0

#判断输入了何种键
if [[ $key == $cESC && ${aKey[1]} == $cESC ]]
then
#ESC键
MyExit
elif [[ ${aKey[0]} == $cESC && ${aKey[1]} == "[" ]]
then
if [[ $key == "A" ]]; then sig=$sigRotate #<向上键>
elif [[ $key == "B" ]]; then sig=$sigDown #<向下键>
elif [[ $key == "D" ]]; then sig=$sigLeft #<向左键>
elif [[ $key == "C" ]]; then sig=$sigRight #<向右键>
fi
elif [[ $key == "W" || $key == "w" ]]; then sig=$sigRotate #W, w
elif [[ $key == "S" || $key == "s" ]]; then sig=$sigDown #S, s
elif [[ $key == "A" || $key == "a" ]]; then sig=$sigLeft #A, a
elif [[ $key == "D" || $key == "d" ]]; then sig=$sigRight #D, d
elif [[ "[$key]" == "[]" ]]; then sig=$sigAllDown #空格键
elif [[ $key == "Q" || $key == "q" ]] #Q, q
then
MyExit
fi

if [[ $sig != 0 ]]
then
#向另一进程发送消息
kill -$sig $pidDisplayer
fi
done
}

#退出前的恢复
function MyExitNoSub()
{
local y

#恢复终端属性
stty $sTTY
((y = iTop + iTrayHeight + 4))

#显示光标
echo -e "\33[?25h\33[${y};0H"
exit
}


function MyExit()
{
#通知显示进程需要退出
kill -$sigExit $pidDisplayer

MyExitNoSub
}


#处理显示和游戏流程的主函数
function RunAsDisplayer()
{
local sigThis
InitDraw

#挂载各种信号的处理函数
trap "sig=$sigRotate;" $sigRotate
trap "sig=$sigLeft;" $sigLeft
trap "sig=$sigRight;" $sigRight
trap "sig=$sigDown;" $sigDown
trap "sig=$sigAllDown;" $sigAllDown
trap "ShowExit;" $sigExit

while (( 1 ))
do
#根据当前的速度级iLevel不同,设定相应的循环的次数
for ((i = 0; i < 21 - iLevel; i++))
do
sleep 0.02
sigThis=$sig
sig=0

#根据sig变量判断是否接受到相应的信号
if ((sigThis == sigRotate)); then BoxRotate; #旋转
elif ((sigThis == sigLeft)); then BoxLeft; #左移一列
elif ((sigThis == sigRight)); then BoxRight; #右移一列
elif ((sigThis == sigDown)); then BoxDown; #下落一行
elif ((sigThis == sigAllDown)); then BoxAllDown; #下落到底
fi
done
#kill -$sigDown $$
BoxDown #下落一行
done
}


#BoxMove(y, x), 测试是否可以把移动中的方块移到(x, y)的位置, 返回0则可以, 1不可以
function BoxMove()
{
local j i x y xTest yTest
yTest=$1
xTest=$2
for ((j = 0; j < 8; j += 2))
do
((i = j + 1))
((y = ${boxCur[$j]} + yTest))
((x = ${boxCur[$i]} + xTest))
if (( y < 0 || y >= iTrayHeight || x < 0 || x >= iTrayWidth))
then
#撞到墙壁了
return 1
fi
if ((${iMap[y * iTrayWidth + x]} != -1 ))
then
#撞到其他已经存在的方块了
return 1
fi
done
return 0;
}


#将当前移动中的方块放到背景方块中去,
#并计算新的分数和速度级。(即一次方块落到底部)
function Box2Map()
{
local j i x y xp yp line

#将当前移动中的方块放到背景方块中去
for ((j = 0; j < 8; j += 2))
do
((i = j + 1))
((y = ${boxCur[$j]} + boxCurY))
((x = ${boxCur[$i]} + boxCurX))
((i = y * iTrayWidth + x))
iMap[$i]=$cBoxCur
done

#消去可被消去的行
line=0
for ((j = 0; j < iTrayWidth * iTrayHeight; j += iTrayWidth))
do
for ((i = j + iTrayWidth - 1; i >= j; i--))
do
if ((${iMap[$i]} == -1)); then break; fi
done
if ((i >= j)); then continue; fi

((line++))
for ((i = j - 1; i >= 0; i--))
do
((x = i + iTrayWidth))
iMap[$x]=${iMap[$i]}
done
for ((i = 0; i < iTrayWidth; i++))
do
iMap[$i]=-1
done
done

if ((line == 0)); then return; fi

#根据消去的行数line计算分数和速度级
((x = iLeft + iTrayWidth * 2 + 7))
((y = iTop + 11))
((iScore += line * 2 - 1))
#显示新的分数
echo -ne "\33[1m\33[3${cScoreValue}m\33[${y};${x}H${iScore} "
if ((iScore % iScoreEachLevel < line * 2 - 1))
then
if ((iLevel < 20))
then
((iLevel++))
((y = iTop + 14))
#显示新的速度级
echo -ne "\33[3${cScoreValue}m\33[${y};${x}H${iLevel} "
fi
fi
echo -ne "\33[0m"


#重新显示背景方块
for ((y = 0; y < iTrayHeight; y++))
do
((yp = y + iTrayTop + 1))
((xp = iTrayLeft + 1))
((i = y * iTrayWidth))
echo -ne "\33[${yp};${xp}H"
for ((x = 0; x < iTrayWidth; x++))
do
((j = i + x))
if ((${iMap[$j]} == -1))
then
echo -ne " "
else
echo -ne "\33[1m\33[7m\33[3${iMap[$j]}m\33[4${iMap[$j]}m[]\33[0m"
fi
done
done
}


#下落一行
function BoxDown()
{
local y s
((y = boxCurY + 1)) #新的y坐标
if BoxMove $y $boxCurX #测试是否可以下落一行
then
s="`DrawCurBox 0`" #将旧的方块抹去
((boxCurY = y))
s="$s`DrawCurBox 1`" #显示新的下落后方块
echo -ne $s
else
#走到这儿, 如果不能下落了
Box2Map #将当前移动中的方块贴到背景方块中
RandomBox #产生新的方块
fi
}

#左移一列
function BoxLeft()
{
local x s
((x = boxCurX - 1))
if BoxMove $boxCurY $x
then
s=`DrawCurBox 0`
((boxCurX = x))
s=$s`DrawCurBox 1`
echo -ne $s
fi
}

#右移一列
function BoxRight()
{
local x s
((x = boxCurX + 1))
if BoxMove $boxCurY $x
then
s=`DrawCurBox 0`
((boxCurX = x))
s=$s`DrawCurBox 1`
echo -ne $s
fi
}


#下落到底
function BoxAllDown()
{
local k j i x y iDown s
iDown=$iTrayHeight

#计算一共需要下落多少行
for ((j = 0; j < 8; j += 2))
do
((i = j + 1))
((y = ${boxCur[$j]} + boxCurY))
((x = ${boxCur[$i]} + boxCurX))
for ((k = y + 1; k < iTrayHeight; k++))
do
((i = k * iTrayWidth + x))
if (( ${iMap[$i]} != -1)); then break; fi
done
((k -= y + 1))
if (( $iDown > $k )); then iDown=$k; fi
done

s=`DrawCurBox 0` #将旧的方块抹去
((boxCurY += iDown))
s=$s`DrawCurBox 1` #显示新的下落后的方块
echo -ne $s
Box2Map #将当前移动中的方块贴到背景方块中
RandomBox #产生新的方块
}


#旋转方块
function BoxRotate()
{
local iCount iTestRotate boxTest j i s
iCount=${countBox[$iBoxCurType]} #当前的方块经旋转可以产生的样式的数目

#计算旋转后的新的样式
((iTestRotate = iBoxCurRotate + 1))
if ((iTestRotate >= iCount))
then
((iTestRotate = 0))
fi

#更新到新的样式, 保存老的样式(但不显示)
for ((j = 0, i = (${offsetBox[$iBoxCurType]} + $iTestRotate) * 8; j < 8; j++, i++))
do
boxTest[$j]=${boxCur[$j]}
boxCur[$j]=${box[$i]}
done

if BoxMove $boxCurY $boxCurX #测试旋转后是否有空间放的下
then
#抹去旧的方块
for ((j = 0; j < 8; j++))
do
boxCur[$j]=${boxTest[$j]}
done
s=`DrawCurBox 0`

#画上新的方块
for ((j = 0, i = (${offsetBox[$iBoxCurType]} + $iTestRotate) * 8; j < 8; j++, i++))
do
boxCur[$j]=${box[$i]}
done
s=$s`DrawCurBox 1`
echo -ne $s
iBoxCurRotate=$iTestRotate
else
#不能旋转,还是继续使用老的样式
for ((j = 0; j < 8; j++))
do
boxCur[$j]=${boxTest[$j]}
done
fi
}


#DrawCurBox(bDraw), 绘制当前移动中的方块, bDraw为1, 画上, bDraw为0, 抹去方块。
function DrawCurBox()
{
local i j t bDraw sBox s
bDraw=$1

s=""
if (( bDraw == 0 ))
then
sBox="\40\40"
else
sBox="[]"
s=$s"\33[1m\33[7m\33[3${cBoxCur}m\33[4${cBoxCur}m"
fi

for ((j = 0; j < 8; j += 2))
do
((i = iTrayTop + 1 + ${boxCur[$j]} + boxCurY))
((t = iTrayLeft + 1 + 2 * (boxCurX + ${boxCur[$j + 1]})))
#\33[y;xH, 光标到(x, y)处
s=$s"\33[${i};${t}H${sBox}"
done
s=$s"\33[0m"
echo -n $s
}


#更新新的方块
function RandomBox()
{
local i j t

#更新当前移动的方块
iBoxCurType=${iBoxNewType}
iBoxCurRotate=${iBoxNewRotate}
cBoxCur=${cBoxNew}
for ((j = 0; j < ${#boxNew[@]}; j++))
do
boxCur[$j]=${boxNew[$j]}
done


#显示当前移动的方块
if (( ${#boxCur[@]} == 8 ))
then
#计算当前方块该从顶端哪一行"冒"出来
for ((j = 0, t = 4; j < 8; j += 2))
do
if ((${boxCur[$j]} < t)); then t=${boxCur[$j]}; fi
done
((boxCurY = -t))
for ((j = 1, i = -4, t = 20; j < 8; j += 2))
do
if ((${boxCur[$j]} > i)); then i=${boxCur[$j]}; fi
if ((${boxCur[$j]} < t)); then t=${boxCur[$j]}; fi
done
((boxCurX = (iTrayWidth - 1 - i - t) / 2))

#显示当前移动的方块
echo -ne `DrawCurBox 1`

#如果方块一出来就没处放,Game over!
if ! BoxMove $boxCurY $boxCurX
then
kill -$sigExit ${PPID}
ShowExit
fi
fi



#清除右边预显示的方块
for ((j = 0; j < 4; j++))
do
((i = iTop + 1 + j))
((t = iLeft + 2 * iTrayWidth + 7))
echo -ne "\33[${i};${t}H "
done

#随机产生新的方块
((iBoxNewType = RANDOM % ${#offsetBox[@]}))
((iBoxNewRotate = RANDOM % ${countBox[$iBoxNewType]}))
for ((j = 0, i = (${offsetBox[$iBoxNewType]} + $iBoxNewRotate) * 8; j < 8; j++, i++))
do
boxNew[$j]=${box[$i]};
done

((cBoxNew = ${colorTable[RANDOM % ${#colorTable[@]}]}))

#显示右边预显示的方块
echo -ne "\33[1m\33[7m\33[3${cBoxNew}m\33[4${cBoxNew}m"
for ((j = 0; j < 8; j += 2))
do
((i = iTop + 1 + ${boxNew[$j]}))
((t = iLeft + 2 * iTrayWidth + 7 + 2 * ${boxNew[$j + 1]}))
echo -ne "\33[${i};${t}H[]"
done
echo -ne "\33[0m"
}


#初始绘制
function InitDraw()
{
clear
RandomBox #随机产生方块,这时右边预显示窗口中有方快了
RandomBox #再随机产生方块,右边预显示窗口中的方块被更新,原先的方块将开始下落
local i t1 t2 t3

#显示边框
echo -ne "\33[1m"
echo -ne "\33[3${cBorder}m\33[4${cBorder}m"

((t2 = iLeft + 1))
((t3 = iLeft + iTrayWidth * 2 + 3))
for ((i = 0; i < iTrayHeight; i++))
do
((t1 = i + iTop + 2))
echo -ne "\33[${t1};${t2}H||"
echo -ne "\33[${t1};${t3}H||"
done

((t2 = iTop + iTrayHeight + 2))
for ((i = 0; i < iTrayWidth + 2; i++))
do
((t1 = i * 2 + iLeft + 1))
echo -ne "\33[${iTrayTop};${t1}H=="
echo -ne "\33[${t2};${t1}H=="
done
echo -ne "\33[0m"


#显示"Score"和"Level"字样
echo -ne "\33[1m"
((t1 = iLeft + iTrayWidth * 2 + 7))
((t2 = iTop + 10))
echo -ne "\33[3${cScore}m\33[${t2};${t1}HScore"
((t2 = iTop + 11))
echo -ne "\33[3${cScoreValue}m\33[${t2};${t1}H${iScore}"
((t2 = iTop + 13))
echo -ne "\33[3${cScore}m\33[${t2};${t1}HLevel"
((t2 = iTop + 14))
echo -ne "\33[3${cScoreValue}m\33[${t2};${t1}H${iLevel}"
echo -ne "\33[0m"
}


#退出时显示GameOVer!
function ShowExit()
{
local y
((y = iTrayHeight + iTrayTop + 3))
echo -e "\33[${y};0HGameOver!\33[0m"
exit
}



#游戏主程序在这儿开始.
if [[ $1 != "--show" ]]
then
bash $0 --show& #以参数--show将本程序再运行一遍
RunAsKeyReceiver $! #以上一行产生的进程的进程号作为参数
exit
else
#当发现具有参数--show时,运行显示函数
RunAsDisplayer
exit
fi

select FQQ,FScoreCount from Tbl_User into outfile "/tmp/terminatedtest.txt" fields terminated by ",";



http://blog.chinaunix.net/u/29134/showart_1074828.html


select * into destTbl from srcTbl
insert into destTbl(fld1, fld2) select fld1, 5 from srcTbl
以上两句都是将 srcTbl 的数据插入到 destTbl,但两句又有区别的:

•第一句(select into from)要求目标表(destTbl)不存在,因为在插入时会自动创建。
•第二句(insert into select from)要求目标表(destTbl)存在,由于目标表已经存在,所以我们除了插入源表(srcTbl)的字段外,还可以插入常量,如例中的:5。

mysql> select * into user_score_20090429  from user_score_20090430;
要求目标表( user_score_20090429  )不存在



insert into user_score_20090504 select * from user_score_20090505 where uid=1608843755;
//这个靠谱些验证过

ERROR 1062 (23000): Duplicate entry '67' for key 1
唯一键id冲突,那就:
truncate table `user_score_20090504`;


修改表名称(发现权限不够):

RENAME TABLE user_score_20090505 TO user_score_20090504;
   用文本方式将数据装入一个数据库表

  如果一条一条地输入,很麻烦。我们可以用文本文件的方式将所有记录加入你的数据库表中。创建一个文本文件“mysql.txt”,每行包含一个记录,用定位符(tab)把值分开,并且以在CREATE TABLE语句中列出的列次序给出,例如:

abccs f 1977-07-07 china   mary f 1978-12-12 usa tom m 1970-09-02 usa


使用下面命令将文本文件“mytable.txt”装载到mytable表中:mysql> LOAD DATA LOCAL INFILE "mytable.txt" INTO TABLE pet;

复制表
create table table2 select * from table1 limit 21;//也可以复制整个表。。。

如果需要的只是某些列也可以将*改为那些列的名字。
复制表的某些列也可以使用这样的方法:
create table b as select a.id, a.name, a.address from user a;
阅读全文
http://blog.sina.com.cn/s/blog_43a1a7c30100bf4e.html
强制索引示例:
select  information.group, information.connection, information.productid, information.invitetype,relation.id, relation.owneruid, relation.otheruid, relation.type, relation.status, relation.infoid from relation  FORCE INDEX (oo,infoid) left join information   FORCE INDEX (g_i_c) on relation.infoid=information.infoid where information.group = 0 and relation.owneruid = 1257432324 and relation.type = 1;

强制不使用缓存查询示例:
select  SQL_NO_CACHE  information.group, information.connection, information.productid, information.invitetype,relation.id, relation.owneruid, relation.otheruid, relation.type, relation.status, relation.infoid from relation  FORCE INDEX (oo,infoid) left join information   FORCE INDEX (g_i_c) on relation.infoid=information.infoid where information.group = 0 and relation.owneruid = 1257432324 and relation.type = 1;


强制不使用索引示例:

select SQL_NO_CACHE  relation.id, relation.owneruid, relation.otheruid, relation.type, relation.status, relation.infoid, information.group, information.connection, information.productid, information.invitetype from relation IGNORE INDEX (PRIMARY,otc,oo,ots,uniq_key,infoid) left join information IGNORE INDEX (PRIMARY,g_i_c)  on relation.infoid=information.infoid where information.group = 0 and relation.owneruid = 1257432324 and relation.type = 1;


强制使用临时表:

select SQL_NO_CACHE SQL_BUFFER_RESULT  relation.id, relation.owneruid, relation.otheruid, relation.type, relation.status, relation.infoid, information.group, information.connection, information.productid, information.invitetype from relation left join information on relation.infoid=information.infoid where information.group = 0 and relation.owneruid = 1257432324 and relation.type = 1;


其他强制操作,优先操作如下:阅读全文
由于出现很多连接错误,主机'host_name'被屏蔽。 可使用'mysqladmin flush-hosts'解除屏蔽。
可使用'mysqladmin flush-hosts'解除屏蔽。

允许的中断连接请求的数目由max_connect_errors系统变量的值决定。当超出max_connect_errors规定的连接请求时,mysqld将认为某处出错(例如,某人正试图插入),并屏蔽主机的进一步连接请求,直至执行了mysqladmin flush-hosts命令,或发出了FLUSH HOSTS语句为止。

在默认情况下,mysqld会在10次连接错误后屏蔽主机。你可以通过下述方式启动服务器来调整该值:

shell> mysqld_safe --max_connect_errors=10000 &

如果在给定主机上遇到该错误,首先应核实该主机的TCP/IP连接是否正确。如果存在网络问题,增加max_connect_errors变量的值不会有任何好处。



GRANT ALL PRIVILEGES ON *.* TO 'space'@'%' IDENTIFIED BY '123qwe';
GRANT ALL PRIVILEGES ON *.* TO 'space'@'localhost' IDENTIFIED BY '123qwe';

只对某个库分配权限:
GRANT ALL ON DB_***team2010***.* TO kary@localhost IDENTIFIED BY "zu9UWep**";
FLUSH PRIVILEGES ;
mysql -ukary -pzu9UWepr


mysql -uspace -p123qwe  -P3306

最后,刷新:
FLUSH PRIVILEGES
http://www.linuxidc.com/Linux/2008-10/16760p2.htm
[ 起源 ]

Linux/Unix下守护进程(Daemon)大家都知道,比如我们常用的httpd、mysqld等等,就是常驻内存运行的程序,类似于Windows下的服务。一般守护进程都是使用C/C++来写,就是通过fork生成子进程,当前台shell下的父进程被杀掉,子进程就转到后台运行,为了不在终端产生输出信息,就通过 syslog等函数来写日志文件。

我们知道php是脚本语言,通过php的脚本引擎来执行,所以要做成守护进程比较麻烦,我们今天就来结合Unix/Linux的命令来实现我们守护进程的功能。

[ 原理 ]

Unix中的nohup命令的功能就是不挂断地运行命令,同时nohup把程序的所有输出到放到当前目录的nohup.out文件中,如果文件不可写,则放到<用户主目录>/nohup.out 文件中。那么有了这个命令以后,我们的php程序就写程shell脚本,使用循环来让我们的脚本一直运行,那么不管我们终端窗口是否关闭,都能够让我们的php脚本一直运行。当然,当我们的php进程被杀或者我们的操作系统重启了,自然就会中止了。

[ 功能 ]

肯定会问,让我们的php脚本做了守护进程又有什么用处呢?当然有,比如最典型的作用,能够基本的替代cron的功能,比如我们需要定期实行的某些操作,完全可以交给它来做,不再需要cron,当然,如果服务器重启就没有办法了,不过,一般的Unix服务器不是那么容易重启的。另外,我们还可以做一个简单的服务器端的功能,比如做一个能够Telnet过去的服务器,嘿嘿,可以做成一个小后门,不过这样实现稍微有点复

杂。


[ 实践 ]

例子一:自动生成文件

我们现在来做两个例子来证明我们上面的说法。首先第一个是每个三十秒自动生成一个文件,永远执行下去。

首必须确保操作系统是Unix或者Linux,比如可以是FreeBSD、Redhat、Fedora或者SUSE什么的。然后我们必须确保我们的php脚本引擎是在 /usr/local/php/bin/php,具体路径可以按照你实际路径来写,如果没有脚本引擎,请自行安装。

比如当前目录是 /home/heiyeluren/,那么我们使用vi或者其他编辑器编写一个叫做php_daemon1.php的文件:
$ vi php_daemon1.php

然后写入如下代码:

#! /usr/local/php/bin/php
<?
set_time_limit(0);
while(1)
{
@fopen("test_".time().".txt","w");
sleep(30);
}
?>


然后保存并且退出vi,然后赋予php_daemon1.php文件可执行权限:
$ chmod +x /home/heiyeluren/php_daemon1.php

然后再让我们的脚本再后台执行,执行如下命令:
$ nohup /home/heiyeluren/php_daemon1.php &

记得最后加上 & 符号,这样才能够跑到后台去运行,执行上述命令后出现如下提示:

[1] 82480
appending output to nohup.out

再 回后车后将出现shell提示符。那么上面的提示就是说,所有命令执行的输出信息都会放到 nohup.out 文件中,这个上面已经讲了。然后执行上面命令后,我们每个三十秒在当前目录就会看到多出以test_开头的文件,比如: test_1139901144.txt test_1139901154.txt等等文件,那么就证明我们的程序已经再后台运行了。

那么我们如何终止程序的运行呢?最好办法就是重启操作系统,呵呵,当然,这是不可取的,我们可以使用kill命令来杀掉这个进程,杀进程之前自然后知道进程的PID号,就是Process ID,使用ps命令就能够看到了。


$ ps
PID TT STAT      TIME COMMAND
82374 p3 Ss     0:00.14 -bash (bash)
82510 p3 S      0:00.06 /usr/local/php/bin/php /home/heiyeluren/php_daemon1.php
82528 p3 R+     0:00.00 ps


上面我们已经看到了我们的php的进程id是:82510 ,于是我们再执行kill命令:


$ kill -9 82510
[1]+ Killed                  nohup /home/heiyeluren/php_daemon1.php


看到这么提示就明白这个进程被杀了,再ps,就会发现没有了:

$ ps
PID TT STAT      TIME COMMAND
82374 p3 Ss     0:00.17 -bash (bash)
82535 p3 R+     0:00.00 ps

如果直接ps命令无法看到进程,那么就使用 ps & apos 两个结合命令来查看,一定能够看到进程。
再上面的基础上进程扩展,能够做成属于自己的cron程序,那就不需要cron啦,当然,这只是一种方式


例子二:服务器端的守护进程

这个例子跟网络有关,大致就是模拟使用php做服务器端,然后一直后台运行,达到服务器端Daemon的效果。

继续在我们的主目录下:/home/heiyeluren,编辑文件php_daemon2.php:


$ vi php_daemon2.php


输入如下代码(代码来自PHP手册,我进行了修改注释):


#! /usr/local/php/bin/php
<?php
/* 设置不显示任何错误 */
error_reporting(0);

/* 脚本超时为无限 */
set_time_limit(0);

/* 开始固定清除 */
ob_implicit_flush();

/* 本机的IP和需要开放的端口 */
$address = '192.168.0.1';
$port = 10000;

/* 产生一个Socket */
if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) {
    echo "socket_create() failed: reason: " . socket_strerror($sock) . "\n";
}

/* 把IP地址端口进行绑定 */
if (($ret = socket_bind($sock, $address, $port)) < 0) {
    echo "socket_bind() failed: reason: " . socket_strerror($ret) . "\n";
}

/* 监听Socket连接 */
if (($ret = socket_listen($sock, 5)) < 0) {
    echo "socket_listen() failed: reason: " . socket_strerror($ret) . "\n";
}

/* 永远循环监接受用户连接 */
do {
    if (($msgsock = socket_accept($sock)) < 0) {
        echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "\n";
        break;
    }
    /* 发送提示信息给连接上来的用户 */
    $msg = "==========================================\r\n" .
" Welcome to the PHP Test Server. \r\n\r\n".
        " To quit, type 'quit'. \r\n" .
" To shut down the server type 'shutdown'.\r\n" .
" To get help message type 'help'.\r\n" .
"==========================================\r\n" .
"php> ";
    socket_write($msgsock, $msg, strlen($msg));

    do {
        if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) {
            echo "socket_read() failed: reason: " . socket_strerror($ret) . "\n";
            break 2;
        }
        if (!$buf = trim($buf)) {
            continue;
        }
   /* 客户端输入quit命令时候关闭客户端连接 */
        if ($buf == 'quit') {
            break;
        }
   /* 客户端输入shutdown命令时候服务端和客户端都关闭 */
        if ($buf == 'shutdown') {
            socket_close($msgsock);
            break 2;
        }
   /* 客户端输入help命令时候输出帮助信息 */
   if ($buf == 'help') {
    $msg = " PHP Server Help Message \r\n\r\n".
    " To quit, type 'quit'. \r\n" .
    " To shut down the server type 'shutdown'.\r\n" .
    " To get help message type 'help'.\r\n" .
    "php> ";
    socket_write($msgsock, $msg, strlen($msg));
    continue;
   }
   /* 客户端输入命令不存在时提示信息 */
        $talkback = "PHP: unknow command '$buf'.\r\nphp> ";
        socket_write($msgsock, $talkback, strlen($talkback));
        echo "$buf\n";
    } while (true);
    socket_close($msgsock);
} while (true);

/* 关闭Socket连接 */
socket_close($sock);
?>


保存以上代码退出。

上面的代码大致就是完成一个类似于Telnet服务器端的功能,就是当服务器端运行该程序的时候,客户端能够连接该服务器的10000端口进行通信。

加上文件的可执行权限:

$ chmod +x /home/heiyeluren/php_daemon2.php


在服务器上执行命令:

$ nohup /home/heiyeluren/php_daemon2.php &


就进入了后台运行,我们通过Windows的客户端telnet上去:


C:\>telnet 192.168.0.1 10000


如果提示:

正在连接到192.168.0.188...不能打开到主机的连接, 在端口 10000: 连接失败

则说明服务器端没有开启,或者上面的程序没有正确执行,请检查php是否 --enable-sockets 功能。如果提示:


==========================================
Welcome to the PHP Test Server.

To quit, type 'quit'.
To shut down the server type 'shutdown'.
To get help message type 'help'.
==========================================

php>


则说明顺利连接上了我们的PHP写的服务器端守护进程,在php>提示符后面能够执行help、quit、shutdown等三个命令,如果命令输入不是这三

个,则提示:


php> asdf
PHP: unknow command 'asdf'.

执行help命令可以获取帮助:

php> help
PHP Server Help Message

To quit, type 'quit'.
To shut down the server type 'shutdown'.
To get help message type 'help'.



这个服务器端就不介绍了,可以自行扩展。

杀进程跟例子一类似。

[ 总结 ]

通过以上学习,我们知道php也可以做守护进程,如果设计的好,功能也会比较强大,不过我们这里只是学习而已,可以自行研究更新。
本文参考了php中文手册,多看手册,对自己非常有好处
文件:
         a.php  b.php  
         aTest.php

a.php:


<?php
class a
{
  private $inHandle;
    public function getHandle($handle='')
    {  
        if ('' != $handle)
        {  
            $this->inHandle = $handle;
            return ;
        }  
        elseif ('' != $this->inHandle)
        {  
            return;
        }  
        $this->inHandle = new b();
        return;
    }
  public function use_b_class($num)
  {  //调用b类的:need_mock方法,假如是外部资源,为此需要mock
    $value = $this->inHandle->need_mock($num);
    $result = $value;
    return $result;    
  }  
}
?>



b.php



<?php
class b
{  protected $a = 0;
  protected $b = 0;
  public function __construct($a,$b)
  {
    $this->a = $a;
    $this->b = $b;
    echo $this->b;    
  }
  public function  need_mock($a)
  {
    $b = $this->a+$a;
    return $b;
  }
}
?>


aTest.php

<?php
require_once 'a.php';
require_once 'b.php';
require_once 'PHPUnit/Framework/TestCase.php';
/**
* a test case.
*/
class aTest extends PHPUnit_Framework_TestCase {  
  /**
   * @var a
   */
  private $a;  
  /**
   * Prepares the environment before running a test.
   */
  protected function setUp() {
    parent::setUp ();    
    // TODO Auto-generated aTest::setUp()
    $this->a = new a(/* parameters */);
  }  
  /**
   * Cleans up the environment after running a test.
   */
  protected function tearDown() {
    // TODO Auto-generated aTest::tearDown()
    $this->a = null;    
    parent::tearDown ();
  }
  
  /**
   * Constructs the test case.
   */
  public function __construct() {
    // TODO Auto-generated constructor
  }
  
  /**
   * Tests a->getHandle()
   */
  public function testGetHandle() {
    // TODO Auto-generated aTest->testGetHandle()
    $this->markTestIncomplete ( "getHandle test not implemented" );    
    $this->a->getHandle(/* parameters */);  
  }
  
  /**
   * Tests a->use_b_class()
   */
  public function testUse_b_class() {
    // TODO Auto-generated aTest->testUse_b_class()
    //$this->markTestIncomplete ( "use_b_class test not implemented" );
    
    //$this->a->use_b_class(/* parameters */);
    $a = array(1,"第二个参数");//注意:必须传array(构造函数参数1,构造函数参数2,构造函数参数3)
    $stub = $this->getMock('b', array('need_mock'),$a);
        $stub->expects($this->any())
             ->method('need_mock')
             ->with(      
                   $this->equalTo( 1 )//传入一个参数
                   )
             ->will($this->returnValue(11));//设定返回为11
        $this->a->getHandle($stub);//传入经过mock的对象      
        echo $this->a->use_b_class(1);
        $this->assertEquals($this->a->use_b_class(1) , 11 );
        $this->assertEquals(array(array(0,1,2)),array(array(0,1,2)));//必须是所谓的二维数组,否则出错
  
  }

}



分页: 267/339 第一页 上页 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 下页 最后页 [ 显示模式: 摘要 | 列表 ]