Mysql: pt-table-checksum 和 pt-table-sync 檢查主從一致性,實驗過程

 

1、安裝 percona 包

1.安裝倉庫的包

https://www.percona.com/doc/percona-repo-config/yum-repo.htmlhtml

sudo yum install http://www.percona.com/downloads/percona-release/redhat/0.1-4/percona-release-0.1-4.noarch.rpm

 

若是成功將看下以下信息
[root@node1 ~]# sudo yum install http://www.percona.com/downloads/percona-release/redhat/0.1-4/percona-release-0.1-4.noarch.rpm
Loaded plugins: fastestmirror
percona-release-0.1-4.noarch.rpm                                      | 6.4 kB  00:00:00     
Examining /var/tmp/yum-root-NKCxiN/percona-release-0.1-4.noarch.rpm: percona-release-0.1-4.noarch
Marking /var/tmp/yum-root-NKCxiN/percona-release-0.1-4.noarch.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package percona-release.noarch 0:0.1-4 will be installed
--> Finished Dependency Resolution
 
Dependencies Resolved
 
=============================================================================================
Package               Arch         Version        Repository                           Size
=============================================================================================
Installing:
percona-release       noarch       0.1-4          /percona-release-0.1-4.noarch       5.8 k
 
Transaction Summary
=============================================================================================
Install  1 Package
 
Total size: 5.8 k
Installed size: 5.8 k
Is this ok [y/d/N]: y
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : percona-release-0.1-4.noarch                                              1/1
  Verifying  : percona-release-0.1-4.noarch                                              1/1
 
Installed:
  percona-release.noarch 0:0.1-4                                                             
 
Complete!
 

2.確保 Percona 的包是可用的

 
sudo yum list | grep percona-toolkit
若是執行成功會看到
percona-toolkit.noarch                     2.2.20-1               percona-release-noarch
percona-toolkit.x86_64                     3.0.9-1.el7            percona-release-x86_64
percona-toolkit-debuginfo.x86_64           3.0.9-1.el7            percona-release-x86_64

3. 安裝 Percona Toolkit 工具包

 
sudo yum install percona-toolkit
出現以下信息表示安裝成功
Installed:
  percona-toolkit.x86_64 0:3.0.9-1.el7                                                       
 
Dependency Installed:
  perl-Compress-Raw-Bzip2.x86_64 0:2.061-3.el7  perl-Compress-Raw-Zlib.x86_64 1:2.061-4.el7
  perl-DBD-MySQL.x86_64 0:4.023-5.el7           perl-DBI.x86_64 0:1.627-4.el7               
  perl-Data-Dumper.x86_64 0:2.145-3.el7         perl-Digest.noarch 0:1.17-245.el7           
  perl-Digest-MD5.x86_64 0:2.52-3.el7           perl-IO-Compress.noarch 0:2.061-2.el7       
  perl-IO-Socket-IP.noarch 0:0.21-4.el7         perl-IO-Socket-SSL.noarch 0:1.94-6.el7      
  perl-Net-Daemon.noarch 0:0.48-5.el7           perl-Net-LibIDN.x86_64 0:0.12-15.el7        
  perl-Net-SSLeay.x86_64 0:1.55-6.el7           perl-PlRPC.noarch 0:0.2020-14.el7           
 
Complete!

安裝了不少命令

pt-align                  pt-ioprofile              pt-slave-delay
pt-archiver               pt-kill                   pt-slave-find
pt-config-diff            pt-mext                   pt-slave-restart
pt-deadlock-logger        pt-mongodb-query-digest   pt-stalk
pt-diskstats              pt-mongodb-summary        pt-summary
pt-duplicate-key-checker  pt-mysql-summary          pt-table-checksum
pt-fifo-split             pt-online-schema-change   pt-table-sync
pt-find                   pt-pmp                    pt-table-usage
pt-fingerprint            pt-query-digest           pt-upgrade
pt-fk-error-logger        pt-secure-collect         pt-variable-advisor
pt-heartbeat              pt-show-grants            pt-visual-explain
pt-index-usage            pt-sift                   ptx
 
 
有的32個命令,能夠分爲7大類
 
 
工具類別
工具命令
工具做用
備註
開發類
pt-duplicate-key-checker
列出並刪除重複的索引和外鍵
 
pt-online-schema-change
在線修改表結構
 
pt-query-advisor
分析查詢語句,並給出建議,有bug
已廢棄
pt-show-grants
規範化和打印權限
 
pt-upgrade
在多個服務器上執行查詢,並比較不一樣
 
