如何恢复/恢复损坏的 Innodb 数据文件?

Ste*_*e06 5 mysql recovery restore

不久前,运行 MySQL Server 5.5.31 的 Windows 7 系统崩溃并损坏了 InnoDB 数据库。可用的每周备份并未涵盖在此期间创建的所有表,因此我将努力从数据中尽可能多地恢复。崩溃后,我将 MySQL 的整个数据文件夹复制到外部驱动器。我想以此作为我的救援尝试的起点。

在下面,我将描述我的(尚未令人信服的)救援尝试的步骤,并感谢您对如何改进它的任何评论或指导:

  1. 我现在已经在另一台 PC 上全新安装了 MySQL Server 5.5.31
  2. 我在命令提示符下使用“net stop MySQL”停止 MySQL 服务。
  3. 我已经认为我需要调整 my.ini 文件中 innodb 日志文件的大小,因为它偏离了默认值 (19MB) (256 MB)。
  4. 在my.ini中,我还设置了innodb_force_recovery=6
  5. 在全新安装的数据文件夹中,我用从崩溃的机器中恢复的文件覆盖了 ibdata1、iblogfile0、iblogfile1 文件。我还将相关的数据库(UPDATE:和 mysql)文件夹复制到这里(不是标准的mysql、 test 和 performance 文件夹)。
  6. 我用“net start MySQL”启动 MySQL 服务。
  7. 我进入 MySQL Workbench,打开我的服务器实例,转到数据导出,基本上保留默认设置,并将我的数据库的每个表作为单独的转储文件导出。我还设置了要转储的存储过程。否则我不会更改那里的默认设置。
  8. 我开始转储过程;它通过了 195 个表中的 43 个。在这 43 个中,
    • 有些无法恢复,产生错误“ mysqldump: Got error: 1146: Table '...whatever...' 在执行 LOCK TABLES 时不存在”,
    • 但很多都可以。我假设当转储没有产生任何错误时,表的数据没有损坏。
      然后,在 44 日之后,所有其他表转储都失败,因为它报告服务器无法再连接到:
      mysqldump: Got error: 2003: Can't connect to MySQL server on 'localhost' (10061) when try to连接
      操作失败,退出代码为 2

      这些错误然后继续发生在从 44 到 195 的所有剩余表中。
      对于第 44 个表本身,错误如下:“ mysqldump: Error 2013: Lost connection to MySQL server during query when dumping table ...table 44...at row: 57 ”。因此,对于此表,似乎损坏是或开始于第 57 行。

现在我的问题:

  • 鉴于 innodb_force_recovery 设置为 6,为什么连接中断?
  • 如何进行?我计算出连接丢失的第 44 个表是什么,可以尝试从第 45 个表恢复进程。但是没有更好的方法来做到这一点吗?
  • 一旦数据被复制并且服务器重新启动良好,我应该尝试转储每个表还是有什么替代方法?

谢谢。


更新:我以后参考的附加说明
- 当重新创建使用 SHOW CREATE PROCEDURE ... 和 SHOW CREATE FUNCTION ... 备份的存储例程时,它们必须使用导入 DELIMITER // (create procedure code of procedure 1)// (create procedure code of procedure 2)// DELIMITER ;

Mic*_*bot 6

检查 MySQL 错误日志。看起来尝试读取表 44 实际上使服务器崩溃。

“在查询期间失去与 MySQL 服务器的连接”对于 MySQL DBA 来说是(或应该是)令人心碎的时间,因为这通常意味着您的查询刚刚执行的任何操作实际上都使服务器崩溃。

随后的消息似乎证实了这一点:

mysqldump: Got error: 2003: Can't connect to MySQL server on 'localhost' (10061) when
trying to connect
Operation failed with exitcode 2
Run Code Online (Sandbox Code Playgroud)

mysqldump的对Windows 7的快速测试对MySQL服务器未运行的回报正是同样的错误,并退出,并%ERRORLEVEL%设置为2。错误10061的性质可以与发现perror工具

C:\>perror 10061
Win32 error code 10061: No connection could be made because the target machine actively refused it.
Run Code Online (Sandbox Code Playgroud)

...所以,检查 MySQL 错误日志。可能发生的情况是您的损坏严重到足以使innodb_force_recoveryMySQL 服务器崩溃。然后我通常会自行重新启动,但这需要时间,因此可能无法在 mysqldump 在随后的连接尝试中拒绝 IP 连接之前完成。这应该都显示在错误日志中。

我假设当转储没有产生任何错误时,表的数据没有损坏。

不正确的假设。如果转储没有产生任何错误,也可能意味着innodb_force_recovery允许服务器检索某些数据。表的“成功”转储仅意味着它没有严重损坏而innodb_force_recovery无法生存。

1 (SRV_FORCE_IGNORE_CORRUPT)

即使检测到损坏的页面,也让服务器运行。尝试SELECT * FROM tbl_name跳过损坏的索引记录和页面,这有助于转储表。

http://dev.mysql.com/doc/refman/5.5/en/forcing-innodb-recovery.html

同样,您应该在 MySQL 错误日志中看到来自 InnoDB 的喋喋不休。

最后的建议,不要使用工作台。使用mysql命令行客户端来探索服务器模式并mysqldump直接从命令行使用来尝试恢复单个模式或单个数据库。


更新/附加:

你如何恢复存储过程?我收到错误,因为他们访问了损坏的表

这不应该是因为过程访问损坏的表,因为存储过程和函数没有以视图的方式针对它们引用的表进行验证(删除一个视图引用的表,然后SHOW CREATE VIEW不起作用——同样是过程或函数不是这种情况)...... MySQL 不关心存储过程和函数引用的表是否存在(运行时除外)......但是,与存储在单个文件中的视图定义不同,定义的过程和函数存储在模式的proc表中mysql,这是一个 MyISAM 表......所以我希望你会看到引用该表的错误消息CHECK TABLE mysql.proc;REPAIR TABLE mysql.proc;可能会让你再次前进。请注意,您用于恢复的 MySQL 服务器的版本需要是相同的发布系列(例如 5.5),否则表定义mysql.proc将是错误的......这不应该是这里的问题,因为如果我阅读问题正确,崩溃的服务器和恢复服务器都是5.5.31。

如果可以,SELECT * FROM mysql.proc那么如果由于某种原因该SHOW CREATE PROCEDURE语句不起作用,则可以以这种方式检索定义。

对于在转储中产生错误的表,有哪些(部分)救援选项?

这取决于所遇到错误的性质和范围。此处讨论的一种选择涉及重复INSERT ... SELECT ... LIMIT ... OFFSET,从可读页面中提取行块到 MyISAM 表中(因为在打开时无法写入 InnoDB 表innodb_force_recovery)。还有用于 InnoDBPercona 数据恢复工具,尽管我从未有机会使用它。