MySQL主從(二)--數據校驗

4、pt-table-checksum校驗主從數據

4.0、參考資料和安裝

參考文檔:

https://www.percona.com/doc/percona-toolkit/3.0/pt-table-checksum.html
https://www.cnblogs.com/dbabd/p/10653408.html
http://seanlook.com/2015/12/29/mysql_replica_pt-table-checksum/
http://keithlan.github.io/2016/05/25/pt_table_checksum/

安裝:

https://www.percona.com/downloads/percona-toolkit/LATEST 地址下載最新的rpm包;

yum install percona-toolkit-*.rpm -y

4.1、pt-table-checksum校驗原理

pt-table-checksum是percona-toolkit系列工具中的一個,可以用來檢測主、從數據庫中數據的一致性。通過開啓general_log觀察主從庫的動作,可以得知:

1.連接主庫和從庫,查詢當前數據庫服務器信息,包括參數設置,負載信息等;
2.根據工具選項設置會話級別參數,設置會話級binlog row format爲STATEMENT;
3.根據工具選項創建校驗結果表(默認爲percona.checksums表),查看當前數據庫服務器運行狀態;
4.獲取校驗的數據庫和表,逐張順序進行檢查校驗;
5.開始分析表,根據表的索引(如有),將表分成多個chunk,每個chunk包含多行,默認爲1000,chunk對應的錶行數可以根據數據庫性能狀態動態調整;
6.根據以上分析生成表的校驗語句,並檢查表結構;
7.開始進行表的校驗分析,爲了保證一致性,這個階段會將當前chuck所包含的行加上行鎖,並將校驗的結果以replace into方式存入校驗結果表;
8.再次查詢校驗結果表,並更新master_crc、master_cnt的值(主庫),如果是從庫則是this_crc、this_cnt;
9.根據數據庫運行狀態調整下一個chunk所包含行數;
10.繼續下一個chunk的校驗檢查,直到表中所有的chunk校驗完成;
11.從庫運行完校驗檢查,彙總這張表的結果;
12.循環完成所有需要校驗的表直到完成所有的表的校驗操作。

4.2、注意事項和常用參數說明

4.2.1、注意事項

1、校驗數據的是後主從庫必須保持同步,確保從庫的IO和SQL進程是YES狀態,否則腳本會發生等待
2、如果--recursion-method=processlist或者hosts時,需要一個即能登錄主庫,也能登錄從庫的賬號。
3、--host參數只能指定一個host,必須爲主庫的IP;並且--port --user --databases --password均指的是主庫的信息。
4、在檢查時會向表加S鎖。
5、如果master和slave的binlog日誌不是STATEMENT格式,要用--no-check-binlog-format選項。
6、表要有主鍵索引或唯一鍵索引。對於一個chunk可以放得下的小表,可以沒有主見。大表沒有主鍵會被忽略,有如下告警信息:
 Cannot checksum table mtest.bbb: There is no good index and the table is oversized. at /bin/pt-table-checksum line 6743
7、不支持級聯從庫的數據校驗。

4.2.2、常用參數說明

參數 說明
–nocheck-replication-filters 不檢查複製過濾器,建議啓用。後面可以用–databases來指定需要檢查的數據庫。
–no-check-binlog-format 不檢查複製的binlog模式,要是binlog模式是ROW,則會報錯。
–replicate-check-only 只顯示不同步的信息。
–replicate= 把checksum的信息寫入到指定表中,建議直接寫到被檢查的數據庫當中。
–databases= 指定需要被檢查的數據庫,多個則用逗號隔開。
–tables= 指定需要被檢查的表,多個用逗號隔開
–nocheck-binlog-format 非statement格式時啓用
–ignore-databases 選擇忽略的庫
–recursion-method 找slave信息的方式,默認processlist
–host Master的地址
–port Master的端口
–user Master的用戶
–password Master的密碼
–databases Master的庫名

關於–recursion-method=dsn方式的使用說明

METHOD USES
processlist SHOW PROCESSLIST
hosts SHOW SLAVE HOSTS
cluster SHOW STATUS LIKE ‘wsrep\_incoming\_addresses’
dsn=DSN DSNs from a table
none Do not find slaves

來自官方的說明:

The dsn method is special: rather than automatically discovering replicas, this method specifies a table with replica DSNs. 
The tool will only connect to these replicas. 
This method works best when replicas do not use the same MySQL username or password as the master, or when you want to prevent the tool from connecting to certain replicas. 
The dsn method is specified like: --recursion-method dsn=h=host,D=percona,t=dsns. The specified DSN must have D and t parts, or just a database-qualified t part, which specify the DSN table. 
The DSN table must have the following structure:

意思是,dsn是一種特殊而又靈活的方式,把slave的信息存放到表中,然後使用dsn=h=host…這樣的方式去連接指定的數據庫,去獲取表數據。無論是主庫、從庫還是其它庫,只要有權限訪問即可。表結構如下:

CREATE TABLE `dsns` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `parent_id` int(11) DEFAULT NULL,
  `dsn` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
);

舉例:

--recursion-method dsn=h=1.1.3.9,u=test,p=Test_123,P=3306,D=mydb9,t=dsns

參與校驗數據的從庫信息,插入到dsn這個字段中,可以多個,按照id排序:

