percona-toolkit 之 【pt-slave-delay】说明

摘要:

      在主从复制的架构中,正常情况下主上操作的记录也会在从上进行操作,虽说是异步复制,但操作会“实时”的同步到从。比如在主上不小心误操作了,还没等反应过来从上也会马上执行误操作,后期只有通过二进制或则备份恢复数据了,费时,又费力,没有任何回旋的余地,而且也会影响到网站的功能。而pt-slave-delay故意让主上的操作延迟制定的时间写入到从,这样就可以快速的处理上面说的问题了。下面介绍下使用方法,其实挺简单的。

前提:

下载地址:wget www.percona.com/downloads/percona-toolkit/2.2.2/percona-toolkit-2.2.2.tar.gz

安装方法:perl Makefile.PL;make;make install

使用方法:

pt-slave-delay [OPTIONS] SLAVE_DSN [MASTER_DSN]

      执行该命令链接数据库的账号需要有 PROCESS、REPLICATION CLIENT、and SUPER权限。他是通过Slave的relay log(中继日志)的position(偏移量),不断启动,关闭 replication SQL thread 来保持主从一直延时固定的时间来实现的,所以没有必要链接主服务器。如果想在运行中停止的话,按CTRL+C中断就可以了。具体执行的命令:

pt-slave-delay --delay=1m --interval=15s --run-time=10m u=root,p=123456,h=192.168.200.25,P=3307



#--delay     :从库延迟主库的时间,上面为1分钟。

#--interval  :检查的间隔时间,上面为15s检查一次。(可选),不选则1分钟检查一次。

#--run-time  :该命令运行时间,上面为该命令运行10分钟关闭。(可选),不选则永远运行。
#--ask-pass :隐性输入密码。 其他的为链接数据库的账号信息,账号要有PROCESS, REPLICATION CLIENT, and SUPER权限 注意:延迟的时间实际为 delay+interval,即该命令的让从延迟主75s。

还有一些具体的参数请见:http://www.percona.com/doc/percona-toolkit/2.2/pt-slave-delay.html

背景:

percona-toolkit 之 【pt-slave-delay】说明
主:

root@localhost : aaa 02:37:21>select * from test;

+----+------+

| id | name |

+----+------+

|  1 | a    |

|  2 | b    |

|  3 | c    |

+----+------+

3 rows in set (0.00 sec)



从:



root@192.168.200.25 : aaa 03:11:44>select * from test;

+----+------+

| id | name |

+----+------+

|  1 | a    |

|  2 | b    |

|  3 | c    |

+----+------+

3 rows in set (0.00 sec)



root@192.168.200.25 : aaa 03:12:05>show slave status\G;

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 192.168.200.25

                  Master_User: rep

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000003

          Read_Master_Log_Pos: 1919

               Relay_Log_File: zhoujy-relay-bin.000131

                Relay_Log_Pos: 1636

        Relay_Master_Log_File: mysql-bin.000003

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

              Replicate_Do_DB: aaa

          Replicate_Ignore_DB: 

           Replicate_Do_Table: 

       Replicate_Ignore_Table: 

      Replicate_Wild_Do_Table: 

  Replicate_Wild_Ignore_Table: 

                   Last_Errno: 0

                   Last_Error: 

                 Skip_Counter: 0

          Exec_Master_Log_Pos: 1919

              Relay_Log_Space: 1951

              Until_Condition: None

               Until_Log_File: 

                Until_Log_Pos: 0

           Master_SSL_Allowed: No

           Master_SSL_CA_File: 

           Master_SSL_CA_Path: 

              Master_SSL_Cert: 

            Master_SSL_Cipher: 

               Master_SSL_Key: 

        Seconds_Behind_Master: 0

Master_SSL_Verify_Server_Cert: No

                Last_IO_Errno: 0

                Last_IO_Error: 

               Last_SQL_Errno: 0

               Last_SQL_Error: 

  Replicate_Ignore_Server_Ids: 

             Master_Server_Id: 1

                  Master_UUID: 

             Master_Info_File: /opt/mysql/mysql5.6/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: 

      Last_IO_Error_Timestamp: 

     Last_SQL_Error_Timestamp: 

               Master_SSL_Crl: 

           Master_SSL_Crlpath: 

           Retrieved_Gtid_Set: 

            Executed_Gtid_Set: 

                Auto_Position: 0
View Code

执行:

session1:命令

zhoujy@zhoujy:~$ pt-slave-delay --delay=1m --interval=15s --run-time=10m --ask-pass u=root,h=192.168.200.25,P=3307

Enter password for 192.168.200.25: 

2013-10-23T15:16:40 slave running 0 seconds behind

2013-10-23T15:16:40 STOP SLAVE until 2013-10-23T15:17:40 at master position mysql-bin.000003/1919

2013-10-23T15:16:55 slave stopped at master position mysql-bin.000003/1919

2013-10-23T15:17:10 slave stopped at master position mysql-bin.000003/1919

2013-10-23T15:17:25 slave stopped at master position mysql-bin.000003/1919

2013-10-23T15:17:40 no new binlog events

