有没有办法恢复删除的mysql数据库?


8

我不小心在服务器上删除了MySQL数据库。有什么方法可以恢复删除的数据库?


您的MySQL数据库在什么平台上运行?
杰克说请尝试topanswers.xyz 2012年

是否有可能备份了数据库所在的驱动器,并且服务器管理员可以拯救您?
肯尼斯·费舍尔

市场上有各种各样的工具可以修复损坏的MySQL数据库,但是要获得最佳的测试结果,您始终可以依靠Stellar工具来修复数据库。该工具可以修复MySQL数据库的InnoDB和MyISAM表。您还可以预览已修复的数据库对象,这将帮助您概述要恢复的数据。免费提供该软件的试用版试用版,以完全完整性和原始格式来修复数据库,从而确保没有数据丢失。
米切尔

Answers:


16

如果您行动迅速,则很有可能恢复数据库。对于InnoDB来说,机会更高,对于MyISAM,它不是零,但是很接近。

问题是MySQL执行DROP TABLE或DROP DATABASE时(本质上是相同的),InnoDB不会清除数据。包含数据的页面仍在磁盘上。

根据innodb_file_per_table的设置,恢复过程有所不同。如果innodb_file_per_table为OFF(默认值直到5.5),则删除的表仍保留在ibdata1中。如果innodb_file_per_table为ON(默认值为5.5),则删除的表位于相应的.ibd文件中。当删除表时,MySQL会删除该文件。

要做的第一件事是停止任何可能的写操作,以免表被覆盖。如果innodb_file_per_table为OFF,则足以停止MySQL(kill -9甚至更好,但请确保先杀死safe_mysqld)。如果innodb_file_per_table为ON,则在MySQL存储其数据的umount分区上进行安装。如果datadir在根分区上,我建议关闭服务器或至少拍摄磁盘映像。让我重复一遍,目标是防止MySQL或操作系统覆盖删除的表。

有一个工具可以在底层使用TwinDB数据恢复工具箱来处理InnoDB页面 。我将用它来说明还原恢复。

您需要使用已删除表(ibdata1或磁盘映像)的介质并在其上找到InnoDB页面。该工具包中的stream_parser工具可以执行此操作。

./stream_parser -f /path/to/disk/image

它将扫描文件,找到InnoDB页面并按类型和index_id对它们进行排序。index_id是InnoDB用于引用索引的标识符。表存储在索引PRIMARY中。要查找删除的表是什么index_id,您需要恢复InnoDB字典

InnoDB词典存储在ibdat1文件中。您需要按照与上面相同的方式扫描ibdata1文件:

./stream_parser -f /var/lib/mysql/ibdata1

现在您需要从InnoDB词典表SYS_TABLES和SYS_INDEXES中获取记录(假设您的表是sakila.actor):

./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000001.page -t dictionary/SYS_TABLES.sql | grep sakila/actor
000000000B28  2A000001430D4D  SYS_TABLES  "sakila/actor"  158  4  1 0   0   ""  0

158是table_id,记住它。

./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page -t dictionary/SYS_INDEXES.sql | grep 158
000000000B28    2A000001430BCA  SYS_INDEXES     158     376     "PRIMARY"       1       3       0       4294967295
000000000B28    2A000001430C3C  SYS_INDEXES     158     377     "idx\_actor\_last\_name"        1       0       0       4294967295

因此,您删除的表(sakila.actor)的index_id为376。

现在,您可以从InnoDB index_id 376中获取已删除表的记录。您需要具有已删除表的表结构,以及创建表所使用的CREATE TABLE语句。在哪里可以买到?从旧的备份,或从其他地方。也可以从InnoDB字典中恢复结构,但是我不会在此答案中涉及。让我们假设您拥有它。

./c_parser -6f pages-ibdata1/FIL_PAGE_INDEX/0000000000000376.page -t actor.sql > dump.tsv 2> load_cmd.sql

c_parser将记录以制表符分隔的转储形式输出到stdout。可以使用LOAD DATA命令加载转储。c_parser将其打印到stderr。

在帖子中查看更多详细信息:


如果在删除表之后创建新表并插入新记录,它是否仍可恢复?
Oki Erie Rinaldi

在这种情况下,您会丢失index_id,因为CREATE会覆盖原始值。您需要以某种方式找到它。通常我grep已知字符串。随后的INSERT可能会或可能不会覆盖数据。如果不是,则可以恢复。您必须尝试,无法预先告知
akuzminsky '16

这个链接给出了404!
从此再也没有

@akuzminsky我一直做到“ dictionary / SYS_INDEXES.sql | grep 158”部分。它为我的表提供了一些index_id,但是它说没有带有index_id的页面文件。例如:0000000000000376.page(当我运行此c_parser -6f时)
Sampath Sri Anuradha

@SampathSriAnuradha当财富不在您身边时,它一定很难过。对不起。
akuzminsky

11

没有简单的方法可以解决这个问题。通过phpmyadmin或命令行删除数据库都没有关系。没了

人为错误是拥有良好备份方案的原因之一。

我不是虔诚的,但我会祈祷,希望这没什么重要的。


这非常重要,交易量会减少
拖延

8
在这种情况下,我最好建议您卸载数据目录所在的文件系统。如果需要,请关闭服务器。打电话给数据恢复服务,准备好掏出数千甚至数十万,而不必花很多钱在无担保的情况下花钱:-\
atxdba 2012年

3
如果将来遇到类似情况的任何人都读过这篇文章,那么我认为还值得一提的是,如果您要雇用一家数据恢复公司,则必须卸载文件系统或尽快提供只读文件,这一点很重要。在文件系统上继续写入的时间越长,包含已删除文件的群集被覆盖的可能性就越大。
詹姆斯L

2

取决于您的设置。如果正确设置系统,则可以恢复。如果您有备份,可以将其还原。然后将二进制日志应用到删除表之前的那一点。

http://dev.mysql.com/doc/refman/5.5/en/mysqlbinlog.html

我建议您在另一台服务器上执行此操作,一旦恢复了表,就可以使用mysqldump提取它并导入回到生产服务器。这不是快速恢复,但是您可以恢复数据。

如果您不知道自己在做什么,我建议与其中一家mysql咨询公司(pythian,percona,palamino可能是最好的)签订支持合同,并请他们帮助您。

祝你好运

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.