mysql 删除数据库恢复

这几天看到几篇关于数据恢复的文件,没有实际操作过,先留着,关键时候可以保命。

原文:https://dba.stackexchange.com/questions/23251/is-there-a-way-to-recover-a-dropped-mysql-database

链接:

  1. http://dba.stackexchange.com/questions/23251/is-there-a-way-to-recover-a-dropped-mysql-database

  2. https://github.com/chhabhaiya/undrop-for-innodb

  3. https://twindb.com/how-to-recover-innodb-dictionary


如果你的行动很快,那么很有可能会重新获得您的数据库。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或操作系统覆盖丢弃的表。

有一个工具,可以使用InnoDB的低级页面, TwinDB数据恢复工具包我会用它来说明无法恢复。

你需要使用删除的表(ibdata1或磁盘映像)来查找InnoDB页面。从工具包stream_parser工具做到这一点。

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

它将扫描文件,找到InnoDB页面并按类型和index_id排序。index_id是InnoDB用来引用索引的标识符。表格存储在索引PRIMARY中。要找到你的drop table是什么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。


你可能感兴趣的:(文章,数据库)