写点什么

Percona Toolkit 神器全攻略(复制类)

作者:GreatSQL
  • 2024-09-06
    福建
  • 本文字数:6533 字

    阅读完需:约 21 分钟

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 表中的记录值来判断主从的延迟情况。


用法


  • pt-heartbeat [OPTIONS] [DSN] --update|--monitor|--check|--stop

选项

至少指定 --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-idEnter password:0.00s [  0.00s,  0.00s,  0.00s ] 1033060.00s [  0.00s,  0.00s,  0.00s ] 1033060.00s [  0.00s,  0.00s,  0.00s ] 1033060.00s [  0.00s,  0.00s,  0.00s ] 103306
复制代码


输出的结果为:实时延迟,[1 分钟延迟,5 分钟延迟,15 分钟延迟] 主节点的 Server_id


  1. 当然也可以使用--interval参数控制主库上的更新间隔,默认是 1 秒

  2. 如果使用守护进程的方式,要关闭的话可以采用pt-heartbeat --stop

  3. 单次查看 Slave 库上的延迟情况可以把monitor换成--check

pt-slave-delay

概要

可能在日常工作中会存在误删除数据的可能,所以可以用该工具设置 Slave 服务器落后于 Master 服务器,达到构建一个延迟从库


原理


通过启动和停止复制 SQL 线程来设置 Slave 库落后于 Master 库的指定时间


用法


  • pt-slave-delay [OPTIONS] SLAVE_DSN [MASTER_DSN]

选项

该工具所有选项如下


最佳实践

此工具只需在 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 behind2024-04-23T09:29:00 STOP SLAVE until 2024-04-23T09:30:00 at master position binlog.000032/5006112024-04-23T09:29:15 slave stopped at master position binlog.000032/5006112024-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: YesSlave_SQL_Running: No
复制代码


可以看到 SQL 线程已关闭,证明此工具精准控制 SQL 线程的启停,有效实现主从延迟


也可使用CHANGE REPLICATION SOURCE TO SOURCE_DELAY=3600;该命令来控制主从延迟的时间

pt-slave-find

概要

查找和打印主从架构中主库的从库个数,类似于拓扑图的意思


用法


  • pt-slave-find [OPTIONS] [DSN]

选项

最佳实践

连接到主从集群的 Master 节点,查看该集群的复制层次数


$ pt-slave-find h=192.168.6.55,u=root --ask-pass192.168.6.55Version         8.0.32-25Server ID       103306Uptime          20:38:01 (started 2024-04-22T14:09:23)Replication     Is not a slave, has 1 slaves connected, is not read_onlyFiltersBinary logging  ROWSlave statusSlave mode      STRICTAuto-increment  increment 1, offset 1InnoDB 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]

选项

最佳实践

在主库创建一张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\GSlave_IO_Running: YesSlave_SQL_Running: NoLast_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\GSlave_IO_Running: YesSlave_SQL_Running: YesLast_SQL_Error:
复制代码

pt-table-checksum

这款数据校验与修复工具虽广受欢迎,却存在不容忽视的短板:不支持 MySQL/GreatSQL 的 MGR 场景、国内普遍的上云下云业务,以及 MySQL/GreatSQL 与 Oracle 间的异构数据库等多元化场景。为了攻克这些难题,GreatSQL 推出了名为gt-checksum的校验 &修复工具,旨在全面满足各类业务需求!


概要

检查 MySQL/GreatSQL 的主从数据是否一致


用法


  • pt-table-checksum [OPTIONS] [DSN]

选项

最佳实践

校验主从数据是否一致(主从端口一致)

主从机器端口一致时,可以使用此方法


检测差异,并写入差异到 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 TABLE04-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 TABLE04-24T17:04:42      0      0        1          0       1       0   0.035 test_db.dsns04-24T17:04:42      0      0        1          0       1       0   0.022 test_db.heartbeat04-24T17:04:42      0      0        0          0       1       0   0.036 test_db.my_table04-24T17:04:42      0      2    10000       9823       4       0   0.097 test_db.ptosc04-24T17:04:42      0      0        5          0       1       0   0.021 test_db.t104-24T17:04:42      0      1       15         15       1       0   0.026 test_db.tc10011_ta404-24T17:04:42      0      1        9          9       1       0   0.078 test_db.test_t104-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 是互斥的


最佳实践

同步单个表

注意,同步时候两台机器不能是主从关系。第一 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 神器全攻略(性能类)


发布于: 刚刚阅读数: 5
用户头像

GreatSQL

关注

GreatSQL社区 2023-01-31 加入

GreatSQL是由万里数据库维护的MySQL分支,专注于提升MGR可靠性及性能,支持InnoDB并行查询特性,是适用于金融级应用的MySQL分支版本。 社区:https://greatsql.cn/ Gitee: https://gitee.com/GreatSQL/GreatSQL

评论

发布
暂无评论
Percona Toolkit 神器全攻略(复制类)_GreatSQL_InfoQ写作社区