zoukankan      html  css  js  c++  java
  • 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

    背景:

    主:
    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 statusG;
    *************************** 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 ...;
  • 相关阅读:
    常用正则表达式
    C语言的指针与二维数组
    【原创】datalist实现简单分页功能
    【原创】datalist的页脚访问和控制
    [原创]手动删除顽固病毒总结
    [zz]复杂指针解析
    极度郁闷的一次电脑维修经历
    武汉城市地铁规划图
    [转]objc_msgSend 的 ARM 汇编分析
    [转]Cydia and XCode Local App Testing
  • 原文地址:https://www.cnblogs.com/zhoujinyi/p/3384283.html
Copyright © 2011-2022 走看看