性能類
pt-index-usage
分析日誌中索引使用狀況,並出報告
 
pt-pmp
爲查詢結果跟蹤,並彙總跟蹤結果
 
pt-visual-explain
格式化執行計劃
 
pt-table-usage
分析日誌中查詢並分析表使用狀況
pt 2.2新增命令
配置類
pt-config-diff
比較配置文件和參數
 
pt-mysql-summary
對mysql配置和status進行彙總
 
pt-variable-advisor
分析參數,並提出建議
 
監控類
pt-deadlock-logger
提取和記錄mysql死鎖信息
 
pt-fk-error-logger
提取和記錄外鍵信息
 
pt-mext
並行查看status樣本信息
 
pt-query-digest
分析查詢日誌,併產生報告
經常使用命令
pt-trend
按照時間段讀取slow日誌信息
已廢棄
複製類
pt-heartbeat
監控mysql複製延遲
 
pt-slave-delay
設定從落後主的時間
 
pt-slave-find
查找和打印全部mysql複製層級關係
 
pt-slave-restart
監控salve錯誤,並嘗試重啓salve
 
pt-table-checksum
校驗主從複製一致性
 
pt-table-sync
高效同步表數據
 
系統類
pt-diskstats
查看系統磁盤狀態
 
pt-fifo-split
模擬切割文件並輸出
 
pt-summary
收集和顯示系統概況
 
pt-stalk
出現問題時,收集診斷數據
 
pt-sift
瀏覽由pt-stalk建立的文件
pt 2.2新增命令
pt-ioprofile
查詢進程IO並打印一個IO活動表
pt 2.2新增命令
實用類
pt-archiver
將表數據歸檔到另外一個表或文件中
 
pt-find
查找表並執行命令
 
pt-kill
Kill掉符合條件的sql
經常使用命令
pt-align
對齊其餘工具的輸出
pt 2.2新增命令
pt-fingerprint
將查詢轉成密文
pt 2.2新增命令
 
此次咱們主要用這兩個命令  pt-table-checksum 和  pt-table-sync
 
  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 會暫停直到遇上主庫的計算時間點(也經過選項--設定一個可容忍的延遲最大值,超過這個值也認爲不一致)。
 
爲了保證主數據庫服務的安全,該工具實現了許多保護措施:
  1. 自動設置 innodb_lock_wait_timeout 爲1s,避免引發
  2. 默認當數據庫有25個以上的併發查詢時,pt-table-checksum會暫停。能夠設置 --max-load 選項來設置這個閥值
  3. 當用 Ctrl+C 中止任務後,工具會正常的完成當前 chunk 檢測,下次使用 --resume 選項啓動能夠恢復繼續下一個 chunk
 

工做過程

1\. 鏈接到主庫:pt工具鏈接到主庫,而後自動發現主庫的全部從庫。默認採用show full processlist來查找從庫,可是這隻有在主從實例端口相同的狀況下才有效。
3\. 查找主庫或者從庫是否有複製過濾規則:這是爲了安全而默認檢查的選項。你能夠關閉這個檢查,可是這可能致使checksum的sql語句要麼不會同步到從庫,要麼到了從庫發現從庫沒有要被checksum的表,這都會致使從庫同步卡庫。
5\. 開始獲取表,一個個的計算。
6\. 若是是表的第一個chunk,那麼chunk-size通常爲1000;若是不是表的第一個chunk,那麼採用19步中分析出的結果。
7\. 檢查表結構,進行數據類型轉換等,生成checksum的sql語句。
8\. 根據表上的索引和數據的分佈,選擇最合適的split表的方法。
9\. 開始checksum表。
10\. 默認在chunk一個表以前,先刪除上次這個表相關的計算結果。除非–resume。
14\. 根據explain的結果,判斷chunk的size是否超過了你定義的chunk-size的上限。若是超過了,爲了避免影響線上性能,這個chunk將被忽略。
15\. 把要checksum的行加上for update鎖,並計算。
17-18\. 把計算結果存儲到master_crc master_count列中。
19\. 調整下一個chunk的大小。
20\. 等待從庫追上主庫。若是沒有延遲備份的從庫在運行,最好檢查全部的從庫,若是發現延遲最大的從庫延遲超過max-lag秒,pt工具在這裏將暫停。
21\. 若是發現主庫的max-load超過某個閾值,pt工具在這裏將暫停。
22\. 繼續下一個chunk,直到這個table被chunk完畢。
23-24\. 等待從庫執行完checksum,便於生成彙總的統計結果。每一個表彙總並統計一次。
25-26\. 循環每一個表,直到結束。
 