insert into dsns(dsn) values ('h=1.1.3.111,u=root,p=1234.C0m,P=3306');
insert into dsns(dsn) values ('h=1.1.3.9,u=root,p=1234.C0m,P=3306');

檢查結果說明

標題 說明
TS 完成檢查的時間。
ERRORS 檢查時候發生錯誤和警告的數量。
DIFFS 0表示一致,1表示不一致。當指定–no-replicate-check時,會一直爲0,當指定–replicate-check-only會顯示不同的信息。
DIFF_ROWS 主庫和從庫差異的數據行數
ROWS 表的行數。
CHUNKS 被劃分到表中的塊的數目。
SKIPPED 由於錯誤或警告或過大,則跳過塊的數目。
TIME 執行的時間。
TABLE 被檢查的表名

DIFF_ROWS數據特殊說明:

在1主2從架構中的測試中發現,只要主庫和任何一個從庫的數據不一致,diffs都標記爲1;
但是diff_rows計數並不是主庫和所有從庫數據的差異總和或者選取最小差異的從庫,而是主庫數據逐個和從庫對比,選取最後一個對比的結果。比如:

從庫2排在第二位:

+------------+-----------+------+------------+--------------------------------------+
| Server_id  | Host      | Port | Master_id  | Slave_UUID                           |
+------------+-----------+------+------------+--------------------------------------+
| 2020021325 | 1.1.3.111 | 3306 | 2019010155 | e34b371d-4e4f-11ea-b9e6-000c29aa5c5d |
| 2020022219 | 1.1.3.9   | 3306 | 2019010155 | b6031e42-5560-11ea-aa8a-000c2921de41 |
+------------+-----------+------+------------+--------------------------------------+

主庫:0條

root@localhost [mtest]> select * from cqy;
Empty set (0.00 sec)

從庫1 (server_id 2020021325): 3條

root@localhost [mtest]> show variables like '%server_id%';
+----------------+------------+
| Variable_name  | Value      |
+----------------+------------+
| server_id      | 2020021325 |
| server_id_bits | 32         |
+----------------+------------+

root@localhost [mtest]> select * from cqy;
+------+------+
| name | id   |
+------+------+
| test |    1 |
| test |    2 |
| test |    3 |
+------+------+

從庫2 (server_id 2020022219):1條

mysql> select * from cqy;
+------+------+
| name | id   |
+------+------+
| test |    1 |
+------+------+

校驗結果:DIFF_ROWS = 1

            TS ERRORS  DIFFS     ROWS  DIFF_ROWS  CHUNKS SKIPPED    TIME TABLE
02-22T22:31:10      0      0   262144          0       5       0   0.801 mtest.aaa
02-22T22:31:11      0      0        0          0       1       0   0.327 mtest.bbb
02-22T22:31:11      0      1        0          1       1       0   0.328 mtest.cqy
02-22T22:31:11      0      0        0          0       1       0   0.330 mtest.dsns
02-22T22:31:12      0      0        1          0       1       0   0.344 mtest.inttest
02-22T22:31:12      0      0        0          0       1       0   0.367 mtest.medivac
02-22T22:31:12      0      1        2          0       1       0   0.338 mtest.t

如果加上參數–replicate-check-only,只顯示有差異的結果,就可以顯示出所有從庫的差異:

Checking if all tables can be checksummed ...
Starting checksum ...
Differences on onetest
TABLE CHUNK CNT_DIFF CRC_DIFF CHUNK_INDEX LOWER_BOUNDARY UPPER_BOUNDARY
mtest.cqy 1 3 1   
mtest.t 1 -2 1   

Differences on rpmtest
TABLE CHUNK CNT_DIFF CRC_DIFF CHUNK_INDEX LOWER_BOUNDARY UPPER_BOUNDARY
mtest.cqy 1 1 1   

4.3、最佳實踐

示例說明:

1.1.3.111 3309 主庫
1.1.3.111 3306 從庫
1.1.3.9   3306 從庫

首先需要創建個用戶並授權:

create user root@'1.1.3.111' identified by 'xxxx';
GRANT SELECT, PROCESS, SUPER, REPLICATION SLAVE ON *.* TO 'root'@'1.1.3.111';

–recursion-method=processlist方式,需要主備庫有相同的用戶名和密碼,並且端口一致:

pt-table-checksum --nocheck-binlog-format --replicate=mtest.testchk --ignore-databases=mysql --recursion-method=processlist --host=1.1.3.111 --port=3309 --user=root --databases=mtest --password=bigbangdata.cn

–recursion-method=hosts方式,需要主備庫有相同的用戶名和密碼,並且主庫show slave hosts可以看到slave的ip和端口:

pt-table-checksum --nocheck-binlog-format --replicate=mtest.testchk --ignore-databases=mysql --recursion-method=hosts --host=1.1.3.111 --port=3309 --user=root --databases=mtest --password=bigbangdata.cn

–recursion-method dsn=h=host,D=percona,t=dsns,比較靈活的方式,主備庫可以有不通的用戶、密碼、端口:

1)、存儲dsn信息的表

CREATE TABLE `dsns` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `parent_id` int(11) DEFAULT NULL,
  `dsn` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
);

2)、dsn列信息,for example: “h=replica_host,u=repl_user,p=repl_pass”

