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. javascript中的作用域和变量提升

    js的运行主要分两个阶段:js的预解析和运行,预解析阶段所有的变量声明和函数定义都会提前,但是变量的赋值不会提前.

  2. Java的策略和保护域

    参考文章: (1)java之jvm学习笔记十(策略和保护域) https://blog.csdn.net/yfqnihao/article/details/8271415

  3. 【Activiti学习之五】BPMN事件

    环境 JDK 1.8 MySQL 5.6 Tomcat 7 Eclipse-Luna activiti 6.0 一.事件定义1.定时器事件(1)timeDate:指定时间触发<timerEven ...

  4. 深入理解JVM-对象已死吗

    在堆中存放着Java世界中几乎所有的对象的实例,垃圾收集器在对堆进行垃圾回收前,第一件事情就是要确定这些对象中还有那些是"存活"着,那些已经死去(即不能再被任何途径使用的对象). ...

  5. MySQL 索引小结

    1.!=.not in 在primary key上使用 !=.not in,explain 的 type 是 range,非primary key是全表扫描(即非主键字段即使有索引也无法应用) 2.a ...

  6. 发现一个企业微信第三方应用开发的疑似BUG

    1.企业微信两个账号A(超级管理员),账号B(分级管理员),账号B具有创建应用与小程序权限.2.账号B添加一个第三方应用后(创建后能看到第三方应用),使用下图接口登录时回调的agent一直为空,3.超 ...

  7. 在RedisTemplate中使用scan代替keys指令

    keys * 这个命令千万别在生产环境乱用.特别是数据庞大的情况下.因为Keys会引发Redis锁,并且增加Redis的CPU占用.很多公司的运维都是禁止了这个命令的 当需要扫描key,匹配出自己需要 ...

  8. Python 监控脚本

    Python 监控脚本 整体通过psutil模块动态获取资源信息.下为示例图: #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time: 2019- ...

  9. 【Linux】CentOS7 打开关闭防火墙及端口

    一.centos7版本对防火墙进行加强,不再使用原来的iptables,启用firewalld1.firewalld的基本使用启动: systemctl start firewalld查状态:syst ...

  10. JSON数据格式:以及XML文件格式,YML文件格式,properties文件格式

    JSON数据格式:以及XML文件格式,YML文件格式,properties文件格式   数据格式: json数据格式:属于轻量级数据格式,是javascript的一种描述数据的格式.具有易于解析,语法 ...