通過任意檔案下載下傳找到了mysql的備份,表類型是獨享式innodb,由一個frm檔案和一個ibd檔案組成。
本以為直接複制到本地的mysql資料目錄中即可恢複資料,但在查詢時卻發現并不如所願:
mysql> select * from admin;
ERROR 1146 (42S02): Table \'test.admin\' doesn\'t exist
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| admin |
+----------------+
1 row in set (0.00 sec)
查找資料得知,innodb的表資訊存放于datadir下面的ib_logfile*與ibdata1檔案内。而由于事務的存在,這些檔案在複制後并不能還原。
由于獨享式innodb的資料實際上都儲存在ibd檔案内,于是嘗試直接從ibd檔案内恢複資料。最後在stackexchange(http://dba.stackexchange.com/questions/57120/recover-mysql-database-from-data-folder-without-ibdata1-from-ibd-files )找到了老外的一個思路:
1.使用mysqlfrm工具将frm轉換為建表語句
2.建立空表
3.釋放表空間
4.複制ibd檔案,還原表空間
從http://dev.mysql.com/downloads/utilities/ 下載下傳了mysqlfrm工具,執行時發現速度非常慢,同時不支援2003。于是下載下傳其源碼,發現其原理大緻如下:
1.修改frm頭部标志位為_DB_TYPE_HEAP,表示記憶體表
2.修改frm檔案中儲存的表引擎名稱為MEMORY
3.複制檔案到資料目錄,執行show create table還原sql
4.替換語句中的MEMORY為原始引擎
對照以上原理,修改成了速度很快的c#版本。
使用工具進行測試,可以成功的還原資料,但操作非常麻煩,為了便捷操作最後寫了這個工具批量恢複。
本地使用了十餘個表進行了測試,總資料條數大概五百萬條,沒有出現任何問題。
附件内InnoDBRestore.exe是編譯好的恢複工具,需要.net 4.0與mysql 5.6環境,指令行如下:
Bash
InnoDBRepair <username> <password> <port> <srcdir> <destDB>
例如:
Bash
InnoDBRepair root pass 3306 c:\dbcopy my_database
會将c:\dbcopy目錄下所有的innodb和myiasm表還原到本地mysql的my_database資料庫中,mysql必須是5.6或更高版本才能成功還原。
其源碼為InnoDBRestore.cs,編譯指令行:
Bash
csc /r:mysql.data.dll InnoDBRestore.cs
務必使用.net 4.0進行編譯。
MySqlFrm.exe是c#版本的frm轉sql工具,需要.net 4.0與mysql環境,指令行如下:
Bash
mysqlfrm <username> <password> <port> <srcdir>
例如:
Bash
mysqlfrm root pass 3306 c:\dbcopy
會将c:\dbcopy目錄下所有的frm轉換為同名的建表sql并儲存在frm檔案所在目錄(需要借助本地mysql進行轉換)。
其源碼為mysqlfrm.cs,編譯指令行:
Bash
csc /r:mysql.data.dll mysqlfrm.cs
同樣務必使用.net 4.0進行編譯。
關于工具的利用:
- 在任意檔案下載下傳中可以嘗試直接下載下傳mysql的資料檔案進行還原;mysql注入時可以load_file讀取frm來偷懶,确定表并不是很大的時候(例如管理者表)甚至可以直接讀取檔案之後恢複。
- 脫褲的時候可以不管表類型直接打包了,比mysqldump快得多。innodb表壓縮率在20%左右,打包下來并不會很大。
- 還原崩潰的mysql資料。
已知錯誤資訊:
ERROR 1030 (HY000): Got error -1 from storage engine
換用高版本的mysql進行恢複,推薦使用5.6.24版本。
若出現此錯誤資訊,務必手動删除@@datadir下剛剛指定的目标資料庫,否則mysql服務停止後将無法啟動。
(不一定有用但可能解決大問題的工具,留着備用吧)
下載下傳位址:

mysqlibd.zip
百度網盤:http://pan.baidu.com/s/1c0rrLfE
解壓密碼見注釋。