insert into dsns(dsn) values ('h=1.1.3.111,u=root,p=1234.C0m,P=3306');

可以插入多行,slave庫的連接信息。
3)、執行腳本

pt-table-checksum --nocheck-binlog-format --replicate=mtest.testchk --ignore-databases=mysql --recursion-method dsn=h=1.1.3.9,u=test,p=Test_123,P=3306,D=mydb9,t=dsns --host=1.1.3.111 --port=3309 --user=root --databases=mtest --password=bigbangdata.cn

腳本說明:

dsn=h=1.1.3.9,u=test,p=Test_123,P=3306,D=mydb9,t=dsns

獲取dsn信息表的連接串,可以和主從庫無關。

–replicate-check-only,只顯示有差異的結果:

pt-table-checksum --nocheck-binlog-format --replicate=mtest.testchk --ignore-databases=mysql --recursion-method=hosts --host=1.1.3.111 --port=3309 --user=root --databases=mtest --password=bigbangdata.cn --replicate-check-only

4.4、常見問題排查

4.4.1、Diffs cannot be detected because no slaves were found

這是在使用pt-table-checksum工具遇到最多的問題,當看到如下提示信息時代表着校驗失敗

Diffs cannot be detected because no slaves were found.  Please read the --recursion-method documentation for information.

錯誤也給出了提示,要你去看看官方文檔–recursion-method的用法,其實看明白了用法,知道了是如何查找從庫信息的,問題也就迎刃而解了。

processlist方式查找從庫信息:

root@localhost [mtest]> show processlist;

+-----+------+-----------------+-------+------------------+-------+---------------------------------------------------------------+------------------+
| Id  | User | Host            | db    | Command          | Time  | State                                                         | Info             |
+-----+------+-----------------+-------+------------------+-------+---------------------------------------------------------------+------------------+
|  97 | repl | 1.1.3.111:12759 | NULL  | Binlog Dump GTID | 49911 | Master has sent all binlog to slave; waiting for more updates | NULL             |
| 115 | repl | 1.1.3.9:35554   | NULL  | Binlog Dump GTID | 45133 | Master has sent all binlog to slave; waiting for more updates | NULL             |
| 126 | root | localhost       | mtest | Query            |     0 | starting                                                      | show processlist |
+-----+------+-----------------+-------+------------------+-------+---------------------------------------------------------------+------------------+
3 rows in set (0.04 sec)

當在主庫上使用show processlist去發現從庫信息時,只能獲取到從庫ip信息。但命令行參數中只傳入了主庫的用戶名、密碼、端口等信息,所以就要求主備庫要有一樣的用戶名、密碼、端口,否則就會找不到從庫信息。

hosts方式查找從庫信息:

root@localhost [mtest]> show slave hosts;
+------------+-----------+------+------------+--------------------------------------+
| Server_id  | Host      | Port | Master_id  | Slave_UUID                           |
+------------+-----------+------+------------+--------------------------------------+
| 2020021325 | 1.1.3.111 | 3306 | 2019010155 | e34b371d-4e4f-11ea-b9e6-000c29aa5c5d |
| 2020022219 |           | 3306 | 2019010155 | b6031e42-5560-11ea-aa8a-000c2921de41 |
+------------+-----------+------+------------+--------------------------------------+
2 rows in set (0.00 sec)

當使用show slave hosts命令時,有可能看不到從庫的ip信息,獲取不到信息當然就不能連上從庫了。這種情況需要在從庫的/etc/my.cnf配置文件中加入參數:從庫的ip和端口

report_host=1.1.3.9
report_port=3306

修改參數後重啓從庫再看看:發現從庫的信息已經有了

root@localhost [mtest]> show slave hosts;
+------------+-----------+------+------------+--------------------------------------+
| Server_id  | Host      | Port | Master_id  | Slave_UUID                           |
+------------+-----------+------+------------+--------------------------------------+
| 2020021325 | 1.1.3.111 | 3306 | 2019010155 | e34b371d-4e4f-11ea-b9e6-000c29aa5c5d |
| 2020022219 | 1.1.3.9   | 3306 | 2019010155 | b6031e42-5560-11ea-aa8a-000c2921de41 |
+------------+-----------+------+------------+--------------------------------------+
2 rows in set (0.00 sec)

最後,同樣的,還需要主從庫上有同樣的用戶和密碼。

5、pt-table-sync修復數據

5.0、參考資料和安裝

參考文檔:

https://www.percona.com/doc/percona-toolkit/3.0/pt-table-sync.html

https://www.hellojava.com/a/75316.html

安裝:

https://www.percona.com/downloads/percona-toolkit/LATEST 地址下載最新的rpm包;

yum install percona-toolkit-*.rpm -y

5.1、pt-table-sync原理

pt-table-sync是percona-toolkit系列工具中的一個,可以用來修復數據。通過開啓general_log觀察主從庫的信息可以得知:

1.開啓兩個會話連接,一個會話負責校驗同步,一個會話負責持續檢查服務器狀態信息;
2.連接DSN主機對應的主庫,檢查當前服務器負載信息,參數設置信息,關閉自動提交功能;
3.設置二進制日誌格式爲STATEMENT,設置會話級別隔離級別爲REPEATABLE READ;
4.檢查當前連接用戶的權限,檢查操作表是否被外鍵約束;
5.通過主鍵或唯一鍵(如有)對錶進行chunk上邊界和下邊界的確定,以便更好進行chunk分塊操作;
6.表被分成多個chunk進行校驗和同步修復,chunk大小由選項--chunk-size控制;
7.完成所有的chunk校驗和同步修復,退出。