session2:主

root@localhost : aaa 03:17:34>insert into test(name) values('d'),('e');

Query OK, 2 rows affected (0.00 sec)

Records: 2  Duplicates: 0  Warnings: 0



root@localhost : aaa 03:17:44>select * from test;

+----+------+

| id | name |

+----+------+

|  1 | a    |

|  2 | b    |

|  3 | c    |

|  4 | d    |

|  5 | e    |

+----+------+

5 rows in set (0.00 sec)

session3:从

root@192.168.200.25 : aaa 03:17:31>select * from test;

+----+------+

| id | name |

+----+------+

|  1 | a    |

|  2 | b    |

|  3 | c    |

+----+------+

3 rows in set (0.00 sec)

从session3里面看到,数据还没有同步过来,因为在session2里插入了数据,继续看session1的输出日志:

zhoujy@zhoujy:~$ pt-slave-delay --delay=1m --interval=15s --run-time=10m --ask-pass u=root,h=192.168.200.25,P=3307

Enter password for 192.168.200.25: 

2013-10-23T15:16:40 slave running 0 seconds behind

2013-10-23T15:16:40 STOP SLAVE until 2013-10-23T15:17:40 at master position mysql-bin.000003/1919

2013-10-23T15:16:55 slave stopped at master position mysql-bin.000003/1919

2013-10-23T15:17:10 slave stopped at master position mysql-bin.000003/1919

2013-10-23T15:17:25 slave stopped at master position mysql-bin.000003/1919

2013-10-23T15:17:40 no new binlog events

2013-10-23T15:17:55 slave stopped at master position mysql-bin.000003/2142

2013-10-23T15:18:10 slave stopped at master position mysql-bin.000003/2142

2013-10-23T15:18:25 slave stopped at master position mysql-bin.000003/2142

2013-10-23T15:18:40 slave stopped at master position mysql-bin.000003/2142

2013-10-23T15:18:55 START SLAVE until master 2013-10-23T15:17:55 mysql-bin.000003/2142

2013-10-23T15:19:10 slave running 0 seconds behind

在日志里面看到了,在15:17:55的时候检测到了新的事件,在15:18:55的时候进行了同步,数据差不多在15:17:40写进去的,时间点刚好一致。15s后检测到了,1m后同步到从。

继续看从上的数据:

root@192.168.200.25 : aaa 03:18:57>select * from test;

+----+------+

| id | name |

+----+------+

|  1 | a    |

|  2 | b    |

|  3 | c    |

|  4 | d    |

|  5 | e    |

+----+------+

5 rows in set (0.00 sec)

最后命令运行了10m后,自动结束:

2013-10-23T15:25:40 slave stopped at master position mysql-bin.000003/2142

2013-10-23T15:25:55 slave stopped at master position mysql-bin.000003/2142

2013-10-23T15:26:10 slave stopped at master position mysql-bin.000003/2142

2013-10-23T15:26:25 no new binlog events

2013-10-23T15:26:40 slave stopped at master position mysql-bin.000003/2142

2013-10-23T15:26:40 Setting slave to run normally

原理:

这个过程的实现:

pt-slave-delay –delay=10m 开始运行

(a)连接到从服务器
检测从服务器落后主服务器多少秒$behind,并输出。
然后记录当前时间,以及Slave_IO_Thread获取到的master_log_file与read_master_log_pos做为一个对象,保存到某数组@positions中。

情况一:
如果从服务器的Slave_SQL_Thread正在运行,并且$behind小于10分钟, STOP SLAVE SQL_THREAD,并计算出多长时间之后(now()-$behind+10分钟),
才需要再次START SLAVE。再次START的时间点称为$next_start。等待一分钟,再goto(a)

情况二:
如果从服务器的Slave_SQL_Thread正在运行,并且$behind超出10分钟, 那就什么也不做。

情况三:
如果从服务器的Slave_SQL_Thread已经被STOP了,并且当前时间没有达到$next_start, 那就等待一分钟,再goto(a)

情况四:
如果从服务器的Slave_SQL_Thread已经被STOP了,并且当前时间达到$next_start,说明从服务器已经休息够了,
就从数组@positions中挑选一个合适的对象出来,此对象记录的时间要比较接近当前时间的10分钟之前。
然后START SLAVE SQL_THREAD UNTIL 此对象的master_log_file与read_master_log_pos。等待一分钟,goto(a)

总结:

通过上面的方法很好的解决了主的误操作影响到从,前提是从允许延迟一定的时间。那如何解决呢?当在主上执行了误操作之后,回到从上

执行:

slave stop;

再执行:

MASTER_LOG_FILE = 'log_name', MASTER_LOG_POS = log_pos  Pos通过mysqlbinlog查看二进制日志获得。

这样就跳过了错误,最后通过切换主从或则把从的表覆盖到主上(需要关闭应用)让主的误操作的数据恢复,和通过binlog和备份比大大减少了恢复时间。

在5.6里面已经包含了延迟这个功能:

CHANGE MASTER TO MASTER_DELAY = N ...;

 

你可能感兴趣的:(slave)