1. checksum table.

checksum table 会对表一行一行进行计算,直到计算出最终的 checksum 结果。比如对表 n4 进行校验(记录数 157W,大小为 4G)

[ytt]>desc n4;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| r1 | char(36) | YES | | NULL | |
| r2 | varchar(100) | YES | | NULL | |
| r3 | datetime | YES | | NULL | |
| r4 | text | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
5 rows in set (0.00 sec)
[ytt]>select count(*) from n4;
+----------+
| count(*) |
+----------+
| 1572864 |
+----------+
1 row in set (6.89 sec)
[ytt]>checksum table n4;
+--------+-----------+
| Table | Checksum |
+--------+-----------+
| ytt.n4 | 874125175 |
+--------+-----------+
1 row in set (8.24 sec)

我自己笔记本上的测试结果,速度挺快。

不过 checksum 的限制比较多。罗列如下,

A、不能对视图进行校验。

[ytt]>checksum table v_n3;
+----------+----------+
| Table | Checksum |
+----------+----------+
| ytt.v_n3 | NULL |
+----------+----------+
1 row in set, 1 warning (0.00 sec)
[ytt]>show warnings;
+-------+------+------------------------------+
| Level | Code | Message |
+-------+------+------------------------------+
| Error | 1347 | 'ytt.v_n3' is not BASE TABLE |
+-------+------+------------------------------+
1 row in set (0.00 sec)

B、字段顺序不同,校验结果也会不一致。

[ytt]>desc n3;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | NO | | NULL | |
| r1 | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)
[ytt]>desc n5;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| r1 | int(11) | YES | | NULL | |
| id | int(11) | NO | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)
[ytt]>checksum table n3,n5;
+--------+------------+
| Table | Checksum |
+--------+------------+
| ytt.n3 | 1795175396 |
| ytt.n5 | 838415794 |
+--------+------------+
2 rows in set (0.00 sec)

C、CHAR(100) 和 VARCHAR(100) 存储相同的字符,校验结果也会不一致。

[ytt]>desc n6;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | int(11) | NO | | NULL | |
| r1 | int(11) | YES | | NULL | |
| s1 | varchar(100) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
[ytt]>desc n3;
+-------+-----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+---------+-------+
| id | int(11) | NO | | NULL | |
| r1 | int(11) | YES | | NULL | |
| s1 | char(100) | YES | | NULL | |
+-------+-----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
[ytt]>select * from n6;
Empty set (0.00 sec)
[ytt]>insert into n6 select * from n3;
Query OK, 8 rows affected (0.01 sec)
Records: 8 Duplicates: 0 Warnings: 0
[ytt]>checksum table n3,n6;
+--------+------------+
| Table | Checksum |
+--------+------------+
| ytt.n3 | 2202684200 |
| ytt.n6 | 455222236 |
+--------+------------+
2 rows in set (0.00 sec)

D、在执行 checksum 同时,会对表所有行加共享读锁。

E、还有就是 MySQL 版本不同,有可能校验结果不一致。比如手册上说的,MySQL 5.6.5 之后的版本对时间类型的存储格式有变化,导致校验结果不一致。那 checksum 的 限制这么多,我们是不是有其方法来突破所有限制呢?比如说可以模拟 checksum table 的原理来手工计算。

2. 自己计算 checksum 值。

这里用了 MySQL 自身的几个特性:session 变量;通用表达式;窗口函数以及 MySQL 的 concat_ws 函数实现非常简单。比如我们用 sha 函数来计算校验值。

[ytt]>set @crc='';
Query OK, 0 rows affected (0.00 sec)
[ytt]>
[ytt]>with ytt (r,rn) as
-> (
-> select @crc:= sha(concat_ws('#',@crc,id,r1,r2,r3,r4)) as r, row_number() over() as rn
-> from n4
-> )
-> select 'n4' tablename, r checksum from ytt where rn = 1572864 ;
+-----------+------------------------------------------+
| tablename | checksum |
+-----------+------------------------------------------+
| n4 | a9711af93399e0d195a53f4148adea46ab684d30 |
+-----------+------------------------------------------+
1 row in set, 1 warning (16.46 sec)

如果在 MySQL 老版本运行,可以利用 MySQL 的黑洞引擎,改下 SQL 如下:

[ytt]>create table tmp_checksum (checksum varchar(100)) engine blackhole;
Query OK, 0 rows affected (0.08 sec)
[ytt]>
[ytt]>set @crc='';insert into tmp_checksum
Query OK, 0 rows affected (0.00 sec)
-> select @crc:= sha(concat_ws('#',@crc,id,r1,r2,r3,r4)) as r from n4;
Query OK, 1572864 rows affected, 1 warning (20.11 sec)
Records: 1572864 Duplicates: 0 Warnings: 1
[ytt]>select 'n4' tablename,@crc checksum;
+-----------+------------------------------------------+
| tablename | checksum |
+-----------+------------------------------------------+
| n4 | a9711af93399e0d195a53f4148adea46ab684d30 |
+-----------+------------------------------------------+
1 row in set (0.00 sec)