校驗結束後,在每一個從庫上,執行以下的sql語句便可看到是否有主從不一致發生:
 
select * from percona.checksums where master_cnt <> this_cnt OR master_crc <> this_crc OR ISNULL(master_crc) <> ISNULL(this_crc) \G
 
檢查使用的mysql用戶通常是沒有 create table 權限的,因此你可能須要先手動建立:
 
CREATE DATABASE IF NOT EXISTS percona;
CREATE TABLE IF NOT EXISTS percona.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;

  

2、具體實驗過程:

修復 Mysql 數據庫不一致及 1032 錯誤

主庫 node1 192.168.112.128 3306 root 123456
從庫 node2 192.168.112.131 3306 root 123456
 
先作mysql的主從,過程略
 
數據庫操做語句主要用到以下:
 
建庫
create database school;
use school;
建表
CREATE TABLE `students` (
  `SID` tinyint(4) NOT NULL AUTO_INCREMENT,
  `Name` varchar(50) NOT NULL,
  `Age` tinyint(4) NOT NULL,
  `Gender` enum('M','F') NOT NULL,
  `Mobile` char(11) NOT NULL,
  `Address` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`SID`),
  UNIQUE KEY `Name` (`Name`),
  UNIQUE KEY `Name_2` (`Name`),
  UNIQUE KEY `index_name` (`Name`),
  KEY `Mobile` (`Mobile`)
) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=latin1;
 
插入數據
INSERT INTO students (Name, Age, Gender, Mobile, Address) VALUES ('w1',41,'F',1111111,'doagnagv');
INSERT INTO students (Name, Age, Gender, Mobile, Address) VALUES ('w2',42,'F',2222222,'dagongws');
INSERT INTO students (Name, Age, Gender, Mobile, Address) VALUES ('w3',43,'F',3333333,'doagdnga');
INSERT INTO students (Name, Age, Gender, Mobile, Address) VALUES ('w4',44,'F',4444444,'dvzxonga');
INSERT INTO students (Name, Age, Gender, Mobile, Address) VALUES ('w5',45,'F',5555555,'dozgngas');
INSERT INTO students (Name, Age, Gender, Mobile, Address) VALUES ('w6',46,'F',6666666,'dagongzg');
INSERT INTO students (Name, Age, Gender, Mobile, Address) VALUES ('w7',47,'F',7777777,'vsdgdong');
INSERT INTO students (Name, Age, Gender, Mobile, Address) VALUES ('w8',48,'F',8888888,'vsdgdong');
INSERT INTO students (Name, Age, Gender, Mobile, Address) VALUES ('w9',49,'F',9999999,'vsgagaga'); 
 
更新
UPDATE students SET age = 43 WHERE Name = 'w3';
刪除
DELETE FROM students WHERE Name = 'w4';

 

開始實驗能夠看到主從是正常的狀態node

如今開始搞事情,將從庫的一條數據刪除:mysql

 
能夠看到主從數據已經不同了,如今我們來檢測下主從的一致性。
 
[root@node1 ~]# pt-table-checksum h='192.168.112.128',u='root',p='123456',P=3306 -d school --recursion-method=processlist --nocheck-replication-filters --replicate=percona.checksums --no-check-binlog-format --ignore-databases=mysql  --engines=innodb
Checking if all tables can be checksummed ...
Starting checksum ...
            TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE
05-08T14:26:45      0      0        9       1       0   0.030 school.students
  • TS :完成檢查的時間戳。
  • ERRORS :檢查時候發生錯誤和警告的數量。
  • DIFFS :不一致的chunk數量。當指定 --no-replicate-check 即檢查完但不當即輸出結果時,會一直爲0;當指定 --replicate-check-only 即不檢查只從checksums表中計算crc32,且只顯示不一致的信息(畢竟輸出的大部分應該是一致的,容易形成干擾)。
  • ROWS :比對的錶行數。
  • CHUNKS :被劃分到表中的塊的數目。
  • SKIPPED :因爲錯誤或警告或過大,則跳過塊的數目。
  • TIME :執行的時間。
  • TABLE :被檢查的表名
 
可是並無看到 DIFFS 這個值是 1,暫時先跳過這個未解決的問題
 
官網給的解釋以下
" The number of chunks that differ from the master on one or more replicas. If --no-replicate-check is specified, this column will always have zeros. If  --replicate-check-only is specified, then only tables with differences are printed."  
 
