1. 程式人生 > 其它 >MySQL資料檔案被惡意刪除後的恢復

MySQL資料檔案被惡意刪除後的恢復

前言

收到很久沒聯絡的一個客戶留言,我預感應該是有什麼事情發生了,問他啥事:跟我說有人rm -rf他們某表的資料檔案了,也沒有備份,嘗試修復了一番,現在資料庫起來了,但是一查那張表就卡住了。

我一聽這個事情挺有意思的,於是就有了接下來的一番操作。

 

覆盤報錯

1.嘗試匯入表空間失敗,日誌提示以下報錯

07:23:01 UTC - mysqld got signal 6 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
Attempting to collect some information that could help diagnose the problem.
As this is a crash and something is definitely wrong, the information
collection process might fail.

key_buffer_size=16777216
read_buffer_size=8388608
max_used_connections=0
max_threads=3000
thread_count=0
connection_count=0
It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 30776532 K bytes of memory
Hope that's ok; if not, decrease some variables in the equation.

Thread pointer: 0x0
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 0 thread_stack 0x40000
/usr/local/mysql/bin/mysqld(my_print_stacktrace+0x35)[0xf4fbe5]
/usr/local/mysql/bin/mysqld(handle_fatal_signal+0x4a4)[0x7d1f54]
/lib64/libpthread.so.0(+0xf630)[0x2b7f2a490630]
/lib64/libc.so.6(gsignal+0x37)[0x2b7f2b943387]
/lib64/libc.so.6(abort+0x148)[0x2b7f2b944a78]
/usr/local/mysql/bin/mysqld(_Z18ut_print_timestampP8_IO_FILE+0x0)[0x7c131e]
/usr/local/mysql/bin/mysqld(_ZN2ib5fatalD1Ev+0xb3)[0x11ae4c3]
/usr/local/mysql/bin/mysqld[0x124f009]
/usr/local/mysql/bin/mysqld[0x124fae8]
/usr/local/mysql/bin/mysqld(_Z6fil_ioRK9IORequestbRK9page_id_tRK11page_size_tmmPvS8_+0x29e)[0x125528e]
/usr/local/mysql/bin/mysqld[0x120c326]

 

表結構是研發提供的,.ibd檔案是在資料目錄當中拿到的,但是確沒有.frm檔案。

測試過程

1.執行rm -rf k1.frm k1.ibd

2.重啟資料庫

3.進入mysql,執行create table 建立了表結構

此時例項中提示報錯,提示k1表已存在,同時資料目錄出現了k1.ibd檔案

 

這也就可以推測,他最後在資料目錄裡面拿到了.ibd 確沒有出現.frm檔案

進一步測試

1.將此時的k1.ibd檔案備份k1.ibd.bak

2.mysql例項中解除安裝k1表空間,alter table k1 discard tablespace;

3.刪除k1表

4.重新建立k1表,生成了k1.frm k1.ibd

5.解除安裝此時的k1.ibd 並重新載入之前k1.ibd.bak (重新命名為k1.ibd)

6.此時就提示了lost connections,並且日誌中出現了他給我的報錯

 

整個事情的過程,就覆盤出來了。瞭解了此時的ibd檔案,並不是最開始的,也掛在不上去,就只能解析ibd檔案試試。

其實最開始,如果沒有重啟,mysql例項登入上去,也是可以獲得結構跟資料的,會省很多事情。

 

2.嘗試恢復.ibd

工具

percona-data-recovery-tool-for-innodb-0.5,但是這個工具太久遠了.2011年。我嘗試進行了安裝,提示了報錯,果斷放棄。因為提示的報錯,應該是核心什麼過高,這種問題不要太糾結了,就是不適合當下的環境。

 

TwinDB

InnoDB資料恢復的工具——TwinDB介紹

簡單的過了一眼介紹,跟percona-data-recovery-tool-for-innodb-0.5的恢復過程型別,決定上手試試。

make時,需要yum gcc flex bison 順利完成。

並跟著文件進行.ibd資料恢復。

 

重點提示

-t 是跟上表結構,而這個表結構,需要是該工具解析出來的 

# ./sys_parser -u root -p dingjia  -d data_recovered world/city
生成的內容,寫入city.sql

 

 

# ./c_parser -6f pages-city.ibd/FIL_PAGE_INDEX/0000000000000041.page -t city.sql \

> > dumps/default/city \

> 2>dumps/default/city.sql

最後順利完成資料修復。

https://github.com/twindb/undrop-for-innodb

3.反思

  • 切記備份,一定要備份,並確保備份的可用性
  • 生產系統使用者最小化,責任到人
  • 資料庫的使用者最小化分配,責任到團隊或人
  • 碰到類似事情,儘量保持現場,立刻停止業務寫入,事情會好辦很多