pt-table-checksum使用實踐

在工做中接觸最多的就是mysql replication,因爲如今公司也還在使用mysql 5.1.x版本,在複製方面仍是比較多的問題,好比主庫宕機或者從庫宕機都會致使複製中斷,一般咱們須要進行人爲修復(mysql 5.5版本解決大部分問題),或者不少時候須要把一個從庫提高爲主庫,但對從庫和主庫的數據一致性不能保證同樣,因此就利用 pt-table-checksum 工做來檢查主從的一致性,以及經過 pt-table-sync 如何修復這些不一致的數據。固然若是你數據量小,slave只是當作一個備份使用,那麼出現數據不一致徹底能夠重作,或者經過其餘方法解決。若是數據量很是大,重作就是很是蛋碎的一件事情了。^_^html

工具安裝:mysql

1.軟件下載:sql

[root@MySQL-01 ~]# wget http://www.percona.com/downloads/percona-toolkit/LATEST/RPM/percona-toolkit-2.2.7-1.noarch.rpm

2.安裝該工具依賴的軟件包:數據庫

[root@MySQL-01 ~]# yum install perl-IO-Socket-SSL perl-DBD-MySQL perl-Time-HiRes -y

3.軟件安裝:服務器

[root@MySQL-01 ~]# rpm -ivh percona-toolkit-2.2.7-1.noarch.rpm 
Preparing...                ########################################### [100%]
   1:percona-toolkit        ########################################### [100%]
[root@MySQL-02 ~]# 

使用方法:工具

pt-table-checksum [OPTIONS] [DSN]

pt-table-checksum在主(master)上經過執行校驗的查詢對複製的一致性進行檢查,對比主從的校驗值,從而產生結果。DSN指向的是主的地址,該工具的退出狀態不爲零,若是發現有任何差異,或者若是出現任何警告或錯誤,更多信息請查看官方資料。測試

下面經過實際的例子來解釋該工具如何使用:this

主庫:spa

mysql> select *  from yayun.t1;
+----+-------+
| id | name  |
+----+-------+
|  1 | yayun |
|  2 | atlas |
|  3 | mysql |
+----+-------+
3 rows in set (0.00 sec)

mysql> 

備庫:code

mysql> select * from yayun.t1;
+----+----------+
| id | name     |
+----+----------+
|  1 | yayun    |
|  2 | atlas    |
|  3 | mysql    |
|  4 | dengyy   |
|  5 | love sql |
+----+----------+
5 rows in set (0.00 sec)

mysql> 

很明顯主從數據不一致,那麼咱們使用工具來檢測:

[root@MySQL-01 ~]# pt-table-checksum --nocheck-replication-filters --replicate=yayun.checksums --databases=yayun --tables=t1 h=127.0.0.1,u=root,p=123456,P=3306
Replica MySQL-02 has binlog_format MIXED which could cause pt-table-checksum to break replication.  Please read "Replicas using row-based replication" in the LIMITATIONS section of the tool's documentation.  If you understand the risks, specify --no-check-binlog-format to disable this check.
[root@MySQL-01 ~]# 

從錯誤信息得出,要是不改binlog模式的話,則執行上面的命令時候要指定:
--no-check-binlog-format,即:

[root@MySQL-01 ~]# pt-table-checksum --nocheck-replication-filters  --no-check-binlog-format --replicate=yayun.checksums --databases=yayun --tables=t1 h=127.0.0.1,u=root,p=123456,P=3306
Cannot connect to P=3306,h=192.168.0.20,p=...,u=root
Diffs cannot be detected because no slaves were found.  Please read the --recursion-method documentation for information.
            TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE
04-13T15:44:23      0      0        3       1       0   0.044 yayun.t1
[root@MySQL-01 ~]# 

Diffs cannot be detected because no slaves were found.  Please read the --recursion-method documentation for information.

這個報錯又是爲何呢?不少文章都沒有說到,我真搞不清楚那文章怎麼寫出來的,囧。。。。

上面的提示信息很清楚,由於找不到從,因此執行失敗。用參數--recursion-method 能夠指定模式解決,關於--recursion-method參數的設置有:

METHOD       USES
===========  =============================================
processlist  SHOW PROCESSLIST
hosts        SHOW SLAVE HOSTS
cluster      SHOW STATUS LIKE 'wsrep\_incoming\_addresses'
dsn=DSN      DSNs from a table
none         Do not find slaves

默認是經過show processlist 找到host的值或show slave hosts 找到host的值。

mysql> show processlist\G
*************************** 1. row ***************************
     Id: 3
   User: slave
   Host: 192.168.0.20:52352
     db: NULL
Command: Binlog Dump
   Time: 4164
  State: Master has sent all binlog to slave; waiting for binlog to be updated
   Info: NULL
*************************** 2. row ***************************
     Id: 33
   User: root
   Host: localhost
     db: NULL
Command: Query
   Time: 0
  State: NULL
   Info: show processlist
2 rows in set (0.00 sec)

還有一種方法是show slave hosts;前提從庫配置文件裏面已經配置本身的地址和端口:

[root@MySQL-02 ~]# grep 'report' /etc/my.cnf 
report_host = 192.168.0.20
report_port = 3306
[root@MySQL-02 ~]# 
mysql> show slave hosts;
+-----------+--------------+------+-----------+
| Server_id | Host         | Port | Master_id |
+-----------+--------------+------+-----------+
|         2 | 192.168.0.20 | 3306 |         1 |
+-----------+--------------+------+-----------+
1 row in set (0.00 sec)

mysql> 

因此找不到從服務器時。在從庫配置文件添加

report_host=slave_ip

report_port=slave_port

最重要的一點是咱們須要在從庫上受權,能讓主庫訪問。不少文章沒提,卻能正常進行,不得不說大牛就是牛B

注意:

一、  根據測試,須要一個即能登陸主庫,也能登陸從庫的帳號;

二、  只能指定一個host,必須爲主庫的IP;

三、  在檢查時會向表加S鎖;

四、  運行以前須要從庫的同步IO和SQL進程是YES狀態。

mysql> GRANT SELECT, PROCESS, SUPER, REPLICATION SLAVE ON *.* TO 'root'@'192.168.0.10' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> 

如今咱們再來檢測數據一致性:

[root@MySQL-01 ~]# pt-table-checksum --nocheck-replication-filters  --no-check-binlog-format --replicate=yayun.checksums --databases=yayun --tables=t1 h=127.0.0.1,u=root,p=123456,P=3306
            TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE
04-13T15:59:31      0      1        3       1       0   0.080 yayun.t1
[root@MySQL-01 ~]# 
TS            :完成檢查的時間。
ERRORS        :檢查時候發生錯誤和警告的數量。
DIFFS         :0表示一致,1表示不一致。當指定--no-replicate-check時,會一直爲0,當指定--replicate-check-only會顯示不一樣的信息。
ROWS          :表的行數。
CHUNKS        :被劃分到表中的塊的數目。
SKIPPED       :因爲錯誤或警告或過大,則跳過塊的數目。
TIME          :執行的時間。
TABLE         :被檢查的表名。

參數的意思:

--nocheck-replication-filters :不檢查複製過濾器,建議啓用。後面能夠用--databases來指定須要檢查的數據庫。
--no-check-binlog-format      : 不檢查複製的binlog模式,要是binlog模式是ROW,則會報錯。
--replicate-check-only :只顯示不一樣步的信息。
--replicate=   :把checksum的信息寫入到指定表中,建議直接寫到被檢查的數據庫當中。 
--databases=   :指定須要被檢查的數據庫,多個則用逗號隔開。
--tables=      :指定須要被檢查的表,多個用逗號隔開
h=127.0.0.1    :Master的地址
u=root         :用戶名
p=123456       :密碼
P=3306         :端口

好了,命令以及經常使用參數都介紹了,一塊兒解釋下上面執行的效果:
經過DIFFS 是1 就能夠看出主從的表數據不一致。怎麼不一致呢? 經過指定--replicate=yayun.checksums 參數,就說明把檢查信息都寫到了checksums表中。
進入SLAVE相應的庫中查看checksums表的信息:

mysql> select * from checksums\G
*************************** 1. row ***************************
            db: yayun
           tbl: t1
         chunk: 1
    chunk_time: 0.010735
   chunk_index: NULL
lower_boundary: NULL
upper_boundary: NULL
      this_crc: babf1dc0    #slave
      this_cnt: 5           #slave
    master_crc: 8727436a    #master
    master_cnt: 3           #master                 能夠發現表t1中從庫比主庫多2條記錄
            ts: 2014-04-13 16:05:16
1 row in set (0.00 sec)

mysql> 

經過上面找到了這些不一致的數據表,如何同步數據呢?即如何修復MySQL主從不一致的數據,讓他們保持一致性呢?利用另一個工具 pt-table-sync
使用方法:

pt-table-sync [OPTIONS] DSN [DSN]

pt-table-sync高效的同步MySQL表之間的數據,他能夠作單向和雙向同步的表數據。他能夠同步單個表,也能夠同步整個庫。它不一樣步表結構、索引、或任何其餘模式對象。因此在修復一致性以前須要保證他們表存在。

接着上面的複製狀況,主和從的t1表數據不一致,須要修復,
執行

先master的ip,用戶,密碼,而後是slave的ip,用戶,密碼

[root@MySQL-01 ~]# pt-table-sync --replicate=yayun.checksums h=127.0.0.1,u=root,p=123456 h=192.168.0.20,u=root,p=123456 --print
DELETE FROM `yayun`.`t1` WHERE `id`='4' LIMIT 1 /*percona-toolkit src_db:yayun src_tbl:t1 src_dsn:h=127.0.0.1,p=...,u=root dst_db:yayun dst_tbl:t1 dst_dsn:h=192.168.0.20,p=...,u=root lock:1 transaction:1 changing_src:yayun.checksums replicate:yayun.checksums bidirectional:0 pid:2190 user:root host:MySQL-01*/;
DELETE FROM `yayun`.`t1` WHERE `id`='5' LIMIT 1 /*percona-toolkit src_db:yayun src_tbl:t1 src_dsn:h=127.0.0.1,p=...,u=root dst_db:yayun dst_tbl:t1 dst_dsn:h=192.168.0.20,p=...,u=root lock:1 transaction:1 changing_src:yayun.checksums replicate:yayun.checksums bidirectional:0 pid:2190 user:root host:MySQL-01*/;
[root@MySQL-01 ~]# 

參數的意義:

--replicate=  :指定經過pt-table-checksum獲得的表,這2個工具差很少都會一直用。
--databases=  : 指定執行同步的數據庫,多個用逗號隔開。
--tables=     :指定執行同步的表,多個用逗號隔開。
--sync-to-master :指定一個DSN,即從的IP,他會經過show processlist或show slave status 去自動的找主。
h=127.0.0.1   :服務器地址,命令裏有2個ip,第一次出現的是Master的地址,第2次是Slave的地址。
u=root        :賬號。
p=123456      :密碼。
--print       :打印,但不執行命令。
--execute     :執行命令。

命令介紹完了,一塊兒解釋下執行的效果:經過(--print)打印出來了修復數據的sql語句,能夠手動的去從行執行,讓他們數據保持一致性。那可否直接執行?固然能夠,經過(--execute)

[root@MySQL-01 ~]# pt-table-sync --replicate=yayun.checksums h=127.0.0.1,u=root,p=123456 h=192.168.0.20,u=root,p=123456 --execute

沒發現任何異常,而後檢查主從數據的一致性:

[root@MySQL-01 ~]# pt-table-checksum --nocheck-replication-filters  --no-check-binlog-format --replicate=yayun.checksums --databases=yayun --tables=t1 h=127.0.0.1,u=root,p=123456,P=3306
            TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE
04-13T16:27:28      0      0        3       1       0   0.097 yayun.t1
[root@MySQL-01 ~]# 

主庫:

mysql> select * from t1;
+----+-------+
| id | name  |
+----+-------+
|  1 | yayun |
|  2 | atlas |
|  3 | mysql |
+----+-------+
3 rows in set (0.00 sec)

mysql> 

備庫:

mysql> select * from t1;
+----+-------+
| id | name  |
+----+-------+
|  1 | yayun |
|  2 | atlas |
|  3 | mysql |
+----+-------+
3 rows in set (0.00 sec)

mysql> 

OK,數據已經保持一致了。不過建議仍是用--print 打印出來的好,這樣就能夠知道那些數據有問題,能夠人爲的干預下。否則直接執行了,出現問題以後更很差處理。總之仍是在處理以前作好數據的備份工做。

注意:要是表中沒有惟一索引或則主鍵則會報錯:

Can't make changes on the master because no unique index exists at /usr/local/bin/pt-table-sync line 10591.

總結:

工具很給力,工做中經常在使用。注意使用該工具須要受權,通常SELECT, PROCESS, SUPER, REPLICATION SLAVE等權限就已經足夠了。

 

參考資料:

http://www.percona.com/doc/percona-toolkit/2.2/pt-table-checksum.html

相關文章
相關標籤/搜索