5.2、工具使用總結

5.2.1、注意事項

特別注意

1、在進行校驗分析的同時會對操作的錶行執行FOR UPDATE語句進行鎖定,所以儘量選擇在業務低峯期進行操作,同時避免在高併發場景下進行操作數據以免造成阻塞。
2、當使用--sync-to-master or --replicate選項時,複製格式需要statement格式,腳本會自動在session級別set binlog_format=STATEMENT,所以用戶必須要有super權限。
3、如果在master-master雙主模式下修復一個沒有主鍵或唯一索引的表時,需要添加選項--no-bin-log,目的是爲了防止修改後的數據,反向又同步到源端。

能做的事情:

1、同步MySQL表之間的數據,可以做單向和雙向同步的表數據。他可以同步單個表,也可以同步整個庫。
2、主從庫之間數據可以同步;非主從庫之間庫名、表名、表結構一致,也可以同步。
3、如果表上沒有唯一鍵,則變更只好在從庫進行;但前提需指定選項--no-check-slave,以及不能再製定參數--replicate或--sync-to-master,這時候需要指定兩個dsn地址,代表源庫和目標庫,目標庫的數據同步爲源庫的。

不能做的事情:

1、不能同步表結構、索引、或任何其他模式對象。所以在修復一致性之前需要保證他們表存在。
2、指定選項--replicate或--sync-to-master時,若表中沒有唯一索引或則主鍵則會報錯,不能進行數據修復。

5.2.2、常用參數說明

基本用法:

pt-table-sync [OPTIONS] DSN [DSN]

常用選項(OPTIONS)

--[no]bin-log
默認值:yes
指定同步操作記錄二進制日誌,相當於執行SET SQL_LOG_BIN=1。如果指定'--no-bin-log',則對應執行SET SQL_LOG_BIN=0。

--channel
指定當主從複製環境是多源複製時需要進行同步哪個主庫的數據,適用於多源複製中多個主庫對應一個從庫的情形。

--charset,-A
指定連接字符集。

--[no]check-master
默認值:yes
指定當選項'--sync-to-master'使用時,嘗試驗證工具連接到的主庫是否是真正的主庫。

--[no]check-slave
默認值:yes
指定檢查目標服務器是否是從庫所在服務器。
如果目標服務器是從庫,則對其進行變更是不安全的,但某些情況卻必須這麼做,比如當主庫需要同步的表上沒有唯一索引時,指定選項'--replace'是不會進行工作的,所以在這種情況下無法對主庫進行變更。默認情況下如果需要對從庫上進行變更,則工具會有提示,可以指定選項'--no-check-slave'禁止檢查。

--chunk-size
默認值:1000
指定表分塊的chunk大小,每個chunk對應的錶行數,也可以是數據塊大小,當指定大小時允許的後綴單位爲k、M、G。

--host,-h
指定連接的數據庫IP地址。

--port,-P
指定連接的數據庫Port端口。

--user,-u
指定連接的數據庫用戶。

--password,-p
指定連接的數據庫用戶密碼。

--socket,-S
指定使用SOCKET文件連接。

--databases,-d
指定需要進行同步的數據庫,如有多個則用','(逗號)隔開。

--tables,-t
指定僅需要進行同步的表,如有多個則用','(逗號)隔開。表名稱可以使用數據庫名加以限定。

--columns,-c
指定進行比較的表字段,如有多個則用','(逗號)隔開。

--where
通過where語句條件限制表的同步內容。

--dry-run
分析、選擇同步的算法,並打印信息和退出。
意味着指定選項'--verbose'可以得出工具分析的結果。分析結果的輸出格式與工具實際執行時的輸出一致,但是並不會有數據被影響。

--execute
指定工具執行同步操作使表數據達成一致狀態,沒有此參數則不執行同步操作。
工具使用此選項意味着將同步指定出現數據不一致的表,因此表的數據將被更改,除非指定了選項'--verbose',否則表數據的更改將以靜默的方式進行。

--ignore-databases
指定需要忽略比較的數據庫,如有多個則用','(逗號)隔開,系統數據庫information_schema和performance_schema默認被忽略。

--ignore-engines
默認值:FEDERATED,MRG_MyISAM
指定需要忽略同步的存儲引擎類型的表,如有多個則用','(逗號)隔開。

--ignore-tables
指定需要忽略同步的表,如有多個則用','(逗號)隔開。表名稱可以使用數據庫名加以限定。

--lock
指定哪個過程中進行鎖表(LOCK TABLES)操作,主要有如下取值:
'
VALUE  MEANING
=====  ===========================================================================
0      永遠不進行鎖表操作;
1      每個同步週期進行鎖表操作,例如鎖定每次同步chunk對就的錶行,這是最細粒度的鎖定級別;
2      在表執行操作的時候進行鎖表操作;
3      爲連接的每個DSN連接的服務器進行鎖表操作,指定語句FLUSH TABLES WITH READ LOCK。
'
當指定選項'--replicate'或'--sync-to-master'時,從庫的表是不會被鎖定的。如果指定了選項'--wait',則主庫對應的表被鎖定,工具暫定執行操作直到從庫追上主庫才繼續執行。
如果指定選項'--transaction',則鎖表操作(LOCK TABLES)不會執行,取代的方式是通過事務的開始和提交來進行鎖定操作,例外情況是'--lock=3',如果指定選項'--no-transaction',則鎖表操作(LOCK TABLES)適應所有'--lock'取值情況。

