不小心drop掉資料庫怎麼辦
不小心刪掉了mysql資料庫怎麼辦
前情提要
- 不小心把資料庫給drop掉了、把table刪掉了。
我的情況是把database整個drop掉、沒有開bin_log紀錄。 - 因為資料庫版本是5.6,預設
innodb_file_per_table=off
,因此資料在被drop掉後,紀錄仍然會在ibdata1裡面。
當下處置和準備
1. 趕緊將資料庫服務整個關掉,要記得把所有mysql的process砍掉。
sudo service stop mysqld
- P.S.最好再用
ps aux |grep "mysql"
檢查一下
2. 把mysql資料夾內的ibdata1
檔案抓出來。
3. 準備一下原本create 要恢復的 table的sql
我因為是使用django,所以能夠用migrate重現原本的table
因此,只要在使用show create table tableName;
就可以拿到create的sql了
P.S. 如果沒有辦法重現的話,twinDB的恢復工具,裡面有sys_parser工具,可以用ibdata1的資料來產生
4. clone 恢復工具
git clone git@github.com:twindb/undrop-for-innodb.git
5. 產生恢復工具(需要gcc、bison、flex、make)
在clone下來的資料夾內編工具
make
P.S. 假如需要sys_parser工具的話,需要再額外去編這個工具(需要對應的mysql dev package,可以用
yum provides "*/mysql_config"
,來show出可以下載的dev package)編譯指令
gcc `mysql_config --cflags` `mysql_config --libs` -o sys_parser sys_parser.c
mysql_config 是mysql的設定檔(通常就叫做mysql_config)。
開始修復
接下來的動作,都是在clone下來的工具的資料夾下操作
手動查的流程
1. 使用stream_parser把ibdata1導成page
./stream_parser -f ibdata1檔案
2. 使用c_parser
來parse第1個page(可以在這分析出table id),並找到對應的database/table
EX: 要找django_database下的user table
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000001.page -t dictionary/SYS_TABLES.sql |grep "django_database/user"
會得到類似這樣的結果,其中,在table名稱後面的,就是他的table Id
000000000521 3B00000149047E SYS_TABLES "django_database/user" 152 3 33 0 64 "" 0 SET FOREIGN_KEY_CHECKS=0;
3. 使用c_parser
來parse第三個page(可以在這分析出index id)
EX: 要找的table id 是 152
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page -t dictionary/SYS_INDEXES.sql | grep '152'
會得到類似這樣的結果,接在table id後面的,就是這個key的index id了
000000000521 3B0000014903A2 SYS_INDEXES 153 45 "PRIMARY" 1 3 0 4294967295 SET FOREIGN_KEY_CHECKS=0;
000000000521 3B0000014903A2 SYS_INDEXES 152 49 "Foreign" 1 3 0 4294967295
這邊選擇Primary key id45
其實剛剛編好的工具裡面,可以產生相對應的查詢表
1. 把recover_dictionary.sh
裡面的43
、50
、58
行的mysql改成自己mysql登入的指令 例如: mysql -u root -p"密碼"
2. 執行recover_dictionary.sh
./recover_dictionary.sh
這樣就會在這台mysql裡面建立一個database 叫
test
3. 就可以直接在這個database裡面下sql來查對應的index id了。
#查詢 table id
select * from SYS_TABLES where name like 'django_database/user%';
#查詢 index id
select * from SYS_INDEXES where table_id=152;
可以很輕鬆的查到對應的index id。
接著真的要開始修復了
1. 先查一下對應index_id的page名稱
ls pages-ibdata1/FIL_PAGE_INDEX/*剛剛查到的index_id*
output : 0000000000000043.page
2. 檢查看看數據是否存在
c_parser -6f pages-ibdata1/FIL_PAGE_INDEX/0000000000000043.page -t /tmp/t2.sql |head -20
這邊
t2.sql
是前置準備時生出來的建表sql
如果無誤的話,應該可以看到被刪掉的資料在上面。
P.S. 這邊的6 可以看一下c_parser --help
看對應的是不是自己資料的格式,以免復原後資料怪怪的(有亂碼之類的)
3. 接下來就可以開始生成恢復的sql了
./c_parser -6f pages-ibdata1/FIL_PAGE_INDEX/0000000000000043.page -t /tmp/t2.sql > dumps/default/user 2> dumps/default/user_load.sql
極重要 : 這邊後面dumps/default/裡面的兩個檔案名稱要和要恢復的table名稱一樣。
user 、user_load.sql
4. 接下來進到要恢復的database裡面,建表還有拿回資料,就可以了。
# 建表
[mysql]> source /home/root/t2.sql
# 導入數據
[mysql]> source /home/root/undrop-for-innodb/dumps/default/user_load.sql
留言
張貼留言