Percona Toolkit 神器全攻略(複製類) Percona Toolkit 神器全攻略系列共八篇,前文回顧: 前文回顧 Percona Toolkit 神器全攻略 Percona Toolkit 神器全攻略(實用類) Percona Toolkit 神器全攻略(配置類) Percona T ...
Percona Toolkit 神器全攻略(複製類)
Percona Toolkit 神器全攻略系列共八篇,前文回顧:
前文回顧 |
---|
Percona Toolkit 神器全攻略 |
Percona Toolkit 神器全攻略(實用類) |
Percona Toolkit 神器全攻略(配置類) |
Percona Toolkit 神器全攻略(監控類) |
Percona Toolkit 神器全攻略(系統類) |
Percona Toolkit 神器全攻略(開發類) |
全文約定:
$
為命令提示符、greatsql>
為GreatSQL資料庫提示符。在後續閱讀中,依據此約定進行理解與操作
複製類
在Percona Toolkit中複製類共有以下工具
pt-heartbeat
:監控MySQL/GreatSQL複製延遲pt-slave-delay
:設定從落後主的時間pt-slave-find
:查找和列印所有MySQL/GreatSQL複製層級關係pt-slave-restart
:監控Salve錯誤,並嘗試重啟Salvept-table-checksum
:校驗主從複製一致性pt-table-sync
:高效同步表數據pt-galera-log-explainer
:對多個 Galera 日誌進行過濾、聚合和彙總
pt-heartbeat
概要
用來監測主從延遲的情況,此工具的設計為向 Master 中插入一條帶有當前時間(GreatSQL中的now()函數)的記錄到心跳錶中,然後,該記錄會複製到 Slave 中。Slave 根據當前的系統時間戳(Perl中的time函數)減去heartbeat表中的記錄值來判斷主從的延遲情況。
用法
- pt-heartbeat [OPTIONS] [DSN] --update|--monitor|--check|--stop
選項
至少指定 --stop
、 --update
、 --monitor
或 --check
之一
互斥關係
--update
、 --monitor
和 --check
是互斥的
--daemonize
和 --check
是互斥的
該工具所有選項如下
參數 | 含義 |
---|---|
--ask-pass | 連接MySQL/GreatSQL提示輸入密碼 |
--charset | 預設字元集 |
--check | 檢查一次從機延遲並退出 |
--check-read-only | 檢查伺服器是否啟用了read_only |
--config | 讀取這個逗號分隔的配置文件列表,如果指定,這必須是命令行上的第一個選項 |
--create-table | 如果heartbeat表--table 不存在,則創建它 |
--create-table-engine | 設置用於heartbeat表的引擎 |
--daemonize | 後臺運行 |
--database | 用於連接的資料庫 |
--dbi-driver | 指定連接的驅動程式 |
--defaults-file | 只從給定文件中讀取 GreatSQL 選項 |
--file | 將最新的--monitor 輸出列印到此文件 |
--frames | 平均值的時間範圍,預設為1m,5m,15m |
--help | 顯示幫助 |
--host | 連接到主機 |
--[no]insert-heartbeat-row | 如果--table 中不存在心跳行,則插入該行 |
--interval | 更新或檢查heartbeat表的頻率,預設1秒 |
--log | 後臺運行時將所有輸出列印到此文件 |
--master-server-id | 根據此主伺服器 ID 計算--monitor 或--check 的延遲 |
--monitor | 連續監控從機延遲 |
--fail-successive-errors | 如果指定,將在給定數量的連續 DBI 錯誤(無法連接到伺服器或發出查詢)後失敗 |
--password | 連接時使用的密碼 |
--pid | 創建給定的 PID 文件 |
--port | 用於連接的埠號 |
--print-master-server-id | 列印自動檢測到的或給定的--master-server-id |
--read-only-interval | 當指定--check-read-only 時,發現伺服器處於只讀狀態時休眠的時間間隔 |
--recurse | 在--check 模式下遞歸檢查從站到此深度 |
--recursion-method | 用於查找從站的首選遞歸方法 |
--replace | 使用REPLACE 而不是UPDATE 進行 –update |
--run-time | 運行時間 |
--sentinel | 如果該文件存在則退出 |
--slave-user | 設置用於連接從站的用戶 |
--slave-password | 設置用於連接從站的密碼 |
--set-vars | 在這個以逗號分隔的variable=value 對列表中設置 MySQL/GreatSQL 變數 |
--skew | 延遲檢查多久,預設值:0.5 |
--socket | 用於連接的套接字文件 |
--stop | 通過創建哨兵文件來停止運行實例 |
--table | 用於心跳的表 |
--update | 更新主機的心跳 |
--user | 登錄的用戶 |
--utc | 忽略系統時區並僅使用 UTC |
--version | 顯示版本 |
--[no]version-check | 版本檢查 |
最佳實踐
為演示該工具,在主機上部署單機多實例並搭建一主一從模式,環境如下:
資料庫 | IP | 埠號 | 角色 |
---|---|---|---|
GreatSQL-8.0.32-25 | 192.168.6.55 | 3306 | Master |
GreatSQL-8.0.32-25 | 192.168.6.55 | 3307 | Slave |
首先需要在Master上添加表
$ pt-heartbeat --user=root --ask-pass -S /data/GreatSQL/mysql.sock -D test_db --master-server-id=103306 --create-table --update
-D:選擇一個資料庫中有的庫
--master-server-id:設置主機的server_id
--create-table:用於創建表
--update:會每秒更新一次heartbeat表的記錄
現在進入Master上可以看到在test_db
庫下有一張heartbeat
表,這裡有一條記錄的數據。在Slave節點上也應該出現這張表
greatsql> SELECT * FROM test_db.heartbeat;
+----------------------------+-----------+---------------+----------+-----------------------+---------------------+
| ts | server_id | file | position | relay_master_log_file | exec_master_log_pos |
+----------------------------+-----------+---------------+----------+-----------------------+---------------------+
| 2024-04-22T15:57:44.001900 | 103306 | binlog.000032 | 41464 | NULL | NULL |
+----------------------------+-----------+---------------+----------+-----------------------+---------------------+
1 row in set (0.00 sec)
接下來我們更新主庫上這張表,並讓他在後臺運行
$ pt-heartbeat --user=root --ask-pass -S /data/GreatSQL/mysql.sock -D test_db --master-server-id=103306 --update --daemonize
進入從機,開始監控主從延遲
$ pt-heartbeat --user=root --ask-pass -S /data/GreatSQL02/mysql.sock -D test_db --master-server-id=103306 --monitor --print-master-server-id
Enter password:
0.00s [ 0.00s, 0.00s, 0.00s ] 103306
0.00s [ 0.00s, 0.00s, 0.00s ] 103306
0.00s [ 0.00s, 0.00s, 0.00s ] 103306
0.00s [ 0.00s, 0.00s, 0.00s ] 103306
輸出的結果為:實時延遲,[1分鐘延遲,5分鐘延遲,15分鐘延遲] 主節點的Server_id
-
當然也可以使用
--interval
參數控制主庫上的更新間隔,預設是1秒 -
如果使用守護進程的方式,要關閉的話可以採用
pt-heartbeat --stop
-
單次查看Slave庫上的延遲情況可以把
monitor
換成--check
pt-slave-delay
概要
可能在日常工作中會存在誤刪除數據的可能,所以可以用該工具設置Slave伺服器落後於Master伺服器,達到構建一個延遲從庫
原理
通過啟動和停止複製SQL線程來設置Slave庫落後於Master庫的指定時間
用法
- pt-slave-delay [OPTIONS] SLAVE_DSN [MASTER_DSN]
選項
該工具所有選項如下
參數 | 含義 |
---|---|
--ask-pass | 連接時提示輸入密碼 |
--charset | 預設字元集 |
--config | 讀取這個逗號分隔的配置文件列表,如果指定,這必須是命令行上的第一個選項 |
--[no]continue | 退出後繼續正常複製 |
--daemonize | 後臺運行 |
--database | 用於連接的資料庫 |
--defaults-file | 只從給定文件中讀取MySQL/GreatSQL選項 |
--delay | 從庫延遲於主庫的時間,預設1小時 |
--help | 顯示幫助 |
--host | 連接到主機的IP地址 |
--interval | 啟動或停止的頻率。預設1分鐘 |
--log | 後臺運行時日誌輸出的位置 |
--password | 連接時使用的密碼 |
--pid | 創建給定的 PID 文件 |
--port | 用於連接的埠號 |
--quiet | 不要列印有關操作的信息性消息 |
--run-time | 運行時間,預設是一直運行 |
--set-vars | 在這個以逗號分隔的variable=value 對列表中設置 MySQL/GreatSQL 變數 |
--socket | 用於連接的套接字文件 |
--use-master | 從Master庫獲取二進位日誌位置,而不從Slave庫獲取 |
--user | 用於登錄的用戶 |
--version | 顯示版本 |
--[no]version-check | 版本檢查 |
最佳實踐
此工具只需在Slave庫運行即可,無需在Master節點運行
$ pt-slave-delay --user=root --ask-pass -S /data/GreatSQL02/mysql.sock --delay=1m --interval=15s --run-time=10m
將主從延遲設定為1分鐘,每15秒進行一次檢測,持續運行10分鐘
輸出結果如下
2024-04-23T09:29:00 slave running 0 seconds behind
2024-04-23T09:29:00 STOP SLAVE until 2024-04-23T09:30:00 at master position binlog.000032/500611
2024-04-23T09:29:15 slave stopped at master position binlog.000032/500611
2024-04-23T09:29:30 slave stopped at master position binlog.000032/500611
......中間省略
2024-04-23T09:30:30 Setting slave to run normally
如果在運行的過程中進入Slave節點查看SHOW SLAVE STATUS\G
Slave_IO_Running: Yes
Slave_SQL_Running: No
可以看到SQL線程已關閉,證明此工具精準控制SQL線程的啟停,有效實現主從延遲
也可使用
CHANGE REPLICATION SOURCE TO SOURCE_DELAY=3600;
該命令來控制主從延遲的時間
pt-slave-find
概要
查找和列印主從架構中主庫的從庫個數,類似於拓撲圖的意思
用法
- pt-slave-find [OPTIONS] [DSN]
選項
參數 | 含義 |
---|---|
--ask-pass | 連接MySQL/GreatSQL提示輸入密碼 |
--charset | 預設字元集 |
--config | 讀取這個逗號分隔的配置文件列表,如果指定,這必須是命令行上的第一個選項 |
--databases | 僅檢查此逗號分隔的資料庫列表 |
--defaults-file | 只從給定文件中讀取 MySQL/GreatSQL 選項 |
--help | 顯示幫助 |
--host | 連接到主機 |
--password | 連接時使用的密碼 |
--pid | 創建給定的 PID 文件 |
--port | 用於連接的埠號 |
--recurse | 層次結構中要遞歸的級別數,預設為無限 |
--recursion-method | 用於查找從庫的首選遞歸方法,有三種 (processlist、hosts、none) |
--report-format | 設置列印有關從庫的哪些信息 |
--resolve-address | 將 IP 地址解析為主機名 |
--slave-user | 設置用於連接從庫的用戶 |
--slave-password | 設置用於連接從庫的密碼 |
--set-vars | 以逗號分隔的variable=value 對列表中設置 MySQL/GreatSQL 變數 |
--socket | 用於連接的套接字文件 |
--user | 登錄的用戶 |
--version | 顯示版本 |
最佳實踐
連接到主從集群的Master節點,查看該集群的複製層次數
$ pt-slave-find h=192.168.6.55,u=root --ask-pass
192.168.6.55
Version 8.0.32-25
Server ID 103306
Uptime 20:38:01 (started 2024-04-22T14:09:23)
Replication Is not a slave, has 1 slaves connected, is not read_only
Filters
Binary logging ROW
Slave status
Slave mode STRICT
Auto-increment increment 1, offset 1
InnoDB version 8.0.32-8.0.32
+- 192.168.6.55:3307
Version 8.0.32-25
Server ID 103307
Uptime 20:35:59 (started 2024-04-22T14:12:02)
Replication Is a slave, has 0 slaves connected, is not read_only
Filters
Binary logging ROW
Slave status 0 seconds behind, running, no errors
Slave mode STRICT
Auto-increment increment 1, o
InnoDB version 8.0.32-8.0.32
可以看到該主節點下只有一個從節點,且輸出也顯示了主節點和總結點的信息
pt-slave-restart
概要
監視一個或多個 GreatSQL 複製從庫是否有錯誤,併在複製停止時嘗試重新啟動複製
用法
- pt-slave-restart [OPTIONS] [DSN]
選項
參數 | 含義 |
---|---|
--always | 永不停止Slave線程 |
--ask-pass | 連接MySQL/GreatSQL提示輸入密碼 |
--charset | 預設字元集 |
--[no]check-relay-log | 在檢查從庫錯誤之前檢查最後一個中繼日誌文件和位置 |
--config | 讀取這個逗號分隔的配置文件列表,如果指定,這必須是命令行上的第一個選項 |
--daemonize | 後臺運行 |
--databases | 資料庫列表 |
--defaults-file | 只從給定文件中讀取 MySQL/GreatSQL 選項 |
--error-length | 要列印的錯誤消息的最大長度 |
--error-numbers | 指定跳過哪些錯誤,可用,進行分隔 |
--error-text | 根據錯誤的信息進行匹配跳過 |
--help | 顯示幫助 |
--host | 連接到主機 |
--log | 後臺運行時,將輸出列印到此文件 |
--max-sleep | 再次輪詢從庫之前休眠的最長時間 |
--min-sleep | 再次輪詢從庫之前休眠眠的最短時間 |
--monitor | 是否監控從機(預設) |
--password | 連接時使用的密碼 |
--pid | 創建給定的 PID 文件 |
--port | 用於連接的埠號 |
--quiet | 抑制正常輸出(禁用--verbose ) |
--recurse | 在主庫執行,監控從庫,預設深度 0 表示“僅監視指定的從庫” |
--recursion-method | 用於查找從庫的首選遞歸方法 |
--run-time | 運行時間 |
--sentinel | 如果該文件存在則退出,預設值:/tmp/pt-slave-restart-sentinel |
--slave-user | 設置用於連接從庫的用戶 |
--slave-password | 設置用於連接從庫的密碼 |
--set-vars | 以逗號分隔的variable=value 對列表中設置 MySQL/GreatSQL 變數 |
--skip-count | 重新啟動從庫時要跳過的語句數,預設1 |
--master-uuid | 使用 GTID 時,應創建一個空事務以便跳過它 |
--sleep | 檢查從庫之間的初始睡眠秒數 |
--socket | 用於連接的套接字文件 |
--stop | 停止運行實例 |
--until-master | 運行到指定的master_log_pos,file位置後停止 |
--until-relay | 運行到指定的中繼日誌文件和位置後停止 |
--user | 用於登錄的用戶 |
--verbose | 向輸出添加更多信息 |
--version | 顯示版本 |
--[no]version-check | 版本檢查 |
最佳實踐
在主庫創建一張t1
表,並插入5條數據
greatsql> CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(255) NOT NULL);
greatsql> INSERT INTO t1 (name) VALUES ('張三');
greatsql> INSERT INTO t1 (name) VALUES ('李四');
greatsql> INSERT INTO t1 (name) VALUES ('王五');
greatsql> INSERT INTO t1 (name) VALUES ('趙六');
greatsql> INSERT INTO t1 (name) VALUES ('孫七');
主庫查看數據
greatsql> SELECT * FROM test_db.t1;
+----+--------+
| id | name |
+----+--------+
| 1 | 張三 |
| 2 | 李四 |
| 3 | 王五 |
| 4 | 趙六 |
| 5 | 孫七 |
+----+--------+
5 rows in set (0.00 sec)
從庫查看數據
greatsql> SELECT * FROM test_db.t1;
+----+--------+
| id | name |
+----+--------+
| 1 | 張三 |
| 2 | 李四 |
| 3 | 王五 |
| 4 | 趙六 |
| 5 | 孫七 |
+----+--------+
5 rows in set (0.00 sec)
主動處理錯誤
在從庫執行pt-slave-restart工具監控從庫
$ pt-slave-restart h=192.168.6.55,P=3307,u=root --ask-pass
註意,若使用該工具,參數
slave_parallel_workers
必須設置為0,否則會報錯”Cannot skip transactions properly because GTID is enabled and slave_parallel_workers > 0. See 'GLOBAL TRANSACTION IDS' in the tool's documentation.“ 如果不關閉多線程複製,工具會分不清到底哪個線程複製出了問題
此時已經開啟了從庫監控,我們在主庫上人為造成一個主從複製錯誤
greatsql> SET sql_log_bin=0;
greatsql> INSERT INTO t1 VALUES(6,'周八');
greatsql> SET sql_log_bin=1;
greatsql> DELETE FROM t1 WHERE id=6;
此時工具檢測到了主從複製異常,並且馬上修複了該錯誤,使主從複製正常運行
$ pt-slave-restart h=192.168.6.55,P=3307,u=root --ask-pass
# 時間戳 + 從庫端信息 + relay log + relat log 位置 + 主從複製報錯碼
2024-04-24T10:33:54 P=3307,h=192.168.6.55,u=root myarch-relay-bin.000003 36702 1032
手動處理錯誤
如果一直運行工具,檢測到錯誤會直接修複。如果是已經有錯誤了要如何使用該工具修複?還是同樣的錯誤,再次主庫手動執行
greatsql> SET sql_log_bin=0;
greatsql> INSERT INTO t1 VALUES(6,'周八');
greatsql> SET sql_log_bin=1;
greatsql> DELETE FROM t1 WHERE id=6;
此時查看從庫報錯
greatsql> SHOW SLAVE STATUS\G
Slave_IO_Running: Yes
Slave_SQL_Running: No
Last_SQL_Error: Could not execute Delete_rows event on table test_db.t1; Can't find record in 't1', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log binlog.000032, end_log_pos 504208
記住報錯的錯誤碼1032
,接著在從庫機器上使用該工具
$ pt-slave-restart h=192.168.6.55,P=3307,u=root --ask-pass --error-numbers=1032
使用
--error-numbers=
指定錯誤碼
此時就會輸出對應的信息
$ pt-slave-restart h=192.168.6.55,P=3307,u=root --ask-pass --error-numbers=1032
2024-04-24T10:49:26 P=3307,h=192.168.6.55,u=root myarch-relay-bin.000003 37046 1032
接著在從庫上查看主從狀態,就可以看到主從複製已經是正常的了
greatsql> SHOW SLAVE STATUS\G
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Last_SQL_Error:
pt-table-checksum
這款數據校驗與修複工具雖廣受歡迎,卻存在不容忽視的短板:不支持MySQL/GreatSQL的MGR場景、國內普遍的上雲下雲業務,以及MySQL/GreatSQL與Oracle間的異構資料庫等多元化場景。為了攻剋這些難題,GreatSQL推出了名為gt-checksum
的校驗&修複工具,旨在全面滿足各類業務需求!
- Gitee倉庫地址:https://gitee.com/GreatSQL/gt-checksum
概要
檢查 MySQL/GreatSQL 的主從數據是否一致
用法
- pt-table-checksum [OPTIONS] [DSN]
選項
參數 | 含義 |
---|---|
--ask-pass | 連接MySQL/GreatSQL提示輸入密碼 |
--channel | 指定複製通道 |
--[no]check-binlog-format | 檢查所有伺服器上的binlog_format系統參數是否相同 |
--binary-index | 修改--create-replicate-table 的行為,使複製表的上下邊界列以 BLOB 數據類型創建 |
--check-interval | 指定因選項--max-lag 檢查之間休眠時間 |
--[no]check-plan | 檢查查詢執行計劃的安全性 |
--[no]check-replication-filters | 指定檢測主從複製是否有設置複製過濾器 |
--check-slave-lag | 指定複製延遲大於選項--max-lag 指定的值之後暫停檢查校驗操作 |
--[no]check-slave-tables | 檢查從庫上的表是否存在並具有所有校驗和--columns |
--chunk-index | 指定使用哪個索引對錶進行chunk分塊操作 |
--chunk-index-columns | 指定使用選項--chunk-index 的索引使用最左首碼幾個索引欄位,只適用於複合索引 |
--chunk-size | 為每個校驗和查詢選擇的行數,允許的尾碼單位為k、M、G |
--chunk-size-limit | 指定chunk的行數最多可以超過選項--chunk-size 指定的行數的多少倍 |
--chunk-time | 動態調整每個chunk的大小使相應的表行數都在指定的時間內完成校驗操作 |
--columns | 指定只需要校驗的欄位,如有多個則用逗號隔開 |
--config | 讀取這個逗號分隔的配置文件列表,如果指定,這必須是命令行上的第一個選項 |
--[no]create-replicate-table | 創建選項--replicate 指定的資料庫和表 |
--databases | 僅對逗號分隔的資料庫列表進行校驗 |
--databases-regex | 僅名稱與此正則表達式匹配和資料庫進行校驗 |
--defaults-file | 只從給定文件中讀取 MySQL/GreatSQL 選項 |
--disable-qrt-plugin | 如果啟用了 QRT(查詢響應時間)插件,請將其禁用 |
--[no]empty-replicate-table | 在對錶進行校驗和之前,刪除每個表之前的校驗和 |
--engines | 僅校驗使用這些存儲引擎的表 |
--explain | 顯示但不執行校驗和查詢(禁用--[no]empty-replicate-table ) |
--fail-on-stopped-replication | 若複製停止,則會失敗並顯示錯誤(退出狀態 128),而不是等到複製重新啟動 |
--float-precision | FLOAT 和 DOUBLE 數字到字元串轉換的精度 |
--function | 指定校驗操作使用的哈希函數。可選函數有SHA1、MD5等 |
--help | 顯示幫助 |
--host | 連接到主機 |
--ignore-columns | 指定需要忽略校驗的欄位 |
--ignore-databases | 指定需要忽略校驗的資料庫 |
--ignore-databases-regex | 指定採用正則表達式匹配忽略校驗的資料庫 |
--ignore-engines | 指定需要忽略校驗的存儲引擎列表 |
--ignore-tables | 指定需要忽略校驗的表 |
--ignore-tables-regex | 指定採用正則表達式匹配忽略校驗的表 |
--max-lag | 指定允許主從複製延遲時長的最大值,單位秒 |
--max-load | 在每個塊之後檢查`SHOW GLOBAL STATUS,如果任何狀態變數高於閾值則暫停 |
--password | 連接時使用的密碼 |
--pause-file | 當此參數指定的文件存在時,執行將暫停 |
--pid | 創建給定的 PID 文件 |
--plugin | 定義pt_table_checksum_plugin 類的 Perl 模塊文件 |
--port | 用於連接的埠號 |
--progress | 將進度報告列印到 STDERR |
--quiet | 僅列印最重要的信息(禁用 --progress ) |
--recurse | 指定搜尋從庫的層級,預設無限 |
--recursion-method | 指定獲取從庫的方式 |
--replicate | 將校驗和結果寫入此表 |
--[no]replicate-check | 指定在校驗完每張表後檢查主從當前表是否出現不一致 |
--replicate-check-only | 檢查副本的一致性,而無需執行校驗和查詢 |
--replicate-check-retries | 指定當校驗出主從數據不一致重試校驗的次數 |
--replicate-database | 指定工具在執行校驗操作時在哪個資料庫下進行 |
--resume | 指定從最後完成校驗的chunk開始恢覆校驗 |
--retries | 指定當出現非嚴重性錯誤時重覆校驗一個塊的次數 |
--run-time | 指定校驗操作運行的時間 |
--separator | 用於 CONCAT_WS() 的分隔符 |
--skip-check-slave-lag | 指定DSN連接從庫時跳過主從延遲檢查,可以指定多個從庫檢查 |
--slave-user | 設置用於連接從庫的用戶 |
--slave-password | 設置用於連接從庫的密碼 |
--set-vars | 運行檢查時指定參數值,如有多個用逗號分隔 |
--socket | 用於連接的套接字文件 |
--slave-skip-tolerance | 當主表被標記為僅在一個塊中進行校驗和,但從表超過了可接受的最大大小時,該表將被跳過 |
--tables | 僅對這個以逗號分隔的表列表進行校驗和 |
--tables-regex | 僅對名稱與此 Perl 正則表達式匹配的表進行校驗 |
--trim | 將 TRIM() 添加到 VARCHAR 列(在比較 4.1 和 >= 5.0 時有幫助) |
--truncate-replicate-table | 在開始校驗和之前截斷複製表 |
--user | 登錄的用戶 |
--version | 顯示版本 |
--[no]version-check | 版本檢查 |
--where | 僅執行與此 WHERE 子句匹配的行 |
最佳實踐
校驗主從數據是否一致(主從埠一致)
主從機器埠一致時,可以使用此方法
檢測差異,並寫入差異到checksums表中,主庫上執行如下命令
pt-table-checksum --create-replicate-table --replicate=test_db.checksums --nocheck-replication-filters --nocheck-binlog-format --recursion-method=processlist --databases=test_db --user=root --ask-pass --host=192.168.6.55 --port=3306
-
--nocheck-replication-filters:不檢查複製過濾器,建議啟用
-
--no-check-binlog-format:不檢查複製的binlog模式,要是binlog模式是ROW,則會報錯
結果如下
Checking if all tables can be checksummed ...
Starting checksum ...
TS ERRORS DIFFS ROWS DIFF_ROWS CHUNKS SKIPPED TIME TABLE
04-24T15:57:13 0 0 9 0 1 0 0.008 test_db.test_t1
- TS:完成檢查的時間
- ERRORS:檢查時候發生錯誤和警告的數量
- DIFFS:0表示一致,非0表示不一致
- DIFF_ROWS:主庫和從庫差異的數據行數
- CHUNKS:被劃分到表中的塊的數目
- SKIPPED:由於錯誤或警告或過大,則跳過塊的數目
- TIME:執行的時間
- TABLE:被檢查的表名
同時結果也保存到了表中
greatsql> select * from checksums;
+---------+--------------------+-------+------------+-------------+----------------+----------------+----------+----------+------------+------------+---------------------+
| db | tbl | chunk | chunk_time | chunk_index | lower_boundary | upper_boundary | this_crc | this_cnt | master_crc | master_cnt | ts |
+---------+--------------------+-------+------------+-------------+----------------+----------------+----------+----------+------------+------------+---------------------+
| test_db | t1 | 1 | 0.001848 | NULL | NULL | NULL | 6d60e23f | 5 | 6d60e23f | 5 | 2024-04-24 16:29:30 |
+---------+--------------------+-------+------------+-------------+----------------+----------------+----------+----------+------------+------------+---------------------+
1 rows in set (0.01 sec)
校驗主從數據是否一致(主從埠不一致)
主從機器埠不一致時,可以使用此方法
在主庫創建一張DSN表
greatsql> CREATE TABLE test_db.dsns ( id int(11) NOT NULL AUTO_INCREMENT, parent_id int(11) DEFAULT NULL,dsn varchar(255) NOT NULL, PRIMARY KEY (id) );
greatsql> INSERT INTO test_db.dsns(dsn) VALUES ('h=192.168.6.55,P=3307,u=root,p=');
使用工具校驗,註意此時--recursion-method
就要改為DSN模式
$ pt-table-checksum --replicate=test_db.checksums --nocheck-replication-filters --no-check-binlog-format --host=192.168.6.55 --port=3306 --user=root --ask-pass --databases=test_db --recursion-method dsn=h=192.168.6.55,D=test_db,t=dsns
結果如下
Checking if all tables can be checksummed ...
Starting checksum ...
TS ERRORS DIFFS ROWS DIFF_ROWS CHUNKS SKIPPED TIME TABLE
04-24T17:04:42 0 0 1 0 1 0 0.035 test_db.dsns
04-24T17:04:42 0 0 1 0 1 0 0.022 test_db.heartbeat
04-24T17:04:42 0 0 0 0 1 0 0.036 test_db.my_table
04-24T17:04:42 0 2 10000 9823 4 0 0.097 test_db.ptosc
04-24T17:04:42 0 0 5 0 1 0 0.021 test_db.t1
04-24T17:04:42 0 1 15 15 1 0 0.026 test_db.tc10011_ta4
04-24T17:04:42 0 1 9 9 1 0 0.078 test_db.test_t1
04-24T17:04:42 0 0 0 0 1 0 0.066 test_db.test_table
可以看到有三張表被檢測出來不一致。如果連表都不存在則會報錯Table 'XXXX' doesn't exist
出現了主從數據不一致,就要使用pt-table-sync
工具進行修複
pt-table-sync
概要
高效同步 MySQL/GreatSQL 表數據
用法
- pt-table-sync [OPTIONS] DSN [DSN]
選項
至少指定 --print
、 --execute
或 --dry-run
之一。--where
和 --replicate
是互斥的
參數 | 含義 |
---|---|
--algorithms | 比較表時使用的演算法(按優先順序),預設值:Chunk、Nibble、GroupBy、Stream |
--ask-pass | 連接 MySQL/GreatSQL 提示輸入密碼 |
--bidirectional | 啟用第一個和後續主機之間的雙向同步 |
--[no]bin-log | 指定同步操作記錄二進位日誌,相當於執行SET SQL_LOG_BIN=1 |
--buffer-in-mysql | 指定 MySQL/GreatSQL 在其記憶體中緩衝查詢 |
--[no]buffer-to-client | 比較時從 MySQL/GreatSQL 中逐一獲取行 |
--channel | 指定複製通道 |
--charset | 預設字元集 |
--[no]check-child-tables | 檢查--execute 是否會對子表產生不利影響 |
--[no]check-master | 指定當選項--sync-to-master 時,嘗試驗證工具連接到的主庫是否是真正的主庫 |
--[no]check-slave | 檢查目標伺服器是否為從伺服器 |
--[no]check-triggers | 檢查目標表上是否未定義觸發器 |
--chunk-column | 指定根據表中欄位對錶進行chunk操作 |
--chunk-index | 指定使用哪個索引對錶進行chunk分塊操作 |
--chunk-size | 每個塊的行數或數據大小 |
--columns | 比較以逗號分隔的列列表 |
--config | 讀取這個逗號分隔的配置文件列表,如果指定,這必須是命令行上的第一個選項 |
--conflict-column | 當--bidirectional 同步期間發生行衝突時比較此列 |
--conflict-comparison | 選擇具有此屬性的--conflict-column 作為源 |
--conflict-error | 如何報告無法解決的衝突和衝突錯誤,預設為:warn(警告) |
--conflict-threshold | 一個--conflict-column 必須超過另一個的數量 |
--conflict-value | 將此值用於某些--conflict-comparison |
--databases | 僅同步的資料庫列表,如有多個用逗號分隔 |
--defaults-file | 只從給定文件中讀取 GreatSQL 選項 |
--dry-run | 分析、決定要使用的同步演算法、列印並退出 |
--engines | 僅同步的存儲引擎列,如有多個用逗號分隔 |
--execute | 執行查詢以使表具有相同的數據 |
--explain-hosts | 列印連接信息並退出 |
--float-precision | FLOAT 和 DOUBLE 數字到字元串轉換的精度 |
--[no]foreign-key-checks | 啟用外鍵檢查 (SET FOREIGN_KEY_CHECKS=1 ) |
--function | 選擇使用哪個哈希函數作為校驗和,預設為 CRC32 |
--help | 顯示幫助 |
--[no]hex-blob | HEX() BLOB、TEXT和 BINARY列 |
--host | 連接到主機 |
--ignore-columns | 要忽略的列,如有多個用逗號分隔 |
--ignore-databases | 要忽略的資料庫,如有多個用逗號分隔 |
--ignore-engines | 要忽略的引擎,如有多個用逗號分隔 |
--ignore-tables | 要忽略的表,如有多個用逗號分隔 |
--ignore-tables-regex | 要忽略的表正則表達式,如有多個用逗號分隔 |
--[no]index-hint | 將 FORCE/USE INDEX 提示添加到塊和行查詢中 |
--lock | 鎖定表:0=永不鎖表,1=每個同步周期鎖表,2=表操作時鎖表,3=每個DSN連接的伺服器鎖表 |
--lock-and-rename | 指定鎖定源表和目標表,執行同步操作,然後進行表名交換 |
--password | 連接時使用的密碼 |
--pid | 創建給定的 PID 文件 |
--port | 用於連接的埠號 |
列印將解決差異的查詢 | |
--recursion-method | 用於查找從站的首選遞歸方法 |
--replace | 將所有INSERT 和UPDATE 語句寫為REPLACE |
--replicate | 同步此表中列為不同的表 |
--slave-user | 設置用於連接從庫的用戶 |
--slave-password | 設置用於連接從庫的密碼 |
--set-vars | 以逗號分隔的variable=value 對列表中設置 MySQL/GreatSQL 變數 |
--socket | 用於連接的套接字文件 |
--sync-to-master | 指定將DSN連接信息確認為從庫,並同步信息到主庫 |
--tables | 要同步的表,如有多個用逗號分隔 |
--timeout-ok | 指定當選項--wait 導致工具執行失敗時跳過失敗繼續執行 |
--[no]transaction | 指定工具操作使用事務代替LOCK TABLES語句進行鎖表 |
--trim | BIT_XOR 和 ACCUM 模式下的 TRIM() VARCHAR 列 |
--[no]unique-checks | 啟用唯一鍵檢查 ( SET UNIQUE_CHECKS=1 ) |
--user | 用於連接的用戶 |
--verbose | 列印同步操作的結果 |
--version | 顯示版本 |
--[no]version-check | 版本檢查 |
--wait | 指定存在主從複製延遲時從庫可以等待多長時間追上主庫,如果超過時間依然存在延遲就中止退出 |
--where | WHERE 子句用於限制同步到表的一部分 |
--[no]zero-chunk | 為具有零或零等值的行添加塊 |
最佳實踐
同步單個表
註意,同步時候兩台機器不能是主從關係。第一DSN為源庫,第二個DSN為被同步庫
將192.168.6.55機器上的test_db.test_t1
表同步至192.168.6.129機器
$ pt-table-sync --execute h=192.168.6.55,u=root,p=,P=3306,D=test_db,t=test_t1 h=192.168.6.129,p=test,u=test,P=3306
同步單個庫
註意,同步時候兩台機器不能是主從關係。第一DSN為源庫,第二個DSN為被同步庫
$ pt-table-sync --execute h=192.168.6.55,u=root,p=,P=3306 h=192.168.6.129,u=test,p=test --databases test_db
此時如果有表不存在,則會報錯
Table test_db.checksums does not exist on P=3306,h=192.168.6.129,p=...,u=test while doing test_db.checksums on 192.168.6.129
此時只需手動建表即可
同步所有庫表
註意,同步時候兩台機器不能是主從關係。第一DSN為源庫,第二個DSN為被同步庫
$ pt-table-sync --execute h=192.168.6.55,u=root,p=,P=3306 h=192.168.6.129,u=test,p=test
主從複製同步從庫
同步test_db.checksums
中記錄的數據不一致的表。該表中的數據是由pt-table-checksum
工具檢測出來的
$ pt-table-sync --execute --replicate 'test_db.checksums' --sync-to-master h=192.168.6.55,P=3307,u=root,p=
本文完