来自:http://dinglin.iteye.com/blog/1791922

有同学问到 checksum table在逻辑备份时候前后是否可以用于验证数据一致性。扩展一下发现有一些有趣的问题,比如数据插入顺序不同、表引擎不同、操作系统位数不同等。

插入顺序不同是否有影响

我们知道全表扫描是可以有很多种顺序的,尤其当表里面出现过delete动作以后,逻辑导出再导入另外一个表后,两个表的全表扫描结果可能不同。

Checksum table计算返回值的逻辑大致如下:

  1. ha_checksum crc= 0;
  2. foreach(row in table)
  3. {
  4. row_crc= get_crc(row);
  5. crc+= row_crc;
  6. }
  7. return crc;

可以看到只要总行数已经行内容相同,与读取行的顺序无关

从这个逻辑还能得到一下几个结论:

1) 与使用的引擎无关,也就是说即使主备不用同一个引擎,checksum也可用于检查。虽然InnoDB有隐藏行,但这里无视。

2) 与是否有索引无关。row_crc只用行本身的数据来计算,并不包括索引数据。

也就是说如果能够保证两个表里面的数据一样,表结构(列内容和顺序一样),操作系统一样,MySQL版本一致,是能够保证checksum的结果的。

下面我们讨论集中“不一样”

字段顺序不同是否有影响

在个row计算row_crc时,是每个字段依次计算的。但计算过程中会将上一个字段的结果作为计算下一个值的输入。

switch (f->type()) {

case MYSQL_TYPE_BLOB:

case MYSQL_TYPE_VARCHAR:

case MYSQL_TYPE_GEOMETRY:

case MYSQL_TYPE_BIT:

{

String tmp;

f->val_str(&tmp);

row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(),

tmp.length());

break;

}

default:

row_crc= my_checksum(row_crc, f->ptr, f->pack_length());

break;

}

因此字段顺序会影响结果。

字段长度不同是否有影响

即使看到相同的内容,也有可能得到不同的checksum。
从上面计算每个field的crc上看,若为变长字段(varchar等),由于用于计算的是实际长度,因此不会影响。比如将表的varchar(20)字段改成varchar(25),不会改变checksum的值。

但若将char(20)改成char(25),或者int改成bigint,则会改变checksum。


操作系统位数不同

因为返回值是unsigned long,我们就担心32位和64位机器的溢出问题。所幸在计算过程中的ha_myisam直接定义为uint32,只是在返回的时候才转成unsigned long,因此无影响。


字符集不同

这个问题其实一直比较含糊。实际上与输入字符集有关。但有一个结论是肯定的:若表里面字段的unhex()值相同,得到的checksum即相同。

有同学问到 checksum table在逻辑备份时候前后是否可以用于验证数据一致性。扩展一下发现有一些有趣的问题,比如数据插入顺序不同、表引擎不同、操作系统位数不同等。

插入顺序不同是否有影响

我们知道全表扫描是可以有很多种顺序的,尤其当表里面出现过delete动作以后,逻辑导出再导入另外一个表后,两个表的全表扫描结果可能不同。

Checksum table计算返回值的逻辑大致如下:

  1. ha_checksum crc= 0;
  2. foreach(row in table)
  3. {
  4. row_crc= get_crc(row);
  5. crc+= row_crc;
  6. }
  7. return crc;

可以看到只要总行数已经行内容相同,与读取行的顺序无关

从这个逻辑还能得到一下几个结论:

1)       与使用的引擎无关,也就是说即使主备不用同一个引擎,checksum也可用于检查。虽然InnoDB有隐藏行,但这里无视。

2)       与是否有索引无关。row_crc只用行本身的数据来计算,并不包括索引数据。

也就是说如果能够保证两个表里面的数据一样,表结构(列内容和顺序一样),操作系统一样,MySQL版本一致,是能够保证checksum的结果的。

下面我们讨论集中“不一样”

字段顺序不同是否有影响

在个row计算row_crc时,是每个字段依次计算的。但计算过程中会将上一个字段的结果作为计算下一个值的输入。

switch (f->type()) {

case MYSQL_TYPE_BLOB:

case MYSQL_TYPE_VARCHAR:

case MYSQL_TYPE_GEOMETRY:

case MYSQL_TYPE_BIT:

{

String tmp;

f->val_str(&tmp);

row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(),

tmp.length());

break;

}

default:

row_crc= my_checksum(row_crc, f->ptr, f->pack_length());

break;

}

因此字段顺序会影响结果。

字段长度不同是否有影响

即使看到相同的内容,也有可能得到不同的checksum。

从上面计算每个field的crc上看,若为变长字段(varchar等),由于用于计算的是实际长度,因此不会影响。比如将表的varchar(20)字段改成varchar(25),不会改变checksum的值。