那咱們用恢復的命令來預同步檢查一下
[root@node1 ~]# pt-table-sync --print --sync-to-master h=192.168.112.131,u=root,p='123456',P=3306 --verbose --wait=10 --transaction --engines=innodb -d school --tables=students --recursion-method=processlist --check-triggers --foreign-key-checks -unique-checks --charset=utf8mb4

從返回的結果來看已經發現了被咱們刪掉的語句,此時將 命令種的 --print 換成 --execute便可同步過去
 
執行完同步以後咱們去查看看一致性是否恢復
 
已經恢復過來。
 
咱們繼續搞事情 將從庫的 w4數據刪除,而後update主庫的這條數據看一下
 
先看主從狀態是否正常
 

 

而後
從庫執行==>   mysql> DELETE FROM students WHERE Name = 'w4';
主庫執行==>   mysql> UPDATE students SET age = 54 WHERE Name = 'w4'; 將原來的 44 換成 54
 
能夠看到主庫的數據更改了,從庫沒有該條數據,
而且主從也斷開了
 

【ERROR】1032:刪除或更新數據,從庫找不到記錄sql

 
先解決主從問題 ,讓它恢復正常
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
 
mysql> CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000017', MASTER_LOG_POS=62376;
Query OK, 0 rows affected (0.01 sec)
 
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
 
或者用
 
mysql> stop slave;
mysql> set global sql_slave_skip_counter=1;
mysql> start slave;

  

而後咱們再次對主庫的這條數據修改
主庫執行==>   mysql> UPDATE students SET age = 64 WHERE Name = 'w4'; 將原來修改過的 54 換成 64
 

主從又出現了這個問題mongodb

 
去主庫看下這個binlog文件到底發生了什麼操做
記錄下 end_log_pos ,根據pos值,找到那條數據,進行insert插入
 
mysql> show binlog events in 'mysql-bin.000017' from 62696  limit 10;
+------------------+-------+------------+-----------+-------------+-----------------------+
| Log_name         | Pos   | Event_type | Server_id | End_log_pos | Info                  |
+------------------+-------+------------+-----------+-------------+-----------------------+
| mysql-bin.000017 | 62696 | Xid        |         1 |       62727 | COMMIT /* xid=3230 */ |
+------------------+-------+------------+-----------+-------------+-----------------------+
1 row in set (0.00 sec)
 
沒看出來,仍是直接用percona 的工具吧
 
這個問題是因爲主從狀態不是兩個 YES 致使的,那咱們先跳過對應的錯誤,恢復主從
 
若是update的行數過多可能會執行不少次 CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000017', MASTER_LOG_POS=62376; 這種操做,很影響效率,
在這直接用  set global sql_slave_skip_counter=1; 這個命令能夠一次跳過不少
 
接着執行percona 的語句
[root@node1 lyj]# pt-table-checksum h='192.168.112.128',u='root',p='123456',P=3306 -d schooursion-method=processlist --nocheck-replication-filters --replicate=percona.checksums --no-inlog-format --ignore-databases=mysql  --engines=innodb
Checking if all tables can be checksummed ...
Starting checksum ...
            TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE
05-08T15:06:11      0      0        9       1       0   0.021 school.students

[root@node1 lyj]# pt-table-sync --execute --sync-to-master h=192.168.112.131,u=root,p='123456',P=3306 --verbose --wait=10 --transaction --engines=innodb -d school --tables=students --recursion-method=processlist --check-triggers --foreign-key-checks -unique-checks --charset=utf8mb4
# Syncing A=utf8mb4,P=3306,h=192.168.112.131,p=...,u=root
# DELETE REPLACE INSERT UPDATE ALGORITHM START    END      EXIT DATABASE.TABLE
#      0       1      0      0 Chunk     15:06:23 15:06:23 2    school.students
 
能夠看到數據已經恢復過來了。
 
常見錯誤:
  1. Diffs cannot be detected because no slaves were found
            不能自動找到從庫,確認processlist或host或dsns方式用對了。
         2. Waiting for the --replicate table to replicate to XXX
            問題出在 percona.checksums 表在從庫不存在,根本緣由是沒有從主庫同步過來,因此看一下從庫是否延遲嚴重。
  1. Pausing because Threads_running=25
            反覆打印出相似上面中止檢查的信息。這是由於當前數據庫正在運行的線程數大於默認25,pt-table-checksum 爲了減小對庫的壓力暫停檢查了。等數據庫壓力過了就行了,或者也能夠直接 Ctrl+C 終端,下一次加上--resume繼續執行,或者加大--max-load=值。
    
 
相關文章
相關標籤/搜索