暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

数据不一致怎么办?

原创 徐佩怡 2021-01-31
2706

pt-table-checksum

pt-table-checksum是一个基于MySQL数据库主从架构在线数据一致性校验工具。其工作原理在主库上运行, 通过对同步的表在主从段执行checksum, 从而判断数据是否一致。在校验完毕时,该工具将列出与主库存在差异的对象结果。

注意

1、根据测试,需要一个即能登录主库,也能登录从库的账号;
2、只能指定一个host,必须为主库的IP;
3、在检查时会向表加S锁;
4、如果master和slave的binlog日志不是STATEMENT格式,要用–no-check-binlog-format选项
5、运行之前需要从库的同步IO和SQL进程是YES状态。
6、表要有主键索引或唯一键索引
7、如果binlog_format 为MIXED格式,会破坏同步,需要使用–no-check-binlog-format选项来关闭检查
8 、必须存在数据库 或 表,否则会破坏复制
9、检查的时候必须指定库表

尽量业务低峰进行

设置了SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ 直到对比完成,才结束这个session.
意味着如果这个session不结束,这个事务对应的undo一直不会被purge,会导致undo不断变大,即ibdata会一直变大。
故而,尽量在低峰期执行

通过RR隔离级别来保证select CRC的值一致的,很容易被DDL所破坏。
措施:DDL可以人为控制时间窗口和周期

pt-table-sync

pt-table-sync用来高效对mysql数据库间存在不一致表的数据进行同步。该工具会修改工具,所以为了安全,在使用该工具前,对数据库进行备份。当使用—replicate或者—sync-to-master参数来对从库数据进行同步时,如果主从数据不一致,不会直接在从库上修改不一致的数据,而是在主库上进行replace 操作(需要表有唯一键),通过binlog把动作传递给从库,从而达到修改从库数据的目的。导致主库数据不一致的根本原因就是直接在从库上进行增删改操作,所以我们在修复从库数据的时候也尽量避免在从库直接操作。(但是如果主从数据不一致的表没有唯一键,那么不能使用—replicate或者—sync-to-master来修复数据)。当然在主库上做的修改应该是no-op的,并不会修改主库表的当前值,只对从库数据产生影响。

pt-table-sync能够实现单向同步,也可以实现双向同步(目前双向同步还处于测试阶段,后面涉及到双向同步的内容先不做介绍)。pt-table-sync不能同步表结构,索引等对象,只能用来同步记录。

示例

1.pt-table-checksum检测数据不一致

pt-table-checksum会默认创建在percona.checksums表。用于记录对比。
pt-table-checksum或根据show processlist的内容寻找从库,并且在每次检测到的数据同步写在从库的percona.checksums表。也可以选择其他的方式,指定需要检测数据不一致的MySQL实例,比如dnsn表格方式。

需要现创建一张用于记录 验证一致性信息 的表

CREATE DATABASE `percona` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */ ;

CREATE TABLE IF NOT EXISTS `music`.`checksums` (
     db             CHAR(64)     NOT NULL,
     tbl            CHAR(64)     NOT NULL,
     chunk          INT          NOT NULL,
     chunk_time     FLOAT            NULL,
     chunk_index    VARCHAR(200)     NULL,
     lower_boundary TEXT             NULL,
     upper_boundary TEXT             NULL,
     this_crc       CHAR(40)     NOT NULL,
     this_cnt       INT          NOT NULL,
     master_crc     CHAR(40)         NULL,
     master_cnt     INT              NULL,
     ts             TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
     PRIMARY KEY (db, tbl, chunk),
     INDEX ts_db_tbl (ts, db, tbl)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8

##通过hosts方式,指定dsns表进行验证
CREATE TABLE `dsns` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `parent_id` int(11) DEFAULT NULL,
  `dsn` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
#比如有2个slave 需要填写2个3336和 3337,只有一个就 只输入3336即可
insert into dsns(id,parent_id,dsn) values(1,1,'h=192.127.5.35,u=root,p=123456,P=3336');
insert into dsns(id,parent_id,dsn) values(2,2,'h=192.127.5.35,u=root,p=123456,P=3337');

复制

执行比较的语句:
使用hosts方式:

pt-table-checksum --no-check-binlog-format h=XXX.XX.XX.XX,u=root,p=XXXXXX --nocheck-plan --databases=LLL  --no-check-replication-filters  --recursion-method=dsn=D=percona,t=dsns
Checking if all tables can be checksummed ...
Starting checksum ...
            TS ERRORS  DIFFS     ROWS  DIFF_ROWS  CHUNKS SKIPPED    TIME TABLE
01-27T02:00:57      0      3  1139978          3       9       0   3.021 LLL.LLL_ence
01-27T02:01:54      0      0   234491          0       7       0   1.948 LLL.LLL_user
01-27T02:02:27      0      0   217221          0       6       0   1.673 LLL.LLL_plan
复制

输出结果的解读:
TS :完成检查的时间。
ERRORS :检查时候发生错误和警告的数量。
DIFFS :0表示一致,1表示不一致。当指定–no-replicate-check时,会一直为0,当指定–replicate-check-only会显示不同的信息。现在的版本中还可能会遇到不为0或1的结果。
ROWS :表的行数。
CHUNKS :被划分到表中的块的数目。
SKIPPED :由于错误或警告或过大,则跳过块的数目。
TIME :执行的时间。
TABLE :被检查的表名
diff_rows 未找到官方定义,个人猜测可能表示同一张表在主从库中count(*)行数差异,或者数据不一致的行数。

2.pt-table-sync修复数据

pt-table-sync --print --sync-to-master h='127.0.0.1',P=3306,u=root,p='123456' --databases=LLL  > /tmp/repair.sql
复制

/tmp/repair.sql内容:

REPLACE INTO `LLL`.`LLL_ence`(`id`, ....) VALUES (...) /*percona-toolkit src_db:LLL .../;
REPLACE INTO `LLL`.`LLL_ence`(`id`, ....) VALUES (...) /*percona-toolkit src_db:LLL .../;
复制

pt-table-sync工具产生的SQL,都是以主库数据为准的内容。建议在修复时候,把数据脚本在主库执行,主库会将数据同步到从库,完成数据的修正,保证主从数据一致(期间最好没有业务修改数据,避免新的业务数据被覆盖)。
pt-table-sync工具产生的SQL语句存在delete,insert,和replace三种:
delete语句的生成,说明从库存在主库没有的数据。
insert表示从库缺少这部分数据。
replace的生成是由于这张表存在主键且存在唯一索引,此时将insert拆分成delete和replace语句。

如果存在不能通过pt-table-sync修复的情况:

比如,在MHA切换过程中,出现问题,主库切换到从库,写入如一段时间后又发生切换到原来本应该死亡的主库上发生脑裂的情况。
此时 建议:
1.暂停业务
2.通过pt-table-checksum比较数据不一致,找到数据不一致的表
3.mysqldump导出主从库中的 数据不一致的表,恢复到测试机上,取名可以类似LLL_user_127,LLL_user_128以确别不同服务器上的同一张表。
4.通过union语句对表数据进行对比,并通过into outfile将不同的数据抽出。
5.通过load data infile 语句导入已经修复的主从库中,完成数据修复。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论