技术分享 | mysql 表数据校验
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 表数据校验的更多相关文章
- 利用Flume将MySQL表数据准实时抽取到HDFS
转自:http://blog.csdn.net/wzy0623/article/details/73650053 一.为什么要用到Flume 在以前搭建HAWQ数据仓库实验环境时,我使用Sqoop抽取 ...
- 如何实现MySQL表数据随机读取?从mysql表中读取随机数据
文章转自 http://blog.efbase.org/2006/10/16/244/如何实现MySQL表数据随机读取?从mysql表中读取随机数据?以前在群里讨论过这个问题,比较的有意思.mysql ...
- MySQL 表数据多久刷一次盘?
前言 事情是这样的,在某乎的邀请回答中看到了这个问题: - 然后当时我没多想就啪一下写下来这样的答案: 这个其实要通过 MySQL 后台线程来刷的,在 Buffer Pool 中被修改的过的 Page ...
- 技术分享 | MySQL数据误删除的总结
欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 内容提要 用delete语句 使用drop.truncate删除表以及drop删 ...
- 技术分享 | MySQL Group Replication集群对IP地址的限制导致的一些问题与解决办法
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 1. 遇到问题 测试人员小玲准备在docker环境中部署MGR集群进行一些测试,她有三个容器,容器IP分别是: 172.3 ...
- 技术分享 | MySQL中MGR中SECONDARY节点磁盘满,导致mysqld进程被OOM Killed
欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 在MGR测试中,人为制造磁盘满问题后,节点被oom killed 问题描述 在对 ...
- Python将MySQL表数据写入excel
背景:将mysql表查询结果写入excel. 1.使用sqlyog工具将查询结果导出到Excel.xml中,用excel打开发现:因为text字段中有回车换行操作,显示结果行是乱的. 2.用mysql ...
- linux下用命令导出mysql表数据
由于数据库服务器是内网环境,只能通过linux跳板机连接,所以navicat工具暂时用不上. 1.用Xshell工具连接跳板机 2.再通过跳板机连接数据库服务器 >ssh -p port ip ...
- Selenium应用代码(读取mysql表数据登录)
1. 封装链接数据库的类: import java.sql.ResultSet; import java.sql.Connection; import java.sql.DriverManager; ...
随机推荐
- Powershell更新
问题:在vin7电脑启动vagrant up 提示powershell版本过低. 在vin7电脑启动vagrant up 提示powershell版本过低: The version of powers ...
- 获取最新的中国IP的脚本,给ROS可以使用的脚本
wget http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latestecho "/ip firewall address-li ...
- libevent笔记5:水位watermarks
bufferevent中提供了对读写回调的触发条件及最大缓存长度的设置,即低高水位: 低水位:是读写回调函数的最低触发数据长度,当输入/输出缓存区中的数据长度小于低水位时,读/写回调函数不会被触发: ...
- Python 的文件保存路径
1.保存在当前代码同级的目录下: 2.保存在代码文件夹外面一层的新文件夹(data文件夹与代码文件夹同级)里: 3.保存在下一级的子文件夹里
- javascript 忍者秘籍读书笔记(二)
闭包的私有变量 function Ninja() { let feints = 0; this.getFeints = function () { return feints }; this.fein ...
- char[],char *,string之间转换
char []与char *之间转换 char []转char *:直接进行赋值即可 // char[] 转char *char str[] = "lala";char *str1 ...
- Akka-CQRS(11)- akka-http for http-web-service: Marshalling-数据序列化
前面几篇讨论了关于gRPC方式的前后端连接集成方式.gRPC也是一个开放的标准,但讲到普及性就远远不及基于http/1.1协议的web-service了.特别是gRPC的前端编程还是有一定的门槛,所以 ...
- Excel批量添加不同的批注
Sub 批量添加不同批注() Dim rng As Range Dim i As String Range("A1:D1").ClearComments For Each rng ...
- python利用dijkstra算法求解图中最短距离
利用dijkstra算法,来完成图中两个顶点间最短的距离,可以直接复制使用,只需要修改参数即可 def dijkstra_raw(edges, from_node, to_node): "& ...
- - Java中boolean类型占用多少个字节 MD
目录 目录 Java中boolean类型占用多少个字节 1个bit(1位) 1个Byte(1字节,8位) 4个Byte(4字节,32位) 分析 官方文档中的描述 Markdown版本笔记 我的GitH ...