pt-table-sync同步表数据,解决主从不一致的利器,使用之前注意做好备份,当使用–replicate或–sync-to-master方法同步作为复制从属的服务器时,它总是 在复制主服务器上进行更改,而不是直接在复制从属服务器上进行
ps: 以下是三种使用方式不是执行顺序,可以print重定向后生成并执行sql文件,也可以通过excucte直接执行
# 填写主库链接,用户名,密码
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
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
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 | 锁定源表和目标表,同步,然后交换名称 |
打印将解决差异的查询。 | |
--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的使用