但若将char(20)改成char(25),或者int改成bigint,则会改变checksum。

操作系统位数不同

因为返回值是unsigned long,我们就担心32位和64位机器的溢出问题。所幸在计算过程中的ha_myisam直接定义为uint32,只是在返回的时候才转成unsigned long,因此无影响。

字符集不同

这个问题其实一直比较含糊。实际上与输入字符集有关。但有一个结论是肯定的:若表里面字段的unhex()值相同,得到的checksum即相同。

 

checksum table 【转】相关推荐

  1. mysql checksum_mysql8 参考手册--CHECKSUM TABLE语句

    CHECKSUM TABLE tbl_name [, tbl_name] ... [QUICK | EXTENDED] CHECKSUM TABLE报告 表内容的校验和.您可以使用此语句来验证备份,回 ...

  2. mysql优化Analyze Table

    MySQL 的Optimizer(优化元件)在优化SQL语句时,首先需要收集一些相关信息,其中就包括表的cardinality(可以翻译为"散列程度"),它表示某个索引对应的列包含 ...

  3. MySQL 创建表 CREATE TABLE 语法

    MySQL中create table语句的基本语法是: . CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition, ...

  4. mysql checksum用法_MySQL checksum理解_mysql

    mysql checksum了解 在主从复制中Checksum常常需要对某些重要的表进行一致性检查. Checksum Table在逻辑备份时候前后是否可以用于验证数据一致性.扩展一下发现有一些有趣的 ...

  5. MySQL主从的一致性校验及修复

    主从的一致性校验 场景: 有人会问道:如何验证主从的一致性 又或者问:一个库里有几十张表 主从结构数据是否一致? 简单来讲可以在低峰期主从上分别使用select count(*)来看一下,这种方式是最 ...

  6. MySQL · 引擎分析 · InnoDB行锁分析

    前言 理解InnoDB行锁,分析一条SQL语句会加什么样的行锁,会锁住哪些数据范围对业务SQL设计和分析线上死锁问题都会有很大帮助.对于InnoDB的行锁,已经有多篇月报进行了介绍,这里笔者借鉴前面月 ...

  7. 对比MySQL表数据内容方式汇总

    一. mysql自带的checksum命令: 可在不同服务器通过checksum值对比两张表是否一致, 加上EXTENDED参数表示逐行扫描, 结果更为可靠; 执行过程会给表加上System lock ...

  8. 我的MYSQL学习心得(十六) 优化

    原文:我的MYSQL学习心得(十六) 优化 我的MYSQL学习心得(十六) 优化 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看 ...

  9. mysql 主从同步检查_MySQL主从复制一致性检测

    在MySQL主从复制过程中,常常需要对某些重要的表进行一致性检查. 由于主从数据在同步时存在一定的延迟,因此直接读取服务器数据的方式无法严格保证信息的一致性.在数据在同步完全结束之前,一直处于不断变化 ...

最新文章

  1. KVM、QEMU和KQemu的区别:
  2. 如果再写 for 循环,我就锤自己!
  3. 移动端Web开发如何处理横竖屏
  4. java多个类调用_JAVA问题总结之15-多个类之间的调用
  5. linux下c语言读取roed文件,如何在Linux系统上安装Android4.4.docx
  6. bigdecimal 设置_BigDecimal 使用方法详解
  7. 13001.udp广播接收程序(python)
  8. QT将窗体变为顶层窗体
  9. 解决Conda install tensorflow弹窗Python.exe已经停止工作的问题
  10. 算法中的最优化方法_学习目录
  11. Vue开发者工具安装祥析
  12. 今晚7:00 | PhD Debate 自监督学习在推荐系统中的应用
  13. PHP实现的7组经纬度与距离的计算函数
  14. 学计算机装机,DIY新手电脑装机教程:自己组装电脑全过程详细图解教学
  15. 为多孔介质的当量直径_CFX多孔介质模型介绍
  16. STM32+DAC8830驱动程序
  17. 怎么在GIF动图中添加文字?一个方法教你快速完成GIF加字
  18. 这里有五种身份证提取出生年月的格式
  19. 总结如何提升网站流量之方法
  20. 安全资讯|SurfingAttack –通过超声波入侵手机

热门文章

  1. POI学习笔记 自定义颜色
  2. 学习使用 Manifest
  3. 在ArcGIS调坐标系引发的一系列问题
  4. 清空Form表单所有内容
  5. CSS3知识点整理(三)----变形与动画
  6. python数据类型基础与解压缩
  7. [转] 图解Seq2Seq模型、RNN结构、Encoder-Decoder模型 到 Attention
  8. eclipse launching workspace太慢的解决方法
  9. 给vmstat加上时间戳
  10. JavaScript——创建对象