当前位置: 首页 > 工具软件 > MySQL-Sync > 使用案例 >

pt工具的使用(6) pt-table-sync的使用

轩辕庆
2023-12-01

一、描述

pt-table-sync同步表数据,解决主从不一致的利器,使用之前注意做好备份,当使用–replicate或–sync-to-master方法同步作为复制从属的服务器时,它总是 在复制主服务器上进行更改,而不是直接在复制从属服务器上进行

二、实践

ps: 以下是三种使用方式不是执行顺序,可以print重定向后生成并执行sql文件,也可以通过excucte直接执行

1.打印结果

# 填写主库链接,用户名,密码
pt-table-sync --print  --charset=utf8 --recursion-method=hosts --replicate=test.checksums  h=host,u=user,p=password -d test_1 -t a > 1.sql
pt-table-sync --print --replace  --charset=utf8 --recursion-method=hosts --replicate=test.checksums  h=host,u=user,p=password -d test_1 -t a 
# 输出结果 REPLACE INTO `test_1`.`a`(`id`, `name`) VALUES ('60', 'a4217')

# 填写从库链接,用户名,密码
pt-table-sync --print  --charset=utf8 --sync-to-master h=host,P=port,u=user,p=password   -d test_1 -t a
 pt-table-sync --print  --charset=utf8 --sync-to-master --replicate=test.checksums h=host,P=port,u=user,p=password  -d test_1 -t a

2.试运行

pt-table-sync --dry-run  --charset=utf8 --sync-to-master h=host,P=port,u=user,p=password   -d test_1 -t a
# 输出如下
# NOTE: --dry-run does not show if data needs to be synced because it
#       does not access, compare or sync data.  --dry-run only shows
#       the work that would be done.
# Syncing via replication A=utf8,P=****,h=******,p=...,u=root in dry-run mode, without accessing or comparing data
# DELETE REPLACE INSERT UPDATE ALGORITHM START    END      EXIT DATABASE.TABLE
#      0       0      0      0 Chunk     18:28:43 18:28:43 0    test_1.a

3.执行

pt-table-sync --execute --replace  --charset=utf8 --recursion-method=hosts --replicate=test.checksums  h=host,u=user,p=password -d test_1 -t a 


pt-table-sync --execute  --charset=utf8 --sync-to-master h=host,P=port,u=user,p=password   -d test_1 -t a
 pt-table-sync --execute  --charset=utf8 --sync-to-master --replicate=test.checksums h=host,P=port,u=user,p=password  -d test_1 -t a

全局日志

