您好,登錄后才能下訂單哦!
下文主要給大家帶來如何使用percona-toolkit工具檢查及修復MySQL數據庫的主從不一致,希望這些內容能夠帶給大家實際用處,這也是我如何使用percona-toolkit工具檢查及修復MySQL數據庫的主從不一致編輯這篇文章的主要目的。好了,廢話不多說,大家直接看下文吧。
pt-table-checksum是Percona-Toolkit的組件之一,用于檢測MySQL主、從庫的數據是否一致。其原理是在主庫執行基于statement的sql語句來生成主庫數據塊的checksum,把相同的sql語句傳遞到從庫執行,并在從庫上計算相同數據塊的checksum,最后,比較主從庫上相同數據塊的checksum值,由此判斷主從數據是否一致。檢測過程根據唯一索引將表按row切分為塊(chunk),以為單位計算,可以避免鎖表。檢測時會自動判斷復制延遲、 master的負載, 超過閥值后會自動將檢測暫停,減小對線上服務的影響。
pt-table-checksum默認情況下可以應對絕大部分場景,官方說,即使上千個庫、上萬億的行,它依然可以很好的工作,這源自于設計很簡單,一次檢查一個表,不需要太多的內存和多余的操作;必要時,pt-table-checksum 會根據云服務器負載動態改變chunk大小,減少從庫的延遲。
為了減少對數據庫的干預,pt-table-checksum還會自動偵測并連接到從庫,當然如果失敗,可以指定--recursion-method選項來告訴從庫在哪里。它的易用性還體現在,復制若有延遲,在從庫checksum會暫停直到趕上主庫的計算時間點(也通過選項--設定一個可容忍的延遲最大值,超過這個值也認為不一致)。
select * from percona.checksums where master_cnt <> this_cnt OR master_crc <> this_crc OR ISNULL(master_crc) <> ISNULL(this_crc) \G
IP | Port | 主機名 | 作用 |
---|---|---|---|
192.168.1.101 | 3306 | node1 | master |
192.168.1.102 | 3306 | node2 | slave |
打開官網:https://www.percona.com/downloads/percona-toolkit/LATEST/
選擇軟件版本:Version,一般默認最新版即可;
選擇系統版本:Software,也可以源碼編譯;我的CentOS6
系統架構:Hardware;我的64位;
我的下載為:
https://www.percona.com/downloads/percona-toolkit/3.0.13/binary/redhat/6/x86_64/percona-toolkit-debuginfo-3.0.13-1.el6.x86_64.rpm
https://www.percona.com/downloads/percona-toolkit/3.0.13/binary/redhat/6/x86_64/percona-toolkit-3.0.13-1.el6.x86_64.rpm
yum install percona-toolkit-3.0.13-1.el6.x86_64.rpm -y yum install percona-toolkit-debuginfo-3.0.13-1.el6.x86_64.rpm -y
CentOS6.*依賴:
perl-DBD-MySQL perl-DBI perl-IO-Socket-SSL perl-Net-LibIDN perl-Net-SSLeay perl-Time-HiRes
perl-Compress-Raw-Bzip2 perl-Compress-Raw-Zlib perl-DBD-MySQL perl-DBI 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 perl-PlRPC
查看安裝的文件:
[root@node1 ~]# rpm -ql percona-toolkit /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-mongodb-query-digest /usr/bin/pt-mongodb-summary /usr/bin/pt-mysql-summary /usr/bin/pt-online-schema-change /usr/bin/pt-pmp /usr/bin/pt-query-digest /usr/bin/pt-secure-collect /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 ... ... [root@node1 ~]#
root@node1 10:56: [(none)]> create database pt_check; Query OK, 1 row affected (0.04 sec) root@node1 10:57: [(none)]> use pt_check Database changed root@node1 10:58: [pt_check]> create table test1(id int auto_increment primary key,name varchar(20) not null); Query OK, 0 rows affected (0.86 sec) root@node1 11:03: [pt_check]> insert into test1 values(null,'will'); Query OK, 1 row affected (0.00 sec) root@node1 11:03: [pt_check]> insert into test1 values(null,'jim'); Query OK, 1 row affected (0.00 sec) root@node1 11:03: [pt_check]> insert into test1 values(null,'tom'); Query OK, 1 row affected (0.05 sec) root@node1 11:03: [pt_check]> select * from pt_check.test1; +----+------+ | id | name | +----+------+ | 1 | will | | 2 | jim | | 3 | tom | +----+------+ 3 rows in set (0.00 sec) root@node1 11:04: [pt_check]>
root@node1 11:03: [pt_check]> select * from pt_check.test1; +----+------+ | id | name | +----+------+ | 1 | will | | 2 | jim | | 3 | tom | +----+------+ 3 rows in set (0.00 sec) root@node1 11:04: [pt_check]> delete from pt_check.test1 where id='2'; Query OK, 1 row affected (0.02 sec) root@node2 12:23: [(none)]> select * from pt_check.test1; +----+------+ | id | name | +----+------+ | 1 | will | | 3 | tom | +----+------+ 2 rows in set (0.00 sec) root@node2 12:23: [(none)]>
root@node1 12:28: [pt_check]> GRANT CREATE,INSERT,SELECT,DELETE,UPDATE,LOCK TABLES,PROCESS,SUPER,REPLICATION SLAVE ON *.* TO 'ptuser'@'192.168.1.101' 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 | +----------------+---------------+ 9 rows in set (0.00 sec) root@node1 12:29: [pt_check]>
root@node2 12:48: [(none)]> 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 | +----------------+---------------+ 8 rows in set (0.00 sec) root@node2 12:48: [(none)]>
--recursion-method:發現從庫的方式。pt-table-checksum 默認可以在主庫的 processlist 中找到從庫復制進程,從而識別出有哪些從庫,但如果使用是非標準3306端口,會導致找不到從庫信息。此時就會自動采用host方式,但需要提前在從庫 my.cnf 里面配置report_host、report_port信息,如:
report_host = MASTER_HOST report_port = 13306
最終極的辦法是dsn,dsn指定的是某個表(如 percona.dsns ),表行記錄是改主庫的(多個)從庫的連接信息。適用以下任一情形:
我比較傾向使用DSN的方式。這個dsns表只需要在執行 pt-table-checksum 命令的云服務器上能夠訪問到就行。這里糾正一個認識,網上很多人說 pt-table-checksum 要在主庫上執行,其實不是的,我的mysql實例比較多,只需在某一臺云服務器上安裝percona-toolkit,這臺服務能夠同時訪問主庫和從庫就行了。具體用法見后面實例。
[root@node1 ~]# pt-table-checksum --nocheck-replication-filters --replicate=test.checksums --databases=pt_check --tables=test1 h=192.168.1.101,u=ptuser,p=123456,P=3306 Checking if all tables can be checksummed ... Starting checksum ... Replica node2 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. [root@node1 ~]#
從庫node2的bbinlog日志為ROW,這可能導致pt-table-checksum中斷復制。可以指定--no-check-binlog-format以禁用此檢查。
[root@node1 ~]# pt-table-checksum --nocheck-replication-filters --replicate=test.checksums --databases=pt_check --tables=test1 h=192.168.1.101,u=ptuser,p=123456,P=3306 --no-check-binlog-format Checking if all tables can be checksummed ... Starting checksum ... TS ERRORS DIFFS ROWS DIFF_ROWS CHUNKS SKIPPED TIME TABLE 02-19T18:23:22 0 1 3 0 1 0 0.045 pt_check.test1 [root@node1 ~]#
看到已經檢查出主從數據有不一致了,DIFFS下的值為1,怎么不一致呢? 通過指定--replicate=test.checksums 參數,就說明把檢查信息都寫到了checksums表中
root@node1 09:19: [(none)]> select * from test.checksums \G *************************** 1. row *************************** db: pt_check tbl: test1 chunk: 1 chunk_time: 0.005212 chunk_index: NULL lower_boundary: NULL upper_boundary: NULL this_crc: b9a54161 this_cnt: 3 # 本機 3行數據 master_crc: b9a54161 master_cnt: 3 # master 3行數據 ts: 2019-02-20 09:18:01 1 row in set (0.00 sec) root@node1 09:19: [(none)]>
root@node2 09:20: [(none)]> select * from test.checksums \G *************************** 1. row *************************** db: pt_check tbl: test1 chunk: 1 chunk_time: 0.005212 chunk_index: NULL lower_boundary: NULL upper_boundary: NULL this_crc: d49ddeb7 this_cnt: 2 # 本機 2行數據 master_crc: b9a54161 master_cnt: 3 # master 3行數據 ts: 2019-02-20 09:18:01 1 row in set (0.01 sec) root@node2 09:20: [(none)]>
master庫用pt-table-sync命令和--print選項打印出master下的check_sum.test1和slave庫的check_sum.test1的不一致的數據,如下:
[root@node1 ~]# pt-table-sync --replicate=test.checksums h=192.168.1.101,u=ptuser,p=123456,P=3306 h=192.168.1.102,u=ptuser,p=123456,P=3306 --print REPLACE INTO `pt_check`.`test1`(`id`, `name`) VALUES ('2', 'jim') /*percona-toolkit src_db:pt_check src_tbl:test1 src_dsn:P=3306,h=192.168.1.101,p=...,u=ptuser dst_db:pt_check dst_tbl:test1dst_dsn:P=3306,h=node2,p=...,u=ptuser lock:1 transaction:1 changing_src:test.checksums replicate:test.checksums bidirectional:0 pid:20377 user:root host:node1*/; [root@node1 ~]#
--replicate= :指定通過pt-table-checksum得到的表. --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 :執行命令。
接下的操作就是把slave上少的數據,從master同步過去(master操作);通過(--execute),讓它們數據保持一致性:
[root@node1 ~]# pt-table-sync --replicate=test.checksums h=192.168.1.101,u=ptuser,p=123456,P=3306 h=192.168.1.102,u=ptuser,p=123456,P=3306 --execute
[root@node1 ~]# pt-table-checksum --nocheck-replication-filters --replicate=test.checksums --databases=pt_check --tables=test1 h=192.168.1.101,u=ptuser,p=123456,P=3306 --no-check-binlog-format Checking if all tables can be checksummed ... Starting checksum ... TS ERRORS DIFFS ROWS DIFF_ROWS CHUNKS SKIPPED TIME TABLE 02-20T10:03:02 0 0 3 0 1 0 0.083 pt_check.test1 [root@node1 ~]#
可以看到再次檢查的時候,DIFFS已經是0了;
root@node1 10:05: [(none)]> select * from pt_check.test1; +----+------+ | id | name | +----+------+ | 1 | will | | 2 | jim | | 3 | tom | +----+------+ 3 rows in set (0.00 sec) root@node1 10:05: [(none)]>
root@node2 10:02: [(none)]> select * from pt_check.test1; +----+------+ | id | name | +----+------+ | 1 | will | | 2 | jim | | 3 | tom | +----+------+ 3 rows in set (0.00 sec) root@node2 10:05: [(none)]>
已經跟master上的數據一致了。
沒有創建CREATE表的權限;
[root@node1 ~]# pt-table-checksum --nocheck-replication-filters --replicate=test.checksums --databases=pt_check --tables=test1 h=192.168.1.101,u=ptuser,p=123456,P=3306 --no-check-binlog-format Checking if all tables can be checksummed ... Starting checksum ... 02-19T18:08:22 --create-replicate-table failed: DBD::mysql::db do failed: CREATE command denied to user 'ptuser'@'node1' for table 'checksums' [for Statement " CREATE TABLE IF NOT EXISTS `test`.`checksums` ( db CHAR(64) NOT NULL, tbl CHAR(64) NOT NULL, chunk INT NOT NULL, chunk_time FLOAT NULL, chunk_index VARCHAR(200) NULL, lower_boundary TEXT NULL, upper_boundary TEXT NULL, this_crc CHAR(40) NOT NULL, this_cnt INT NOT NULL, master_crc CHAR(40) NULL, master_cnt INT NULL, ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (db, tbl, chunk), INDEX ts_db_tbl (ts, db, tbl) ) ENGINE=InnoDB DEFAULT CHARSET=utf8"] at /usr/bin/pt-table-checksum line 12272. 02-19T18:08:22 --replicate table checksums does not exist and it cannot be created automatically. You need to create the table. [root@node1 ~]#
不能自動找到從庫,確認processlist或host或dsns方式用對了。
可以在pt-table-checksum命令前加PTDEBUG=1來看詳細的執行過程,如端口、用戶名、權限錯誤。
問題出在 percona.checksums 表在從庫不存在,根本原因是沒有從主庫同步過來,所以看一下從庫是否延遲嚴重。
反復打印出類似上面停止檢查的信息。這是因為當前數據庫正在運行的線程數大于默認25,pt-table-checksum 為了減少對庫的壓力暫停檢查了。等數據庫壓力過了就好了,或者也可以直接 Ctrl+C 終端,下一次加上--resume繼續執行,或者加大--max-load=值。
對于以上關于如何使用percona-toolkit工具檢查及修復MySQL數據庫的主從不一致,大家是不是覺得非常有幫助。如果需要了解更多內容,請繼續關注我們的行業資訊,相信你會喜歡上這些內容的。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。