如何识别 InnoDB 表损坏?

ran*_*omx 25 mysql innodb percona-server

我有一些已分区的表,并且在复制的从属设备上有多个索引。将快照(已验证安全)复制到新从属并将 mysqld 从 5.1.42 升级到 5.5.15 并重新启动复制后,我收到 InnoDB 崩溃并显示错误消息“无效指针...”

这些错误发生在具有不同硬件和操作系统的 2 个服务器上。运行后:

ALTER TABLE .... COALESCE PARTION n;

那张桌子的问题就消失了。

不过,我的问题范围更大,那就是“您如何识别 InnoDB 表损坏?” 或改写为“您如何评估 InnoDB 表的健康状况?” 是“检查表”可用于识别问题预碰撞唯一的工具?

不确定它是否重要,但运行时发生崩溃:版本:'5.5.15-55-log' 套接字:'/opt/mysql.sock' 端口:3306 Percona Server (GPL),版本 rel21.0,修订版 158

Der*_*ney 21

Morgan在他的评论中给出了一个提示,即 InnoDB 通过对它读取的页面进行校验和来不断检查损坏的页面。如果 InnoDB 发现校验和不匹配,它将崩溃停止服务器。

如果你想加快这个过程(而不是等待 InnoDB 读取损坏的页面),你可以使用innochecksum

因为校验和不匹配会导致 InnoDB 故意关闭正在运行的服务器,所以最好使用这个工具而不是等待生产使用中的服务器遇到损坏的页面。

一个有趣的警告:

innochecksum 不能用于服务器已经打开的表空间文件。对于此类文件,您应该使用 CHECK TABLE 来检查表空间中的表。

所以是的,对于在线表CHECK TABLE可能是该工具(或者如果您想一次执行多个数据库,则在另一个答案中 指出mysqlcheck。)

如果你可以关闭你的数据库,你可以强制使用校验和 innochecksum

轶事: 在 29GB 的 innodb 表空间(使用innodb_file_per_table=1),此脚本花费了大约 2 分钟

#!/bin/bash
for i in $(ls /var/lib/mysql/*/*.ibd)
do
  innochecksum -v $i
done
Run Code Online (Sandbox Code Playgroud)

不过,作为奖励,由于您正在运行 Percona,他们为快速 innodb checksum实现了一种新方法。我从未使用过它,但它可能会加快进程。

  • Percona 服务器还有一些其他不错的功能。见 innodb_corrupt_table_action http://www.percona.com/doc/percona-server/5.5/reliability/innodb_corrupt_table_action.html (!!) (2认同)

mar*_*cio 7

警告:在尝试任何这些说明之前,强烈建议验证您的数据库是否有健康的备份,以防万一。(感谢@Nick 的警告)

尝试使用该mysqlcheck命令。在终端上:

mysqlcheck -u username -p --databases database1 database2
Run Code Online (Sandbox Code Playgroud)

此命令将输出所有表的列表和状态,告诉您是否存在某种损坏:

table1  OK
table2  OK
table3  OK
tableN  OK
Run Code Online (Sandbox Code Playgroud)

有了它,您就已经知道必须修理哪些表。以防万一您想立即修复所有内容:

table1  OK
table2  OK
table3  OK
tableN  OK
Run Code Online (Sandbox Code Playgroud)

更多关于mysqlcheckhttp : //dev.mysql.com/doc/refman/5.0/en/mysqlcheck.html

注意:您用标记了您的问题。我不知道那是什么,所以我用谷歌搜索。它似乎是 MySQL 的一个分支,但我没有理由相信这些命令不兼容(手指交叉)。


有人向我指出了本指南,其中包含针对 InnoDB 数据库恢复的更具体说明,适用于整个数据库无法启动的更危急情况:http : //www.softwareprojects.com/resources/programming/t-how-to-fix-mysql -database-myisam-innodb-1634.html

  • @randymelder - 你说 mysqlcheck 是`CHECK TABLE` 的同义词是错误的。您链接到的文档指出:“`mysqlcheck` 以一种方便用户的方式使用 SQL 语句 `CHECK TABLE`、`REPAIR TABLE`、`ANALYZE TABLE` 和 `OPTIMIZE TABLE`。它确定要用于哪些语句要执行的操作,然后将语句发送到服务器执行。” 那不是同义词;这是一组语句的用户界面。 (3认同)

Rol*_*DBA 7

根据MySQL 5.0 认证学习指南,第 443,444 页第 30.4 节

您可以使用 CHECK TABLE 命令或使用客户端程序为您发出语句来检查 InnoDB 表。但是,如果 InnoDB 表有问题,则无法使用 REPAIR TABLE 修复它,因为该语句仅适用于 MyISAM。

如果表检查表明 InnoDB 表有问题,您应该能够通过使用 mysqldump 转储它、删除它并从该转储重新创建它来将该表恢复到一致状态。

如果 MySQL 服务器或其运行的主机发生崩溃,某些 InnoDB 表可能需要修复。通常,只需重新启动服务器就足够了,因为 InnoDB 存储引擎执行自动恢复作为其启动序列的一部分。在极少数情况下,由于 InnoDB 自动恢复失败,服务器可能无法启动。如果发生这种情况,请使用以下过程:

  • 重新启动服务器,将 --innodb_force_recovery 选项设置为 1 到 6 范围内的值。这些值表示在避免崩溃时的谨慎级别增加,以及对恢复表中可能不一致的容忍级别增加。一个好的开始值是 4。

  • 当您将 --innodb_force_recovery 设置为非零值启动服务器时,InnoDB 将表空间视为只读。因此,您应该使用 mysqldump 转储 InnoDB 表,然后在该选项生效时删除它们。然后在没有 --innodb_force_recovery 选项的情况下重新启动服务器。当服务器启动时,从转储文件中恢复 InnoDB 表。

  • 如果前面的步骤失败,则需要从以前的备份中恢复 InnoDB 表。

请阅读有关InnoDB 强制恢复的MySQL 文档  

  • FWIW,认证指南有一个非常政治正确的答案:) 如果您在 InnoDB 表上检查 TABLE 并且它实际上已损坏,它将永远不会以“损坏”的形式返回,它将使服务器崩溃。该语句在 InnoDB 中几乎已过时,因为每次读取 InnoDB 页面时,它都会检查损坏(通过页面校验和)。 (3认同)