--print
指定打印工具需要執行哪些查詢語句來同步表,解決數據不一致,只是打印輸出,並不會真正執行。

--recursion-method
默認值:processlist,hosts
指定獲取從庫的方式。
'
METHOD       USES
===========  =============================================
processlist  SHOW PROCESSLIST   
hosts        SHOW SLAVE HOSTS   
none         Do not find slaves
==========================================================
'
processlist:通過SHOW PROCESSLIST方式找到slave,爲默認方式,當SHOW SLAVE HOSTS不可用時。一旦實例運行在非3306端口上時,hosts方式就會變爲默認方式;
hosts:通過SHOW SLAVE HOSTS方式找到slave,hosts方式要求從庫配置'--report_host'和'--report_port'這兩個參數。

--replicate
指定參照該選項中列出的表進行表同步操作。
工具將在該選項指定的表中去查詢數據不一致表的信息並進行同步操作,這個選項跟工具pt-table-checksum當中的同名選項是相同意義的。該選項會自動設置選項'--wait=60'並確保在主庫進行變更。
如果指定選項'--sync-to-master',則工具會假設指定的連接是從庫,並會尋找主庫連接進行表數據同步操作,如果指定的連接不是從庫,工具將使用選項'--recursion-method'中查找從庫方法進行查找操作,然後再找到需要進行同步操作的表。

--sync-to-master
指定將DSN連接信息確認爲從庫,並同步信息到主庫。
該選項將指定的服務器當作是從庫,並且檢查從庫的主庫,連接主庫。將主庫作爲數據同步的源端,從庫作爲數據同步的目標端進行同步。選項會默認設置選項'--wait=60'和'--lock=1',並且設置選項'--no-transaction'。

--timeout-ok
指定當選項'--wait'導致工具執行失敗時跳過失敗繼續執行。
如果指定了選項'--wait',但是從庫在指定時間內還是沒能追上主庫且依然存在主從延遲,則工具將中止操作並退出。指定選項'--timeout-ok'則會繼續執行操作。

--verbose,-v
指定打印更詳細的操作信息。

DSN選項(DSN)說明:

可以使用DSN方式來連接數據庫,DSN選項爲key=value方式,在等號的兩側不能有空格出現,並且區分大小寫,多個選項之前以’,’(逗號)隔開,主要選項如下:

選項 說明
A 指定字符集
D 指定需要同步數據庫
t 指定需要同步的表
h 指定要連接的HOST
P 指定要連接的PORT
S 指定連接所使用的SOCKET文件(Unix systems)
u 指定連接的用戶名
p 指定連接的用戶名密碼

示例:

h=192.168.58.3,P=3306,D=employees,t=employees

5.2.3、–replicate選項說明

pt-table-sync工具使用起來有點複雜,它可以通過很多不同方式起作用,其中選項–replicate的使用對於工具至關重要,以下關於該選項的使用作進一步的說明。

該選項的使用邏輯如下:

一、如果不指定--replicate選項,DSN選項中有涉及到表選項t,則只同步指定的表:
  1.如果DSN只有1個主機信息,並指定選項--sync-to-master:
    1).如果DSN代表的是從庫,工具也會連接它的主庫並且同步;
    2).如果DSN代表的是主庫,工具會報錯找不到主庫。
  2.如果DSN裏大於1個主機信息:
    1).第1個DSN主機是源端數據庫(並不區分主庫和從庫),按順序向之後DSN主機同步。如果第一個是DSN主機是從庫的話會將從庫的數據同步到主庫;
    2).如果第1個DSN主機是主庫,確保同步的表有唯一索引以便在主庫執行REPLACE變更操作,並指定選項--no-check-slave。
二、如果指定--replicate選項,證明已經存在保存數據差異結果的表(可以先使用工具pt-table-checksum進行校驗):
  1.指定--sync-to-master選項:
    1).當這兩個選項一起使用時,只允許有1個DSN主機,否則工具會報錯退出。DSN代表的是從庫。工具會連接它的主庫,找出差異數據並進行同步修復。
  2.不指定--sync-to-master選項:
    1).DSN代表的是主庫。工具會找出所有從庫並連接,找出差異數據並進行同步修復。
三、其他情況,不指定選項--replicate和--sync-to-master:
  1.有多個DSN主機:
    1).通過--databases或者--ignore-databases等過濾選項找出指定數據庫所有表數據的差異,以DSN第1個主機爲主,並同步差異到DSN其餘所有主機。

總結:

1.如果DSN只有1個主機信息,則必須指定選項–sync-to-master或者–replicate其中之一,否則報錯;

2.如果有指定選項–replicate和–sync-to-master,或者兩者其中之一,參考以上使用邏輯;

3.如果DSN不只1個主機信息,並且都沒有指定選項–replicate和–sync-to-master,則以第1個主機爲主,同時指定選項–no-check-slave,在其餘主機上同步差異數據。

