MySQL 通過ibd恢復數據


個人學習筆記,謝絕轉載!!!

原文:https://www.cnblogs.com/wshenjin/p/14780723.html


故障背景:線上一台老數據庫跑在單盤上,因壞道導致ibdata損壞。
恢復前提:表ibd文件正常,開啟innodb_file_per_table。

安裝mysqlfrm以讀取表結構

[root@ ~]#  wget https://downloads.mysql.com/archives/get/p/30/file/mysql-utilities-1.6.5.tar.gz
[root@ ~]#  tar -xvzf mysql-utilities-1.6.5.tar.gz 
[root@ ~]#  cd mysql-utilities-1.6.5
[root@ ~]#  python ./setup.py build
[root@ ~]#  python ./setup.py install

導出故障實例表結構

[root@ ~]#  /usr/bin/mysqlfrm --diagnostic /data/database/mysql/testdb/user_info.frm

恢復數據

新起一個MySQL5.7新實例,在新實例上建相同的表,並卸載表空間

(root@localhost) > alter table testdb.user_info discard tablespace;

將故障庫user_info表的ibd文件(testdb/user_info.ibd)拷貝到新實例對應的路徑

掛在表空間

(root@localhost) > alter table testdb.user_info import tablespace;

如果報錯Error Code: 1808. Schema mismatch (Table has ROW_TYPE_DYNAMIC row format, .ibd file has ROW_TYPE_COMPACT row format.)
則在建表語句后加上  ROW_FORMAT=COMPACT

至此,user_info表就恢復了。

另一種方法(mysql5.5):

新起一個MySQL5.5新實例,在新實例上建相同的表,關閉數據庫。從新表的ibd文件(testdb/user_info.ibd)中獲取新表的tablespace id :

[root@ ~]#  hexdump -C /data/database/mysql/testdb/user_info.ibd | head -3                                           
00000000  55 e6 77 a3 00 00 00 00  00 00 00 00 00 00 00 00  |U.w.............|
00000010  00 00 00 00 00 00 35 69  00 08 00 00 00 00 00 00  |......5i........|
00000020  00 00 00 00 00 e2 00 00  00 e2 00 00 00 00 00 00  |................|

從上面可以知道,新表的tablespace id是 00e2(16進制)。
這時用vim -b打開舊表的idb文件(testdb/user_info.ibd),vim打開后輸入 :%!xxd 轉換為16進制,大致如下:

0000000: 6372 4c23 0000 0000 0000 0000 0000 0000  crL#............
0000010: 0000 0000 0696 f666 0008 0000 0000 0000  .......f........
0000020: 0000 0000 00d6 0000 00d6 0000 0000 0000  ................
0000030: 0007 0000 0040 0000 0000 0000 0005 0000  .....@..........
0000040: 0000 ffff ffff 0000 ffff ffff 0000 0000  ................
0000050: 0001 0000 0000 009e 0000 0000 009e 0000  ................

可以看到舊表的tablespace id是 00d6(16進制)。
修改為00e2,再輸入 :%!xxd -r 保存,最后wq退出vim。

將故障庫user_info表的ibd文件(testdb/user_info.ibd)拷貝到新實例對應的路徑。

最后MySQL的配置my.cnf中配置以下兩個選項:

innodb_force_recovery=6
innodb_purge_threads=0

啟動數據庫,user_info表即恢復了。只要將user_info表重新導出導入到舊庫即可。
如果不配置上面兩個選項,數據庫會認為user_info已被損壞。變更了新的tablespace id后的.ibd表文件,啟動數據庫后只能認出數據,但不能寫入,這是因為原ibdata文件不僅保存了space id索引,還同時保存了一些其它的元數據。為了使元數據補全,所以采取導出、再導入的操作。

參考:

https://blog.csdn.net/u012887385/article/details/54406712
https://blog.csdn.net/weixin_31478029/article/details/113171741
https://www.cnblogs.com/gered/p/12524586.html
https://mp.weixin.qq.com/s/Iad4qT_vG9B3vBhvQ2p_2g


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM