mha文章:http://467754239.blog.51cto.com/4878013/1695175 html
關於如何驗證主從數據的不一致mysql
pt-table-checksum,它能夠檢測master和slave上表結構和數據是否一致sql
如何解決主從數據不一致
數據庫
pt-table-sync,它能夠修復主從數據不一致
編程
這兩款工具都是由Percona公司提供的,Percona在MySQL的平常管理提供了不少相似的工具。
bash
適用場景服務器
pt-table-checksum是一個在線驗證主從數據一致性的工具,主要用於如下場景架構
1. 數據遷移先後,進行數據一致性檢查ide
2. 當主從複製出現問題,待修改完成後,對主從數據一致性檢查工具
3. 把從庫當成主庫,進行數據更新,產生了'髒數據'
4. 按期校驗
Percona的文檔地址:https://www.percona.com/doc/percona-toolkit/2.2/index.html
1、環境準備
準備一個主從架構的環境,建議是新配置的主從環境,並驗證主從配置是正常的。
一、地址規劃 192.168.1. master(主機名和角色) 192.168.1. slave(主機名和角色) 二、驗證主從是否一致 登陸slave主機,查看主從同步狀態 [root@slave ~]# mysql -uroot -p123456 -e 'show slave status\G;' |egrep "(Slave_IO_Running:|Slave_SQL_Running:)" Slave_IO_Running: Yes #表示主從ok Slave_SQL_Running: Yes
2、安裝
# yum install perl-DBI perl-CPAN perl-devel perl-Time-HiRes perl-DBD-mysql perl-IO-Socket-SSL perl-TermReadKey -y # wget https://www.percona.com/downloads/percona-toolkit/2.2.15/RPM/percona-toolkit-2.2.15-1.noarch.rpm # rpm -ivh percona-toolkit-2.2.15-1.noarch.rpm 查看軟件包提供了哪些可用的工具 # rpm -ql percona-toolkit |grep '/usr/bin' /usr/bin/pt-align /usr/bin/pt-archiver /usr/bin/pt-config-diff /usr/bin/pt-deadlock-logger /usr/bin/pt-diskstats /usr/bin/pt-duplicate-key-checker /usr/bin/pt-fifo-split /usr/bin/pt-find /usr/bin/pt-fingerprint /usr/bin/pt-fk-error-logger /usr/bin/pt-heartbeat /usr/bin/pt-index-usage /usr/bin/pt-ioprofile /usr/bin/pt-kill /usr/bin/pt-mext /usr/bin/pt-mysql-summary /usr/bin/pt-online-schema-change /usr/bin/pt-pmp /usr/bin/pt-query-digest /usr/bin/pt-show-grants /usr/bin/pt-sift /usr/bin/pt-slave-delay /usr/bin/pt-slave-find /usr/bin/pt-slave-restart /usr/bin/pt-stalk /usr/bin/pt-summary /usr/bin/pt-table-checksum /usr/bin/pt-table-sync /usr/bin/pt-table-usage /usr/bin/pt-upgrade /usr/bin/pt-variable-advisor /usr/bin/pt-visual-explain
3、介紹pt-table-checksum
用法:
pt-table-checksum
描述:
在主master上經過執行校驗的查詢對複製的一致性進行檢查,對比主從的校驗值,從而產生結果。DSN指向的是主的地址.
不指定任何參數,會直接對本地的全部數據庫的表進行檢查。
[root@master ~]# pt-table-checksum -uroot -p123456 --no-check-binlog-format -S /tmp/mysql.sock TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE 09-18T17:35:00 0 0 2 1 0 0.012 dbtest.tb 09-18T17:35:00 0 0 0 1 0 0.013 mysql.columns_priv 09-18T17:35:00 0 0 0 1 0 0.012 mysql.db 09-18T17:35:00 0 0 0 1 0 0.014 mysql.event 09-18T17:35:00 0 0 0 1 0 0.015 mysql.func 09-18T17:35:01 0 0 40 1 0 0.290 mysql.help_category 09-18T17:35:01 0 0 608 1 0 0.275 mysql.help_keyword 09-18T17:35:01 0 0 1216 1 0 0.284 mysql.help_relation 09-18T17:35:02 0 0 583 1 0 0.343 mysql.help_topic 09-18T17:35:02 0 0 0 1 0 0.040 mysql.ndb_binlog_index 09-18T17:35:02 0 0 0 1 0 0.039 mysql.plugin 09-18T17:35:02 0 0 0 1 0 0.035 mysql.proc 09-18T17:35:02 0 0 0 1 0 0.013 mysql.procs_priv 09-18T17:35:02 0 0 1 1 0 0.014 mysql.proxies_priv 09-18T17:35:02 0 0 0 1 0 0.014 mysql.servers 09-18T17:35:02 0 0 0 1 0 0.014 mysql.tables_priv 09-18T17:35:02 0 0 0 1 0 0.015 mysql.time_zone 09-18T17:35:02 0 0 0 1 0 0.015 mysql.time_zone_leap_second 09-18T17:35:02 0 0 0 1 0 0.014 mysql.time_zone_name 09-18T17:35:02 0 0 0 1 0 0.014 mysql.time_zone_transition 09-18T17:35:02 0 0 0 1 0 0.014 mysql.time_zone_transition_type 09-18T17:35:02 0 1 4 1 0 0.015 mysql.user 09-18T17:35:02 0 1 1 1 0 0.014 test.checksums
接下來,來作個案例來測試工具的可用性。
這裏能夠分兩種狀況
(1)主從數據一致的狀況下的比較
(2)模擬主從數據不一致的狀況下的比較
首先,咱們看第一種主從數據一致的比較
爲了試驗從0作起,這裏我從開始模擬數據 一、登陸master建立模擬須要的庫、表並插入數據 [root@master ~]# mysql -uroot -p123456 mysql> CREATE DATABASE IF NOT EXISTS dbtest; mysql> USE dbtest; mysql> CREATE TABLE tb (id int primary key not null auto_increment,name varchar(30),age int) ENGINE=InnoDB; mysql> INSERT INTO tb(name,age) VALUES ('zhengyansheng','25'); mysql> INSERT INTO tb(name,age) VALUES ('qinheng','24'); mysql> SELECT * FROM tb; +----+---------------+------+ | id | name | age | +----+---------------+------+ | 1 | zhengyansheng | 25 | | 2 | qinheng | 24 | +----+---------------+------+ 二、登陸slave查看是否已經同步到數據 [root@slave ~]# mysql -uroot -p123456 -e 'USE dbtest;SELECT * FROM tb;' +----+---------------+------+ | id | name | age | +----+---------------+------+ | 1 | zhengyansheng | 25 | | 2 | qinheng | 24 | +----+---------------+------+ 若是獲得這樣的結果,代表主從同步是正常的。 三、工具的驗證 pt-table-checksum [OPTIONS] [DSN] pt-table-checksum:在master上經過執行校驗的查詢對複製的一致性進行檢查,對比主從的校驗值,從而產生結果。DSN指向的是主的地址,該工具的退出狀態不爲零。 [root@master ~]# pt-table-checksum --user=root --password=123456 --host=192.168.1.105 --port=3306 --databases=dbtest --tables=tb --nocheck-replication-filters --no-check-binlog-format --replicate=test.checksums TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE 09-18T15:27:05 0 0 2 1 0 0.308 dbtest.tb 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參數能夠判斷主從數據是否一致。而且也能夠經過指定--replicate=rep_test.checksums 參數,就說明把檢查信息都寫到了checksums表中。 進入SLAVE相應的庫中查看checksums表的信息: [root@slave ~]# mysql -uroot -p123456 -e 'USE test;SELECT * FROM checksums\G;' Warning: Using a password on the command line interface can be insecure. *************************** 1. row *************************** db: dbtest tbl: tb chunk: 1 chunk_time: 0.001182 chunk_index: NULL lower_boundary: NULL upper_boundary: NULL this_crc: 5ede99f4 #從的 this_cnt: 2 #從的 master_crc: 5ede99f4 #主的 master_cnt: 2 #主的 ts: 2015-09-18 15:27:04 經過上面的 this_crc <> master_crc 更能清楚的看出他們的不一致了,經過chunk知道是這個張表的哪一個塊上的記錄出現不一致。
其次,咱們來看主從數據不一致的狀況
一、登陸slave主機,手動向dbtest數據庫中的tb表插入一條數據 [root@slave ~]# mysql -uroot -p123456 -e 'USE dbtest; INSERT INTO tb(name,age) VALUES ("liyuntang",25);' [root@slave ~]# mysql -uroot -p123456 -e 'USE dbtest; SELECT * FROM tb;' +----+---------------+------+ | id | name | age | +----+---------------+------+ | 1 | zhengyansheng | 25 | | 2 | qinheng | 24 | | 3 | liyuntang | 25 | +----+---------------+------+ 二、用工具驗證 [root@master ~]# pt-table-checksum --user=root --password=123456 --host=192.168.1.105 --port=3306 --databases=dbtest --tables=tb --nocheck-replication-filters --no-check-binlog-format --replicate=test.checksums TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE 09-18T15:41:16 0 1 2 1 0 0.013 dbtest.tb 這個時候在DIFFS的值就編程1了,表示主從已經不一樣步了。若是看更具體的能夠在slave主機的查看 [root@slave ~]# mysql -uroot -p123456 -e 'USE test;SELECT * FROM checksums\G;' *************************** 1. row *************************** db: dbtest tbl: tb chunk: 1 chunk_time: 0.000746 chunk_index: NULL lower_boundary: NULL upper_boundary: NULL this_crc: 4b6ecf1 #從 this_cnt: 3 master_crc: 5ede99f4 #主 master_cnt: 2 ts: 2015-09-18 15:41:16 這裏你會發現this-crc和master_crc的值已經不同的,說明主從數據庫不一致。
4、介紹pt-table-sync
用法:pt-table-sync [OPTIONS] DSN [DSN]
描述:高效的同步MySQL表之間的數據,他能夠作單向和雙向同步的表數據。他能夠同步單個表,也能夠同步整個庫。它不一樣步表結構、索引、或任何其餘模式對象。因此在修復一致性以前須要保證他們表存在。
方式1:
先master的IP地址,在slave的IP地址 # pt-table-sync --replicate=test.checksums --charset=utf8 h=127.0.0.1,u=root,p=123456,P=3306 h=192.168.1.106,u=root,p=123456,P=3306 --print # pt-table-sync --replicate=test.checksums --charset=utf8 h=127.0.0.1,u=root,p=123456,P=3306 h=192.168.1.106,u=root,p=123456,P=3306 --execute
方式2:
經過--sync-to-master參數指定一個slave的IP地址就能夠了 # pt-table-sync --replicate=test.checksums --databases=dbtest --tables=tb --charset=utf8 --sync-to-master h=192.168.1.106,u=root,p=123456,P=3306 --print # pt-table-sync --replicate=test.checksums --databases=dbtest --tables=tb --charset=utf8 --sync-to-master h=192.168.1.106,u=root,p=123456,P=3306 --execute
參數的意義
--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 :密碼。 --ask-pass : 交互式輸入密碼。 --print :打印,但不執行命令。 --execute :執行命令。
該工具檢查的表,須要檢查鏈接的賬號須要有很高的權限,在通常權限行須要加SELECT, PROCESS, SUPER, REPLICATION SLAVE等權限,測試方便我直接給了ALL的權限,pt-table-checksum 和 pt-table-sync 一塊兒互補使用
錯誤彙總
錯誤1: Can't make changes on the master because no unique index exists at /usr/bin/pt-table-sync line 10660 緣由是:表中沒有惟一索引或則主鍵則會報錯 錯誤2: 09-14T18:04:36 install_driver(mysql) failed: Attempt to reload DBD/mysql.pm aborted. Compilation failed in require at (eval 23) line 3. at /usr/bin/pt-table-checksum line 1581 解決辦法: ln -sv /usr/lib64/mysql/libmysqlclient.so.16 /lib64/