5.3、使用案例

如果表上具有唯一鍵(主鍵)時,對於主從複製架構來說,最理想的做法是指定選項–replicate或–sync-to-master將同步需要執行的變更語句放在主庫上執行,並將變更的操作通過主從複製傳遞給從庫來執行。

5.3.1、只有1個DSN主機

1).只指定選項–sync-to-master

因爲只有1個DSN主機並且指定了選項–sync-to-master,則DSN主機對應爲從庫的連接串,可以先使用選項–dry-run查看執行信息;使用–dry-run參數會覆蓋掉–execute參數,所以下面的語句不會執行同步:

pt-table-sync --execute --sync-to-master --charset=utf8 --transaction h=1.1.3.111,u=root,p=1234.C0m,P=3306 --databases=mtest --tables=aaa,bbb,cqy --verbose --dry-run

去掉–dry-run,可以看到已經對錶cqy進行了修復,從庫上刪除一行記錄:

[mysql@onetest ~]$ pt-table-sync --execute --sync-to-master --charset=utf8 --transaction h=1.1.3.111,u=root,p=1234.C0m,P=3306 --databases=mtest --tables=aaa,bbb,cqy --verbose
# Syncing A=utf8,P=3306,h=1.1.3.111,p=...,u=root
# DELETE REPLACE INSERT UPDATE ALGORITHM START    END      EXIT DATABASE.TABLE
#      0       0      0      0 Chunk     15:53:19 15:53:22 0    mtest.aaa
#      0       0      0      0 Chunk     15:53:22 15:53:22 0    mtest.bbb
#      1       0      0      0 Chunk     15:53:22 15:53:22 2    mtest.cqy
[mysql@onetest ~]$ 

2).只指定選項–replicate

如果是隻指定選項–replicate,則DSN主機對應的爲主庫的連接串,在這之前選項–replicate指定的表有保存之前數據不一致的校驗結果,可以先通過工具pt-table-checksum進行校驗,否則並不會進行同步變更修復。

先使用pt-table-checksum工具做一次主從校驗,發現bbb和cqy這兩張表的數據不一致:

[mysql@onetest ~]$ pt-table-checksum --nocheck-binlog-format --replicate=mtest.testchk --ignore-databases=mysql --recursion-method=hosts --host=1.1.3.111 --port=3309 --user=root --databases=mtest --password=1234.C0m
Checking if all tables can be checksummed ...
Starting checksum ...
            TS ERRORS  DIFFS     ROWS  DIFF_ROWS  CHUNKS SKIPPED    TIME TABLE
02-23T15:59:32      0      0   262144          0       5       0   0.826 mtest.aaa
02-23T15:59:33      0      1        0          1       1       0   0.333 mtest.bbb
02-23T15:59:33      0      1        0          1       1       0   0.332 mtest.cqy
02-23T15:59:33      0      0        0          0       1       0   0.326 mtest.dsns
02-23T15:59:34      0      0        1          0       1       0   0.326 mtest.inttest
02-23T15:59:34      0      0        0          0       1       0   0.330 mtest.medivac
02-23T15:59:34      0      0        2          0       1       0   0.347 mtest.t
02-23T15:59:35      0      0        0          0       1       0   0.323 mtest.t0
02-23T15:59:35      0      0        3          0       1       0   0.329 mtest.t1
02-23T15:59:35      0      0        1          0       1       0   0.345 mtest.t_tab_test
02-23T15:59:36      0      0        1          0       1       0   0.332 mtest.tab0
02-23T15:59:36      0      0        1          0       1       0   0.337 mtest.tab1

執行修復腳本:1.1.3.111 3309爲主庫

pt-table-sync --execute --replicate=mtest.testchk --charset=utf8 --transaction h=1.1.3.111,u=root,p=1234.C0m,P=3309 --databases=mtest --tables=aaa,bbb,cqy --verbose

下面信息可以看出,主庫下面的兩個從庫的數據都被修復了:

# Syncing via replication A=utf8,P=3306,h=1.1.3.111,p=...,u=root
# DELETE REPLACE INSERT UPDATE ALGORITHM START    END      EXIT DATABASE.TABLE
#      1       0      0      0 Chunk     16:06:32 16:06:32 2    mtest.bbb
#      1       0      0      0 Chunk     16:06:32 16:06:33 2    mtest.cqy
# Syncing via replication A=utf8,P=3306,h=1.1.3.9,p=...,u=root
# DELETE REPLACE INSERT UPDATE ALGORITHM START    END      EXIT DATABASE.TABLE
#      1       0      0      0 Chunk     16:06:33 16:06:33 2    mtest.bbb
#      1       0      0      0 Chunk     16:06:33 16:06:33 2    mtest.cqy

3).同時指定選項–sync-to-master和–replicate

因爲選項–sync-to-master出現,所以DSN主機對應的爲從庫的連接串;測試前再次製造主從不一致,並使用pt-table-checksum校驗下數據,因爲如果沒有校驗數據信息則不執行任何操作:同樣的,還是bbb和cqy表不一致,並且兩個從庫都不一致

