1. 程式人生 > >mysql 刪除資料庫恢復

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。