MySQL主從一致的校驗
pt-table-checksum是查看主從一致性的工具, 網上很多人說 pt-table-checksum 要在主庫上執行,其實不是的,我的mysql實例比較多,只需在某一臺服務器上安裝percona-toolkit,這臺服務能夠同時訪問主庫和從庫就行了。
pt-table-checksum 來解決這個問題
-
工具安裝
[root@MySQL-01 ~] wget http://www.percona.com/get/percona-toolkit.tar.gz
-
安裝所需依賴
[root@MySQL-01 ~] yum install perl perl-devel perl-Time-HiRes perl-DBI perl-DBD-MySQL ''' perl-Compress-Raw-Bzip2 perl-Compress-Raw-Zlib perl-Digest perl-Digest-MD5 perl-IO-Compress perl-IO-Socket-IP perl-IO-Socket-SSL perl-Mozilla-CA perl-Net-Daemon perl-Net-LibIDN perl-Net-SSLeay ... '''
-
安裝工具
[root@MySQL-01 ~] tar zxf percona-toolkit-2.2.13.tar.gz [root@MySQL-01 ~] cd percona-toolkit-2.2.13 [root@MySQL-01 ~] perl Makefile.PL [root@MySQL-01 ~] make && make install
-
在進行主從校驗之前,我們首先需要對主從庫進行授權,來看看如何來做吧
-
主庫授權
root@node1 12:28: [pt_check]> GRANT CREATE,INSERT,SELECT,DELETE,UPDATE,LOCK TABLES,PROCESS,SUPER,REPLICATION SLAVE ON *.* TO 'root'@'47.97.218.145' IDENTIFIED BY '123456'; Query OK, 0 rows affected (0.00 sec) root@node1 12:29: [pt_check]> flush privileges; Query OK, 0 rows affected (0.00 sec)
root@node1 12:29: [pt_check]> select Host,User from mysql.user; +----------------+---------------+ | Host | User | +---------------------+--------------------+ | localhost | root | | localhost | mysql.session | | localhost | mysql.sys | | 172.16.156.% | rep | | % | java | | 192.168.1.101 | ptuser | +----------------------+---------------------+
-
從庫授權
MariaDB [(none)]> GRANT SELECT, PROCESS, SUPER, REPLICATION SLAVE ON *.* TO 'root'@'9.106.84.122' IDENTIFIED BY '123456'; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> flush privileges; Query OK, 0 rows affected (0.00 sec)
授權到主從兩個數據庫之後呢,我們就可以開開心心的,進行主從數據一致性的校驗。下面
pt-table-checksum是通過在主(master)上通過執行校驗的查詢對複製的一致性進行檢查,對比主從的校驗值,從而產生結果。
DSN指向的是主的地址,該工具的退出狀態不爲零,如果發現有任何差別,或者如果出現任何警告或
錯誤,可以查看官方資料。
-
現在有一主庫,數據如下:
mysql> select * from yayun.t1; +----+-------+ | id | name | +----+-------+ | 1 | yayun| | 2 | atlas | | 3 | mysql | +----+-------+ 3 rows in set (0.00 sec) # 主庫有三條數據
-
而從庫的數據於主庫是不一致的,我們來欣賞下從庫不一致的數據:
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) # 從庫有五條數據,多了倆條不一樣的:4、5
-
接下來,我們通過工具進行檢測:
[root@MySQL-01 ~] pt-table-checksum --nocheck-binlog-format --nocheck-replication-filters --replicate=pt.checksums --databases test -u'root' -p'123456' -h127.0.0.1 -P3306
命令會展示如下的結果
TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE 04-13T15:59:31 0 1 3 1 0 0.080 yayun.t1
其中如上表所示的結果中,各字段解釋如下
標題名字 | 示意 |
---|---|
TS | 完成檢查的時間 |
ERRORS | 檢查時候發生錯誤和警告的數量 |
DIFFS | 0表示一致,1表示不一致 |
ROWS | 表的行數 |
CHUNKS | 被劃分到表中的塊的數目 |
SKIPPED | 由於錯誤或警告或過大,則跳過塊的數目 |
TIME | 執行的時間 |
TABLE | 被檢查的表名 |
清晰的看到,當主從之間數據不一致時,進行一致性檢查看到的結果DIFF爲1。此時代表一致性是錯誤的。
上面命令的各參數的意思在這裏也做好事做到底來解釋一下:
參數 | 示意 |
---|---|
–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主從不一致的數據,讓他們保持一致性呢?利用另外一個工具pt-table-sync。
這個命令的使用很簡單,他的語法是這個:pt-table-sync [OPTIONS] DSN [DSN]。pt-table-sync
,高效的同步MySQL表之間的數據,他可以做單向和雙向同步的表數據;他可以同步單個表,也可以同步整個庫。
它不同步表結構、索引、或任何其他模式對象。所以在修復一致性之前需要保證他們表存在。
- 接着上面的複製情況,主和從的t1表數據不一致,需要修復,首先執行:
[root@MySQL-01 ~] pt-table-sync --replicate=pt.checksums h=47.97.218.145,u=root,p=123456 h=39.106.84.122,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*/;
- 參數的意義:
--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=pt.checksums h=47.97.218.145,u=root,p=123456 h=39.106.84.122,u=root,p=123456 --execute
- 沒發現任何異常,然後檢查主從數據的一致性:
[root@MySQL-01 ~] pt-table-checksum --nocheck-binlog-format --nocheck-plan --nocheck-replication-filters --replicate=pt.checksums --set-vars
innodb_lock_wait_timeout=120 --databases test -u'root' -p'123456' -h47.97.218.145 -P3306
TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE
04-13T16:27:28 0 0 3 1 0 0.097 yayun.t1
- 再來看看對應的數據庫吧:
主庫:
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)
OK,數據已經保持一致了。
不過來自1902a班的張磊建議還是用—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等權限就已經足夠了。