[mysql@onetest ~]$ pt-table-checksum --nocheck-binlog-format --replicate=mtest.testchk --ignore-databases=mysql --recursion-method=hosts --host=1.1.3.111 --port=3309 --user=root --databases=mtest --password=1234.C0m
Checking if all tables can be checksummed ...
Starting checksum ...
            TS ERRORS  DIFFS     ROWS  DIFF_ROWS  CHUNKS SKIPPED    TIME TABLE
02-23T16:19:51      0      0   262144          0       5       0   0.859 mtest.aaa
02-23T16:19:51      0      1        0          1       1       0   0.329 mtest.bbb
02-23T16:19:52      0      1        0          1       1       0   0.325 mtest.cqy
02-23T16:19:52      0      0        0          0       1       0   0.330 mtest.dsns
02-23T16:19:52      0      0        1          0       1       0   0.337 mtest.inttest
02-23T16:19:53      0      0        0          0       1       0   0.325 mtest.medivac
02-23T16:19:53      0      0        2          0       1       0   0.341 mtest.t
02-23T16:19:53      0      0        0          0       1       0   0.330 mtest.t0
02-23T16:19:54      0      0        3          0       1       0   0.325 mtest.t1
02-23T16:19:54      0      0        1          0       1       0   0.339 mtest.t_tab_test
02-23T16:19:54      0      0        1          0       1       0   0.332 mtest.tab0

執行修復腳本:1.1.3.111 3306爲從庫1

pt-table-sync --execute --sync-to-master --replicate=mtest.testchk --charset=utf8 --transaction h=1.1.3.111,u=root,p=1234.C0m,P=3306 --databases=mtest --tables=aaa,bbb,cqy --verbose

執行腳本後,發現只有指定的從庫1數據被修復了,從庫2(1.1.3.9 3306)並沒有被修復:

[mysql@onetest ~]$ pt-table-sync --execute --sync-to-master --replicate=mtest.testchk --charset=utf8 --transaction h=1.1.3.111,u=root,p=1234.C0m,P=3306 --databases=mtest --tables=aaa,bbb,cqy --verbose
# Syncing via replication A=utf8,P=3306,h=1.1.3.111,p=...,u=root
# DELETE REPLACE INSERT UPDATE ALGORITHM START    END      EXIT DATABASE.TABLE
#      1       0      0      0 Chunk     16:22:08 16:22:08 2    mtest.bbb
#      1       0      0      0 Chunk     16:22:08 16:22:08 2    mtest.cqy

小結:–sync-to-master和–replicate一起指定,可以定向的修復某個從庫,單獨指定–replicate可以修復主庫下所有的從庫。
4).不指定選項–sync-to-master和–replicate呢?

當DSN只有1個主機的時候,必須指定至少其中一個選項,否則工具報錯退出。

[mysql@onetest ~]$ pt-table-sync --execute  --charset=utf8 --transaction h=1.1.3.111,u=root,p=1234.C0m,P=3309 --databases=mtest --tables=aaa,bbb,cqy --verbose
Usage: pt-table-sync [OPTIONS] DSN [DSN]

Errors in command-line arguments:
  * At least one DSN is required, and at least two are required unless --sync-to-master or --replicate is specified

pt-table-sync synchronizes data efficiently between MySQL tables.  For more
details, please use the --help option, or try 'perldoc /bin/pt-table-sync' for
complete documentation.

5.3.2、指定多個DSN主機

1).只指定選項–sync-to-master

因爲有多個DSN主機,必須確保所列出DSN主機均爲從庫,否則工具報錯退出。

pt-table-sync --execute --sync-to-master --charset=utf8 --transaction h=1.1.3.111,u=root,p=1234.C0m,P=3306 h=1.1.3.9,u=root,p=1234.C0m,P=3306 --databases=mtest --tables=aaa,bbb,cqy --verbose

從下面的結果看出,指定的兩個從庫數據都被修復了,和指定主庫dsn使用–replicate效果一樣:

# Syncing A=utf8,P=3306,h=1.1.3.111,p=...,u=root
# DELETE REPLACE INSERT UPDATE ALGORITHM START    END      EXIT DATABASE.TABLE
#      0       0      0      0 Chunk     16:30:26 16:30:29 0    mtest.aaa
#      1       0      0      0 Chunk     16:30:29 16:30:29 2    mtest.bbb
#      1       0      0      0 Chunk     16:30:29 16:30:29 2    mtest.cqy
# Syncing A=utf8,P=3306,h=1.1.3.9,p=...,u=root
# DELETE REPLACE INSERT UPDATE ALGORITHM START    END      EXIT DATABASE.TABLE
#      0       0      0      0 Chunk     16:30:29 16:30:32 0    mtest.aaa
#      1       0      0      0 Chunk     16:30:32 16:30:32 2    mtest.bbb
#      1       0      0      0 Chunk     16:30:32 16:30:33 2    mtest.cqy

2).只指定選項–replicate

–replicate參數必須確保第一個dsn主機爲主庫,其它dsn地址爲從庫。

pt-table-sync --execute --replicate=mtest.testchk  --charset=utf8 --transaction h=1.1.3.111,u=root,p=1234.C0m,P=3309 h=1.1.3.9,u=root,p=1234.C0m,P=3306 --databases=mtest --tables=aaa,bbb,cqy --verbose

測試發現,即使指定了一個從庫dsn,但還是會把其它從庫的數據給修復了,所以無論主庫dsn後面還有沒有從庫的dsn地址,效果都等同於–replicate後面只指定一個主庫dsn。

