Percona Toolkit 神器全攻略(复制类)
Percona Toolkit 神器全攻略系列共八篇,前文回顾:
全文约定:$
为命令提示符、greatsql>
为 GreatSQL 数据库提示符。在后续阅读中,依据此约定进行理解与操作
复制类
在 Percona Toolkit 中复制类共有以下工具
pt-heartbeat
:监控 MySQL/GreatSQL 复制延迟
pt-slave-delay
:设定从落后主的时间
pt-slave-find
:查找和打印所有 MySQL/GreatSQL 复制层级关系
pt-slave-restart
:监控 Salve 错误,并尝试重启 Salve
pt-table-checksum
:校验主从复制一致性
pt-table-sync
:高效同步表数据
pt-galera-log-explainer
:对多个 Galera 日志进行过滤、聚合和汇总
pt-heartbeat
概要
用来监测主从延迟的情况,此工具的设计为向 Master 中插入一条带有当前时间(GreatSQL 中的 now()函数)的记录到心跳表中,然后,该记录会复制到 Slave 中。Slave 根据当前的系统时间戳(Perl 中的 time 函数)减去 heartbeat 表中的记录值来判断主从的延迟情况。
用法
选项
至少指定 --stop
、 --update
、 --monitor
或 --check
之一
互斥关系
--update
、 --monitor
和 --check
是互斥的
--daemonize
和 --check
是互斥的
该工具所有选项如下
最佳实践
为演示该工具,在主机上部署单机多实例并搭建一主一从模式,环境如下:
首先需要在 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 库的指定时间
用法
选项
该工具所有选项如下
最佳实践
此工具只需在 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
概要
查找和打印主从架构中主库的从库个数,类似于拓扑图的意思
用法
选项
最佳实践
连接到主从集群的 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 复制从库是否有错误,并在复制停止时尝试重新启动复制
用法
选项
最佳实践
在主库创建一张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
的校验 &修复工具,旨在全面满足各类业务需求!
概要
检查 MySQL/GreatSQL 的主从数据是否一致
用法
选项
最佳实践
校验主从数据是否一致(主从端口一致)
主从机器端口一致时,可以使用此方法
检测差异,并写入差异到 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
复制代码
结果如下
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
复制代码
同时结果也保存到了表中
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 表数据
用法
选项
至少指定 --print
、 --execute
或 --dry-run
之一。--where
和 --replicate
是互斥的
最佳实践
同步单个表
注意,同步时候两台机器不能是主从关系。第一 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=
复制代码
本文完 :) 下章节将介绍 Percona Toolkit 神器全攻略(性能类)
评论