来自: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。


操作系统位数不同

位和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。

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

字符集不同

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

 

checksum table 【转】的更多相关文章

  1. mysql 优化analyze table

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

  2. 13.1.17 CREATE TABLE Syntax

    13.1.17 CREATE TABLE Syntax 13.1.17.1 CREATE TABLE ... LIKE Syntax 13.1.17.2 CREATE TABLE ... SELECT ...

  3. MySQL create table 语法

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

  4. MySQL ANALYZE TABLE

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

  5. DROP TABLE 恢复【一】

    当DROP TABLE指令敲下的时候,你很爽,你有考虑过后果么?如果该表真的没用,你DROP到无所谓,如果还有用的,这时你肯定吓惨了吧,如果你有备份,那么恭喜你,逃过一劫,如果没有备份呢?这时就该绝望 ...

  6. pt-table-checksum

    pt-table-checksum是percona公司提供的一个用于在线比对主从数据一致性的工具. 实现原理 将一张大表分成多个chunk,每次针对一个chunk进行校验,同时将校验的结果通过REPL ...

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

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

  8. 如何将MySQL help contents的内容有层次的输出

    经常会遇到这种情况,在一个不能上网的环境通过MySQL客户端登录数据库,想执行一个操作,却忘了操作的具体语法,各种不方便. 其实,MySQL数据库内置了帮助文档,通过help contents即可查看 ...

  9. 生产环境使用 pt-table-checksum 检查MySQL数据一致性

    公司数据中心从托管机房迁移到阿里云,需要对mysql迁移(Replication)后的数据一致性进行校验,但又不能对生产环境使用造成影响,pt-table-checksum 成为了绝佳也是唯一的检查工 ...

随机推荐

  1. linq/EF/lambda 比较字符串日期时间大小

    在使用EF时,想要比较字符串类型的日期时,参考以下: SQL语句: 1 2 3 4 1)select * from TableName where StartTime > '2015-04-08 ...

  2. 解决前面有一篇文章中'flashplayer.so为什么要设置777权限的'问题 的 思考了

    列出某个目录下的所有内容? ls -A, -A等同于-a, 即是-all, 只是-A 不显示.和.. ll ls 某个目录, 如果它下面没有任何东西, 那么 就没有输出! 同时, ll某个目录, 不会 ...

  3. 关于linux vi命令替换的使用说明

    转自:http://os.51cto.com/art/200907/140987.htm vi/vim 中可以使用 :s 命令来替换字符串.以前只会使用一种格式来全文替换,今天发现该命令有很多种写法( ...

  4. 时间处理工具类DateUtils

    public class DateUtils {         public static final String                            SHORT_DATE    ...

  5. Inside the c++ object module 阅读摘要

    这本书是 Stanley B. Lippman于1996年所写,而最早的c++标准是 ISO/IEC 14882:1998[18],即C++98. Chapter 1: Object Lessons ...

  6. JVM执行引擎总结(读《深入理解JVM》) 早期编译优化 DCE for java

    execution engine: 运行时栈current stack frame主要保存了 local variable table, operand stack, dynamic linking, ...

  7. 【PHP面向对象(OOP)编程入门教程】5.如何实例化对象?

    我们上面说过面向对象程序的单位就是对象,但对象又是通过类的实例化出来的,既然我们类会声明了,下一步就是实例化对象了. 当定义好类后,我们使用new关键字来生成一个对象. $对象名称 = new 类名称 ...

  8. centos systemctl指令

    # systemctl #输出已激活单元 # systemctl list-units #输出已激活单元 # systemctl --failed #输出运行失败的单元 # systemctl lis ...

  9. HDU 1532 最大流模板题

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1532 最近在学网络流,学的还不好,先不写理解了,先放模板... 我觉得写得不错的博客:http://blo ...

  10. jQuery学习笔记 - 基础知识扫盲入门篇

    jQuery学习笔记 - 基础知识扫盲入门篇 2013-06-16 18:42 by 全新时代, 11 阅读, 0 评论, 收藏, 编辑 1.为什么要使用jQuery? 提供了强大的功能函数解决浏览器 ...