[mysql@onetest ~]$ pt-table-sync --execute --replicate=mtest.testchk  --charset=utf8 --transaction h=1.1.3.111,u=root,p=1234.C0m,P=3309 h=1.1.3.9,u=root,p=1234.C0m,P=3306 --databases=mtest --tables=aaa,bbb,cqy --verbose
# Syncing via replication A=utf8,P=3306,h=1.1.3.111,p=...,u=root
# DELETE REPLACE INSERT UPDATE ALGORITHM START    END      EXIT DATABASE.TABLE
#      1       0      0      0 Chunk     16:43:20 16:43:20 2    mtest.bbb
#      1       0      0      0 Chunk     16:43:20 16:43:20 2    mtest.cqy
# Syncing via replication A=utf8,P=3306,h=1.1.3.9,p=...,u=root
# DELETE REPLACE INSERT UPDATE ALGORITHM START    END      EXIT DATABASE.TABLE
#      1       0      0      0 Chunk     16:43:20 16:43:20 2    mtest.bbb
#      1       0      0      0 Chunk     16:43:20 16:43:21 2    mtest.cqy

3).同時指定選項–sync-to-master和–replicate

當同時指定這兩個選項時,DSN主機只允許有一個,並且必須爲從庫dsn地址,否則工具報錯退出。

4).不指定選項–sync-to-master和–replicate

因爲都不指定這兩個選項,所以DSN主機的順序必須格外注意,最好是先寫主庫再寫從庫,或者根據同步的方向來確定。同時如果需要做同步變更修復的表上沒有唯一鍵(主鍵),需要指定選項–no-check-slave直接在從庫進行變更修復。

不加–no-check-slave參數

pt-table-sync --execute --charset=utf8 --transaction h=1.1.3.111,u=root,p=1234.C0m,P=3309 h=1.1.3.111,u=root,p=1234.C0m,P=3306 --databases=mtest --tables=aaa,bbb,cqy,t --verbose

在把主庫的數據同步到從庫時,因爲表上沒有主鍵,得到了如下報錯:

# Syncing A=utf8,P=3306,h=1.1.3.111,p=...,u=root
# DELETE REPLACE INSERT UPDATE ALGORITHM START    END      EXIT DATABASE.TABLE
Can't make changes on A=utf8,P=3306,h=1.1.3.111,p=...,u=root because it's a slave. See the documentation section 'REPLICATION SAFETY' for solutions to this problem. at /bin/pt-table-sync line 10879.  while doing mtest.aaa on 1.1.3.111
#      0       0      0      0 0         16:52:01 16:52:01 1    mtest.aaa
Can't make changes on A=utf8,P=3306,h=1.1.3.111,p=...,u=root because it's a slave. See the documentation section 'REPLICATION SAFETY' for solutions to this problem. at /bin/pt-table-sync line 10879.  while doing mtest.bbb on 1.1.3.111
#      0       0      0      0 0         16:52:01 16:52:01 1    mtest.bbb
Can't make changes on A=utf8,P=3306,h=1.1.3.111,p=...,u=root because it's a slave. See the documentation section 'REPLICATION SAFETY' for solutions to this problem. at /bin/pt-table-sync line 10879.  while doing mtest.cqy on 1.1.3.111
#      0       0      0      0 0         16:52:01 16:52:01 1    mtest.cqy
Can't make changes on A=utf8,P=3306,h=1.1.3.111,p=...,u=root because it's a slave. See the documentation section 'REPLICATION SAFETY' for solutions to this problem. at /bin/pt-table-sync line 10879.  while doing mtest.t on 1.1.3.111
#      0       0      0      0 0         16:52:01 16:52:01 1    mtest.t

加上–no-check-slave參數

pt-table-sync --execute --charset=utf8 --transaction h=1.1.3.111,u=root,p=1234.C0m,P=3309 h=1.1.3.111,u=root,p=1234.C0m,P=3306 --databases=mtest --tables=aaa,bbb,cqy,t --no-check-slave --verbose

從下面的結果看出,已經完成了沒有主鍵或唯一索引表mtest.t的修復:

# Syncing A=utf8,P=3306,h=1.1.3.111,p=...,u=root
# DELETE REPLACE INSERT UPDATE ALGORITHM START    END      EXIT DATABASE.TABLE
#      0       0      0      0 Chunk     16:55:10 16:55:11 0    mtest.aaa
#      0       0      0      0 Chunk     16:55:11 16:55:11 0    mtest.bbb
#      0       0      0      0 Chunk     16:55:11 16:55:11 0    mtest.cqy
#      1       0      1      0 GroupBy   16:55:11 16:55:11 2    mtest.t

總結

1、只使用1個DSN主機信息,連接的主庫,加上選項–replicate,需先進行校驗,與pt-table-checksum工具配合使用;

2、只使用1個DSN主機信息,連接的從庫,加上選項–sync-to-master,無需先進行校驗;
3、使用多個DSN主機信息,按照數據同步方向,順序寫好主機信息,根據實際需求加上選項–no-check-slave;

4、推薦使用多個DSN主機信息的方式,同時避免使用選項–replicate和–sync-to-master,無需先進行校驗,只需考慮數據同步的方向。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章