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

摘要:html

      在主從複製的架構中,正常狀況下主上操做的記錄也會在從上進行操做,雖然說是異步複製,但操做會「實時」的同步到從。好比在主上不當心誤操做了,還沒等反應過來從上也會立刻執行誤操做,後期只有經過二進制或則備份恢復數據了,費時,又費力,沒有任何迴旋的餘地,並且也會影響到網站的功能。而pt-slave-delay故意讓主上的操做延遲制定的時間寫入到從,這樣就能夠快速的處理上面說的問題了。下面介紹下使用方法,其實挺簡單的。
mysql

前提:sql

下載地址: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中斷就能夠了。具體執行的命令:session

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 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

執行:ide

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 ...;
相關文章
相關標籤/搜索