2021-09-28T07:25:17.872683Z	  264 Query	START TRANSACTION /*!40108 WITH CONSISTENT SNAPSHOT */
2021-09-28T07:25:17.881886Z	  264 Query	SELECT /*test_1.a:2/11*/ 1 AS chunk_num, COUNT(*) AS cnt, COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS('#', `id`, `name`, CONCAT(ISNULL(`name`)))) AS UNSIGNED)), 10, 16)), 0) AS crc FROM `test_1`.`a` FORCE INDEX (`PRIMARY`) WHERE (`id` > 0 AND `id` < '1001') FOR UPDATE
2021-09-28T07:25:17.891155Z	  265 Query	SHOW MASTER STATUS
2021-09-28T07:25:17.950078Z	  264 Query	SET @crc := '', @cnt := 0
2021-09-28T07:25:17.967039Z	  264 Query	SELECT /*rows in chunk*/ `id`, `name`, CRC32(CONCAT_WS('#', `id`, `name`, CONCAT(ISNULL(`name`)))) AS __crc FROM `test_1`.`a` FORCE INDEX (`PRIMARY`) WHERE (`id` > 0 AND `id` < '1001') ORDER BY `id` FOR UPDATE
2021-09-28T07:25:18.008473Z	  264 Query	SELECT `id`, `name` FROM `test_1`.`a` WHERE `id`='60' LIMIT 1
2021-09-28T07:25:18.017940Z	  264 Query	REPLACE INTO `test_1`.`a`(`id`, `name`) VALUES ('60', 'a4217') /*percona-toolkit src_db:test_1 src_tbl:a 
。。。。。。。
2021-09-28T07:25:18.027475Z	  264 Query	SELECT `id`, `name` FROM `test_1`.`a` WHERE `id`='120' LIMIT 1
2021-09-28T07:25:18.036961Z	  264 Query	REPLACE INTO `test_1`.`a`(`id`, `name`) VALUES ('120', 'a1030') /*percona-toolkit src_db:test_1 src_tbl:a 
。。。。。
2021-09-28T07:25:18.046432Z	  264 Query	SET @crc := '', @cnt := 0
2021-09-28T07:25:18.062958Z	  264 Query	commit

三、参数详解

参数意义
--algorithms=s对比表的算法 (默认 Chunk,Nibble,GroupBy,Stream)
--bidirectional双向同步(新功能),
限制:
仅在将一台服务器同步到其他独服务器时有效
对复制不起作用
要求表可使用 Chunk 算法分块
不是N路,一次只能在两个服务器之间双向同步
不处理 DELETE 更改
--algorithms=s对比表的算法 (默认 Chunk,Nibble,GroupBy,Stream)
--[no]bin-log记录到二进制日志(set SQL_LOG_BIN=1)
--buffer-in-mysql指示 MySQL 在其内存中缓冲查询。
此选项将 SQL_BUFFER_RESULT 选项添加到比较查询。 这会导致 MySQL 在将结果发送回 pt-table-sync 之前执行查询并将它们放在内部的临时表中。 这种策略的优点是 pt-table-sync 可以根据需要获取行,而无需在 Perl 进程内部使用大量内存,同时释放 MySQL 表上的锁(以减少与其他查询的争用)。 缺点是它在 MySQL 服务器上使用更多内存。
您可能也希望启用 --[no]buffer-to-client,因为缓冲到临时表然后将其全部提取到 Perl 的内存中可能是一件愚蠢的事情。 此选项对于 GroupBy 和 Stream 算法最有用,它们可能会从服务器获取大量数据。
--[no]buffer-to-client比较时从 MySQL 中一一获取行。
此选项启用 mysql_use_result,这会导致 MySQL 将所选行保存在服务器上,直到该工具获取它们。 这允许该工具使用更少的内存,但可能会使行在服务器上锁定更长时间。
如果通过指定 --no-buffer-to-client 禁用此选项,则使用 mysql_store_result 使 MySQL 一次将所有选定的行发送到该工具。 这可能会导致结果集在服务器上保持打开的时间较短,但如果表很大,它可能需要很长时间,并且会占用所有的内存。
对于一般数据大小,启用此选项
使用 --bidirectional 时禁用此选项。
--[no]check-child-tables检查 --execute 是否会对子表产生不利影响。当指定 --replace、 --replicate 或 --sync-to-master 时,该工具可能使用 REPLACE 语句同步表。如果正在同步的表具有 ON DELETE CASCADE、ON UPDATE CASCADE 或 ON UPDATE SET NULL 的子表,则该工具会打印错误并跳过该表,因为 REPLACE会先delete再insert,这回删除子表的行
指定 --no-check-child-tables 以禁用此检查。为了完全避免影响子表,还要指定 --no-foreign-key-checks 以便 MySQL 不会从父表到子表级联任何操作。
仅当指定了 --execute 和 --replace、–replicate 或 --sync-to-master 之一时,才会执行此检查。 --print 不检查子表。
该错误消息仅打印找到的第一个具有 ON DELETE CASCADE、ON UPDATE CASCADE 或 ON UPDATE SET NULL 外键约束的子表。可能还有其他受影响的子表。
--[no]check-master使用 --sync-to-master时,尝试验证检测到的 master 是否是真正的 master。
--[no]check-slave检查目标服务器是否为从服务器。
--[no]check-triggers检查目标表上是否未定义触发器。
--conflict-column=s在 --bidirectional 同步期间行冲突时比较此列。根据–conflict-comparison、–conflict-value 和–conflict-threshold 比较每一行中该列的值,以确定哪一行具有正确的数据并成为源。 该列可以是具有适当 --conflict-comparison 的任何类型( blob 除外)。
--conflict-comparison=s选择具有此属性的 --conflict-column 作为源。
newest|oldest|greatest|least|equals|matches
--conflict-error=s如何报告无法解决的冲突和冲突错误
warn:输出一条关于冲突的报警。
die:停止同步并输出一条警告
--conflict-threshold=s一个 --conflict-column 必须超过另一个的数量。
如果两个 --conflict-column 值之间的绝对差异小于此数量,则 --conflict-threshold 会阻止解决冲突。 例如,如果两个 --conflict-column 具有时间戳值“2009-12-01 12:00:00”和“2009-12-01 12:05:00”,则差异为 5 分钟。 如果 --conflict-threshold 设置为“5m”,冲突将得到解决,但如果 --conflict-threshold 设置为“6m”,则冲突将无法解决,因为差异不大于或等于 6 分钟。 在后一种情况下, --conflict-error 将报告失败。
--conflict-value=s将此值用于某些 --conflict-comparison。此选项给出等于和匹配的值 --conflict-comparison。
--dry-run分析、决定使用的同步算法、打印和退出。
暗示–verbose你可以看到结果。结果与您在实际运行该工具时看到的输出格式相同,但受影响的行将为零。这是因为该工具实际执行,但在比较任何数据之前停止并仅返回零。零并不意味着不需要进行任何更改。
--execute执行表数据同步
--explain-hosts打印连接信息并退出。
--foreign-key-checks启用外键检查 (SET FOREIGN_KEY_CHECKS=1 )。
--[no]hex-blob针对BLOB, TEXT 和BINARY类型的字段,当从源获取行数据以创建查询以同步数据(即通过 看到–print和执行的查询–execute)时,二进制列被包装在 HEX() 中,因此二进制数据不会产生无效的 SQL 语句
--[no]index-hint向块和行查询添加 FORCE/USE INDEX 提示
--lock=i锁定表:0=无,1=每个同步周期锁定和解锁一次(例如锁定每个块),2=每个表,或 3=全局
--lock-and-rename锁定源表和目标表,同步,然后交换名称
--print打印将解决差异的查询。
--replace将所有INSERT和UPDATE语句写为REPLACE,当存在唯一索引违规时,它会根据需要自动打开。
--sync-to-master将 DSN 视为从站并将其同步到其主站。将指定的服务器视为从服务器。 检查 SHOW SLAVE STATUS,连接到服务器的 master,并将 master 视为源,将 slave 视为目标。 导致在主服务器上进行更改。 默认情况下将 --wait 设置为 60,默认情况下将 --lock 设置为 1,并默认禁用 --[no]transaction。 另请参阅–replicate,它会更改此选项的行为。
--timeout-ok如果 --wait 失败,请继续。如果指定 --wait 并且从站在等待超时之前没有赶上主站的位置,不中止
--[no]transaction使用事务而不是锁表。
开始和提交事务的粒度由 --lock 控制。 默认情况下启用此功能,但由于默认情况下禁用 --lock,因此它不起作用。
默认情况下,大多数启用锁定的选项也会禁用事务,因此如果您想使用事务锁定(通过 LOCK IN SHARE MODE 和 FOR UPDATE,您必须明确指定 --transaction。
如果您没有明确指定 --transaction,pt-table-sync 将根据每个表决定是使用事务还是表锁。 它目前在 InnoDB 表上使用事务,并在所有其他表上使用表锁。
如果指定了 --no-transaction,那么 pt-table-sync 将根本不使用事务(甚至不用于 InnoDB 表)并且锁定由 --lock 控制。
启用后,无论是显式还是隐式,事务隔离级别设置为可重复读取,并且事务以 WITH CONSISTENT SNAPSHOT 启动。
--[no]unique-checks启用唯一键检查 (SET UNIQUE_CHECKS=1)。
--[no]zero-chunk为具有零或零等效值的行添加块。 只有在指定 --chunk-size 时才有效。 零块的目的是捕获可能会使第一个块的大小不平衡的大量零值。 例如,如果许多负数被插入到一个无符号整数列中,导致它们被存储为零,那么这些零值将被零块而不是第一个块及其所有非零值捕获。
--verbose打印同步操作的结果。

ps:一些相同的参数请参考pt工具的使用(5) pt-table-checksum的使用

 类似资料: