1、pt-table-checksum檢查主從庫數據的一致性mysql
pt-table-checksum在MASTER上校驗指定庫、表,將結果存在一個庫表裏,複製進程將檢驗sql傳遞到slave上再執行一次。經過比較M/S的檢驗值肯定數據是否一致。利用主從複製作檢驗,不須要在檢驗期間對主從數據庫同時鎖表,能夠控制校驗的數據和速度,不影響到正常服務。sql
安裝:shell
一、安裝依賴包 yum install perl perl-devel perl-DBI perl-DBD-MySQL perl-TermReadKey perl-IO-Socket-SSL perl-Time-HiRes -y 二、#percona-toolkit包 wget 三、編譯安裝 tar xzvf percona-toolkit-2.2.4.tar.gz ; cd percona-toolkit-2.2.4 ; perl Makefile.pl && make && make install
使用方法:數據庫
pt-table-checksum [OPTIONS] [DSN]服務器
pt-table-checksum:在主<Master>上經過執行校驗的查詢對複製的一致性進行檢查,對比主從的校驗值,從而產生結果。DSN指向的是主的地址,該工具的退出狀態不爲零,若是發現有任何差異,或者若是出現任何警告或錯誤,更多信息請見官網。ide
一、不指定任何參數,會直接對本地的全部數據庫的表進行檢查:工具
pt-table-checksum –S /tmp/mysqld.sock u=root,p=123456
實驗環境: 測試
二、在Master上初始化實驗數據ui
create database mvbox; use mvbox; create table test(id int primary key,name varchar(20)); insert into test values(1,'a'),(2,'b'),(3,'c'),(4,'d'); 由於主從環境已經搭建,這些數據會自動同步到Slave上。
三、在Slave從庫添加一個數據,模擬主從數據不一致的場景。this
注意,這裏模擬的是slave數據比master數據多
insert into test values(5,'e'); insert into test values(6,'f');
在Master主庫執行pt-table-checksum命令,由於主從環境,這個數據會複製到Slave
也就是說Slave的percona.checksums表,存放的是主庫數據的校驗碼。
因此在Slave對數據執行一樣的校驗,而後比對checksums表中的數據,就能夠驗證主從是否一致。
四、注意:
a、 根據測試,須要一個即能登陸主庫,也能登陸從庫,並且還能同步數據庫的帳號; b、 只能指定一個host,必須爲主庫的IP; c、 在檢查時會向表加S鎖; d、 運行以前須要從庫的同步IO和SQL進程是YES狀態。 五、因此執行pt-table-checksum命令的賬號,至少須要有全庫的只讀權限和percona庫的讀寫權限。
GRANT SELECT, PROCESS, SUPER, REPLICATION SLAVE ON *.* TO ‘per’@'192.168.2.%’ IDENTIFIED BY ‘p4ssword’;
6,查詢主從庫的數據
#主庫: mysql> use mvbox Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from test; +----+------+ | id | name | +----+------+ | 1 | a | | 2 | b | | 3 | c | | 4 | d | +----+------+ 4 rows in set (0.00 sec) #從庫: mysql> select * from test; +----+------+ | id | name | +----+------+ | 1 | a | | 2 | b | | 3 | c | | 4 | d | | 5 | e | | 6 | f | +----+------+ 6 rows in set (0.00 sec)
七、執行檢測(MASTER上):
參數說明:
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能夠看出主從的表數據不一致。
經過查看從庫上的test.checksums表能夠看到主從庫的檢驗信息。
mysql> use percona; mysql> select * from checksums\G; *************************** 1. row *************************** db: mvbox tbl: test chunk: 1 chunk_time: 0.001801 chunk_index: NULL lower_boundary: NULL upper_boundary: NULL this_crc: b76fca95 #從的校驗值 this_cnt: 6 #從的行數 master_crc: f2890e1c #主的校驗值 master_cnt: 4 #主的行數 ts: 2016-01-15 10:03:31 1 row in set (0.00 sec)
經過上面的 this_crc <>, master_crc 更能清楚的看出他們的不一致了,經過chunk知道是這個張表的哪一個塊上的記錄出現不一致。
要是主的binlog模式是Row 則會報錯:
Replica db2 has binlog_format ROW 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.
從錯誤信息得出,要是不改binlog模式的話,則在執行上面的命令時候要指定:--no-check-binlog-format,即:
數據不一致的SLAVE和表都找出來了,下面就用pt-table-sync來修補數據。
2、pt-table-sync修復從庫不一致的數據
使用方法:
pt-table-sync [OPTIONS] DSN [DSN]
pt-table-sync: 高效的同步MySQL表之間的數據,他能夠作單向和雙向同步的表數據。他能夠同步單個表,也能夠同步整個庫。它不一樣步表結構、索引、或任何其餘模式對象。因此在修復一致性以前須要保證他們表存在。
繼續上面的複製環境,主和從的test表數據不一致,須要修復
#先MASTER的IP,再SLAVE的IP,如下是master執行結果
#下面是在slave執行的結果
建議仍是用--print 打印出來的好,這樣就能夠知道那些數據有問題,能夠人爲的干預下。否則直接執行了,出現問題以後更很差處理。總之仍是在處理以前作好數據的備份工做。
參數的意義:
--replicate= :指定經過pt-table-checksum獲得的表,這2個工具差很少都會一直用。 --databases= : 指定執行同步的數據庫,多個用逗號隔開。 --tables= :指定執行同步的表,多個用逗號隔開。 --sync-to-master :指定一個DSN,即從的IP,他會經過show processlist或show slave status 去自動的找主。 h=127.0.0.1 :服務器地址,命令裏有2個ip,第一次出現的是M的地址,第2次是Slave的地址。 u=root :賬號。 p=123456 :密碼。 --print :打印,但不執行命令。 --execute :執行命令。 更多的參數請見官網,上面指出來的是經常使用的,對該場景夠用的參數。
開始修復數據:
先看下slave數據
執行修復命令,此時在slave進行執行的操做
再次查看slave數據
此時,代表數據已經同步完成
注意:要是表中沒有惟一索引或則主鍵則會報錯:
Can't make changes on the master because no unique index exists at /usr/local/bin/pt-table-sync line 10591.
補充:
因爲正式環境都是主從沒有延遲,一致性正常、因此模擬了以上作法,反過來 原理相同、
要是主庫有的數據,而從庫沒有,那這個數據怎麼處理?會主動添加SLAVE少了數據, 修復SLAVE缺失數據的SQL語句。
若是在shell窗口不想顯示輸入密碼則能夠添加:--ask-pass 參數,如:
[root@mysql-slave ~]# pt-table-sync --print --ask-pass --sync-to-master h=192.168.2.23,u=root,P=3306 --databases mvbox --tables test Enter password for 192.168.2.23:
若是使用--ask-pass,報錯:
Cannot read response; is Term::ReadKey installed? Can't locate Term/ReadKey.pm in @INC
安裝Term/ReadKey.pm模塊:
[root@mysql-slave ~]# perl -MCPAN -e "shell"cpan[1]> install Term::ReadKey
總結:
該工具執行檢查表動做,檢查鏈接的賬號須要有很高的權限,在通常權限上須要加SELECT, PROCESS, SUPER, REPLICATION SLAVE等權限。pt-table-checksm 配合pt-table-sync使用,在執行pt-table-sync數據同步以前,必定要執行pt-table-checksm命令檢查。