innochecksum工具可以打印InnoDB文件的校验值,该工具读取InnoDB表空间文件,计算每个页面的校验值,将计算的校验值与存储的校验值进行比较,并报告指示损坏页面的不匹配。它最初是为了加速验证断电后表空间文件的完整性而开发的,也可以在文件复制后使用。由于校验值不匹配导致InnoDB故意关闭正在运行的服务器,因此最好使用此工具而不是等待生产服务器遇到损坏的页面。从MySQL 5.7.2开始,innochecksum支持大于2GB的文件。先前,innochecksum只支持最大2GB的文件。
从MySQL 5.7.2开始,innochecksum支持包含压缩页面的表空间。
但需要注意的是,innochecksum不能用于服务器已经打开的表空间文件。对于这样的文件,你应该使用CHECK TABLE检查表空间内的表。试图在服务器已打开的表空间上运行innochecksum将导致“Unable to lock file”错误。也就是说文件不可以打开 !换句话说,可能需要关闭实例才能使用如下功能!!!
如果发现校验值不匹配,通常会从备份中恢复表空间或启动服务器,并尝试使用mysqldump对表空间内的表进行备份。
innochecksum语法:
1 |
$ innochecksum [options] file_name |
常用选项:
1. –version, -V
显示版本信息。
2. –count, -c
打印文件中的页数并退出。用法示例:
1 2 |
$ innochecksum --count /var/lib/mysql/sbtest/sbtest1.ibd Number of pages:15360 |
3. –start-page=num, -s num
指定从某个页面开始校验。用法示例:
1 |
$ innochecksum --start-page=600 /var/lib/mysql/sbtest/sbtest1.ibd |
4. –end-page=num, -e num
指定校验结束于此页面。用法示例:
1 |
$ innochecksum --end-page=600 /var/lib/mysql/sbtest/sbtest1.ibd |
5. –page=num, -p num
只校验某个页面。用法示例:
1 |
$ innochecksum --page=701 /var/lib/mysql/sbtest/sbtest1.ibd |
6. –strict-check, -C
指定一个严格的校验值算法。选项包括innodb,crc32和none。
如果不指定–strict-check选项,innochecksum验证innodb,crc32和none。如果指定了none选项,则只允许none生成的校验值。如果指定了innodb选项,则只允许innodb生成的校验值。如果指定了crc32选项,则只允许crc32生成的校验值。
7. –no-check, -n
重写校验值时忽略校验和验证,该选项只能与innochecksum –write选项一起使用。如果没有指定–write选项,innochecksum将终止。
在这个例子中,innodb校验值被重写以替换无效的校验值:
1 |
$ innochecksum --no-check --write innodb /var/lib/mysql/sbtest/sbtest1.ibd |
8. –allow-mismatches, -a
在innochecksum终止之前允许的校验值不匹配的最大数目,默认设置是0。如果–allow-mismatches=N,N>=0,N允许不匹配和innochecksum终止在N+1。当 –allow-mismatches设置为0时, innochecksum在第一个校验值不匹配时终止。
在这个例子中,–allow-mismatches为1,现有的innodb校验值被重写:
1 |
$ innochecksum --allow-mismatches=1 --write innodb /var/lib/mysql/sbtest/sbtest1.ibd |
随着–allow-mismatches设置为1,如果在600页和1000页文件不匹配,另一个在700页,校验为0-599和601-699页进行更新。由于–allow-mismatches设置为1,所以校验值可以容忍第一个不匹配,并在第二个不匹配时终止,从而使页面600和页面700-999保持不变。
当–allow-mismatches设置为1时,如果在文件的600页和700页与1000页之间存在不匹配,则会更新页0-599和601-699的校验值。因为–allow-mismatches设置为1,校验值可容忍第一个不匹配,并在第二个不匹配时终止,使页600和页700-999保持不变。
9. –write=name, -w num
重写页的校验值。通过innochecksum来修改页校验值是非常危险的操作,建议操作前备份。但若遇到页损毁的问题,可以通过该工具重写页的校验值。重写无效校验值时,–no-check选项必须和–write选项一起使用。该–no-check选项告诉innochecksum忽略验证无效的校验值。如果当前校验值有效,则不必指定选项。
使用该–write选项时必须指定一个算法。该–write选项的可能值是:
innodb:使用原始InnoDB算法从软件中计算校验值。
crc32:使用crc32算法计算的校验值,可能用硬件辅助完成。
none:一个常数。
该选项将整个页面重写到磁盘,如果新的校验值与现有的校验值相同,则新的校验值不会被写入到磁盘,以最小化I/O。当–write选项被使用时,innochecksum获得排他锁。
1 2 3 4 5 |
# 重写有效校验值的页; $ innochecksum -w crc32 /var/lib/mysql/sbtest/sbtest.ibd # 重写带有无效校验值的页; $ innochecksum --no-check -w crc32 /var/lib/mysql/sbtest/sbtest.ibd |
10. –page-type-summary, -S
在表空间中显示每个页面类型的计数。用法示例:
1 |
$ innochecksum --page-type-summary /var/lib/mysql/sbtest/sbtest1.ibd |
示例输出为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
File::/var/lib/mysql/sbtest/sbtest1.ibd ================PAGE TYPE SUMMARY============== #PAGE_COUNT PAGE_TYPE =============================================== 14547 Index page 0 Undo log page 1 Inode page 0 Insert buffer free list page 810 Freshly allocated page 1 Insert buffer bitmap 0 System page 0 Transaction system page 1 File Space Header 0 Extent descriptor page 0 BLOB page 0 Compressed BLOB page 0 Other type of page =============================================== Additional information: Undo page type: 0 insert, 0 update, 0 other Undo page state: 0 active, 0 cached, 0 to_free, 0 to_purge, 0 prepared, 0 other |
11. –page-type-dump, -D
将表空间中的每个页面的页面类型信息转储到stderr或stdout。用法示例:
1 |
$ innochecksum --page-type-dump=/tmp/a.txt /var/lib/mysql/sbtest/sbtest1.ibd |
输出信息大概如下:
1 2 3 4 5 6 7 8 9 10 |
Filename::/var/lib/mysql/sbtest/sbtest1.ibd ============================================================================== PAGE_NO | PAGE_TYPE | EXTRA INFO ============================================================================== #:: 0 | File Space Header | - #:: 1 | Insert Buffer Bitmap | - #:: 2 | Inode page | - #:: 3 | Index page | index id=764, page level=0, No. of records=7, garbage=0, - #:: 4 | Freshly allocated page | - #:: 5 | Freshly allocated page | - |
12. –log, -l
innochecksum工具日志输出,必须提供日志文件名称。日志输出包含每个表空间页面的校验值。对于未压缩的表格,还提供了LSN值。用法示例:
1 |
$ innochecksum --log=/tmp/log.txt /var/lib/mysql/sbtest/sbtest1.ibd |
PS:有些数据库进行升级时,大部分用户选择的都是原地升级,因此虽然数据库版本升级到了5.6,而页的格式却还是之前的老版本。这不会对数据库产生任何影响,因为InnoDB默认的处理方式就是兼容原来的方式,只是在写入新页时才会用新的crc32算法更新页的校验值。因此,若想要完全升级数据库,享受素有的性能提升优化点,或许还需要更新新页的校验值,并将参数innodb_checksum_algorithm设置为strict_crc32。而这可以通过innochecksum来完成。通过innochecksum来修改页校验值是非常危险的操作,建议操作前备份。但若遇到页损毁的问题,可以通过该工具重写页的校验值。
官方地址:https://dev.mysql.com/doc/refman/5.7/en/innochecksum.html