总结

对于表要计算校验数据一致性的需求,首选第二种自己写 SQL 的方法。

技术分享 | mysql 表数据校验的更多相关文章

  1. 利用Flume将MySQL表数据准实时抽取到HDFS

    转自:http://blog.csdn.net/wzy0623/article/details/73650053 一.为什么要用到Flume 在以前搭建HAWQ数据仓库实验环境时,我使用Sqoop抽取 ...

  2. 如何实现MySQL表数据随机读取?从mysql表中读取随机数据

    文章转自 http://blog.efbase.org/2006/10/16/244/如何实现MySQL表数据随机读取?从mysql表中读取随机数据?以前在群里讨论过这个问题,比较的有意思.mysql ...

  3. MySQL 表数据多久刷一次盘?

    前言 事情是这样的,在某乎的邀请回答中看到了这个问题: - 然后当时我没多想就啪一下写下来这样的答案: 这个其实要通过 MySQL 后台线程来刷的,在 Buffer Pool 中被修改的过的 Page ...

  4. 技术分享 | MySQL数据误删除的总结

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 内容提要 用delete语句 使用drop.truncate删除表以及drop删 ...

  5. 技术分享 | MySQL Group Replication集群对IP地址的限制导致的一些问题与解决办法

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 1. 遇到问题 测试人员小玲准备在docker环境中部署MGR集群进行一些测试,她有三个容器,容器IP分别是: 172.3 ...

  6. 技术分享 | MySQL中MGR中SECONDARY节点磁盘满,导致mysqld进程被OOM Killed

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 在MGR测试中,人为制造磁盘满问题后,节点被oom killed 问题描述 在对 ...

  7. Python将MySQL表数据写入excel

    背景:将mysql表查询结果写入excel. 1.使用sqlyog工具将查询结果导出到Excel.xml中,用excel打开发现:因为text字段中有回车换行操作,显示结果行是乱的. 2.用mysql ...

  8. linux下用命令导出mysql表数据

    由于数据库服务器是内网环境,只能通过linux跳板机连接,所以navicat工具暂时用不上. 1.用Xshell工具连接跳板机 2.再通过跳板机连接数据库服务器 >ssh -p port ip ...

  9. Selenium应用代码(读取mysql表数据登录)

    1. 封装链接数据库的类: import java.sql.ResultSet; import java.sql.Connection; import java.sql.DriverManager; ...

随机推荐

  1. nodejs内存溢出 FATAL ERROR: CALL_AND_RETRY_0 Allocation failed – process out of memory

    spa项目整体迁移转为ssr后,改动之后部署一切还好,就是突然有一天访问人数太多,node进程很容易就挂了自动重启. 最后经过压力测试,考虑到是堆内存溢出的问题,就报错误:FATAL ERROR: C ...

  2. 2019qbxtCSP-S2 模拟题1

    T1 \(solution\) 求出第一个开始下降的位置,移动到连续的与它相同的数的最前面的一个数的位置,记录为\(p\) \(p\)以前的位置的数与原数相同,\(p\)位置为原数-1,后面全部为9 ...

  3. python3 ini文件读写

    import configparser config = configparser.ConfigParser() file = 'config.ini' config.read(file) confi ...

  4. SpringMVC之使用ResponseEntity

    1.Post请求 一般情况下,在非必须的情况下,使用Jquery实现post请求,而后台返回一般都需要手动封装ResponseUtil,和使用@ResponseBody注解来实现返回.然而我们书上学到 ...

  5. 仿微信、qq聊天,@好友功能

    文章主要介绍我们平时用的qq,微信输入框里面的@功能 如图,输入@符号 会出现一个ul ul的位置随着@符号的位置变动 下面是代码 希望对大家有用 直接全部复制,在编辑器中打开 即可 <!DOC ...

  6. Hystrix实现ThreadLocal上下文的传递 转

    springcloud微服务中, 服务间传输全局类参数,如session信息等. 一.问题背景 Hystrix有2个隔离策略:THREAD以及SEMAPHORE,当隔离策略为 THREAD 时,是没办 ...

  7. 破解Charles4.2.7版本

    软件下载地址:请点我 密码:sats dmg软件解密密码是:xclient.info 激活方法 1.将 Charles.app 拖至 应用程序 文件夹 2.将 keygen.jar 拖至 桌面 3.打 ...

  8. myeclipse安装android开发环境全过程

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/liang_824/article/det ...

  9. AGC038

    Contest Page 开题开错翻车场.jpg A sol $A > \frac{W}{2}$或者$B > \frac{H}{2}$的时候无解,否则构造方法长下面这样 #include& ...

  10. java异常的嵌套和级联

    一.分开捕获或者嵌套使用 我们先看看下面这段代码: public class Cal { public int div(int a, int b) { int result = a / b; retu ...