{{ item.name }}
{{ item.name }}

{{ it.name }}

{{ it.text }}

{{ it.name }}

{{ innerIt.name }}

{{ innerIt.text }}

{{news.time}}
{{news.title}}
两个单机 MySQL 该如何校验数据一致性
2022-03-23发布 3,153浏览

一、测试dsn

利用线上的配置文件搭建一套主从环境。

搭建步骤略

  • 本例使用 mysql 5.7.26 进行测试

  • 本例使用 percona-toolkit-3.2.1 进行测试1、校验主从数据一致性

  • 这个用例将通过 dsn 方式连接从库。

Checking if all tables can be checksummed ...

Starting checksum ...

TS ERRORS DIFFS ROWS DIFF_ROWS CHUNKS SKIPPED TIME TABLE

01-13T17:48:20 0 0 0 0 1 0 0.377 dbatest1.dbatest

可以看到测试通过,能正常做校验。

2、校验非主从数据一致性

这个用例将通过 dsn 方式连接从库,但是会将从库的复制链路 stop 掉,并清空复制信息。

mysql> stop slave;

Query OK, 0 rows affected (0.01 sec)

mysql> reset slave all;

Query OK, 0 rows affected (0.01 sec)

mysql>

二、开发工具遇到的问题

1、解决复杂的联合主键问题

(1)查询索引失效,或者查询报错问题

熟悉 pt-table-checksum 的朋友应该都知道,该工具是基于主键(非空唯一键)进行扫描数据行,其实这个逻辑针对整型单列主键实现起来很简单,但是如果是联合主键且是字符型,好像就没那么简单了,有兴趣的可以思考一下。下面我先说一下大致的逻辑:

第一步:判断 _min_rowid 是否为空,为空就取该表的第一行,并记作 _min_rowid 。

if [ -z "${_min_rowid}" ]

then #拿出当前表的最小行id, 每次拿数据的起始行

_min_rowid="$(${mysql_comm} -NBe "select min(pk) from table")"

fi

第二步:根据 _min_rowid 作为条件进行扫描该表,取下一个数据块的数据,记录数据块的最后一行数据的主键值,记录 checksum 的值,并记下 _min_rowid 。select * from table where pk > ${_min_rowid} limit checksize #计算这个块的checksum值

_min_rowid="$(${mysql_comm} -NBe "select max(pk) from (select pk from table where pk > ${_min_rowid} order by pk limit checksize)a")" #记录下一个最小行pk值

第三步:判断 _min_rowid 是否为空,非空重复第二步,为空退出检查。if [ -z "${_min_rowid}" ]

then

break

else

continue

fi

通过上述三个步骤可以看到,如果是单列整型的主键,实现起来很简单,但是问题来了,业务的表的主键五花八门,有的是联合主键,有的是字符型的联合主键,还有整型+字符型的联合主键,那么上述的实现方式显然是有问题的。所以实现起来需要多考虑几个问题:

需要考虑主键是否是联合主键。

需要考虑主键字段的数据类型是否是整型或字符型。

获取主键字段列表,放在数组里

根据主键字段名获取字段的数据类型,放在关联数组里

根据字段的数据类型,如果是字符型就需要做特殊处理(2)如何界定每个数据块的左区间的边界

假如有这么一个联合主键字段 primary key(a,b,c) 都是整型,该如何编写遍历 sql 呢?起初我的想法很简单,具体如下:_min_rowid=(xxx,yyy,zzz)

select * from where 1 = 1 and a >= xxx and b >= yyy and c > zzz order by a,b,c limit checksize

乍一看好像逻辑没问题,但是实际跑脚本的时候发现这个逻辑不能完全扫完全表,后来经过多次测试校验,得出下面的逻辑 sql

_min_rowid=(xxx,yyy,zzz)

select * from where 1 = 1 and ((a > xxx) or (a = xxx and b > yyy) or (a = xxx and b = yyy and c > zzz)) order by a,b,c limit checksize

至此在编写校验脚本过程遇到的两个问题就算告一段落了,剩下的就是各种逻辑处理了,不过多赘述,有兴趣的可以自行阅读脚本文件。

三、数据校验工具做了哪些改动

1、取消 for update

2、支持表结构校验

3、支持基于表的并行校验

4、支持网络监控

5、支持定时任务功能

6、支持任意两个节点的校验

7、添加超时机制及自杀机制

四、数据校验工具使用介绍

1、校验逻辑

基于主键以一个块遍历数据表,比对 checksum 的值,块的大小可通过参数指定。

(1)获取该表的第一个数据块的查询 SQL 。

(2)将两个目标节点的数据块的 checksum 的值,记录到临时文件,file1 file2。

(3)比对 file1 file2 是否一致。不一致 : 重复(2)的操作,至多连续 20 次,还不一致会将该 SQL 记录到 table 目录一致 : 跳到

(4)file1 为空 : 表示该表遍历完成,直接跳到

(5)(4)获取该表的下一个数据块的查询 SQL 。(5)检查通过就跳到(7),检查不通过调到(6)。

(6)读取 table 目录校验不通过的 SQL 进行再次校验。本次校验通过也视为数据一致如果校验不通过,会将不一致的部分记录到diff目录

(7)该表校验任务结束。

2、功能介绍

检查随意两个几点的数据一致性支持表结构的校验支持并发检查,基于表的并发支持指定时间,可以规避业务高峰期支持网络监控,如果网络超过阈值可以暂停校验不支持无主键(非空唯一键)的表不支持联合主键达到四个字段及以上的表


上一篇
MySQL 字符集再探
400-820-6580 13916131869
marketing@actionsky.com
上海市闵行区万源路2138号泓茂中心2号楼
产品详情
关系型数据库
AI数据库
数据库智能管理平台
数据库生态产品
行业案例
金融行业
新零售行业
制造业
通信行业
更多
公司动态
最新新闻
国产化信息
技术分享
关于我们
公司简介
公司分布
国家专利
资质认证
扫码关注公众号
© Copyright 2017, All rights reserved by: 上海爱可生信息技术股份有限公司 沪ICP备12003970号-1 | 法律声明 | 网站地图
沪公网安备 31010402003331号