MySQL:如何從ibd文件中恢復數據

在使用獨立表空間的情況下,如果不慎使得innodb存儲引擎的元數據文件ibdata損壞,我們還可以挽救寶貴的數據.因為在innodb使用獨立表空間的情況下,ibdata文件會記錄每個innodb表的id,隻要使得ibd中的表id和ibdata文件中記錄的表id相同,就能夠打開表,讀取到數據.

#創建表

CREATE TABLE `ibdtest` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `fid` int(11) NOT NULL COMMENT '表b中的id',
  `content` char(255) NOT NULL COMMENT '操作內容,系統生成',
  `mark` char(255) NOT NULL COMMENT '備註',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8


#添加數據
INSERT ibdtest (fid,content,mark) VALUES (1,'1','1'),(2,'2','2');

SELECT * FROM ibdtest;

 

關閉mysql將ibdtest.ibd copy出來,放到其他數據庫中來模擬災難.

[root@localhost ~]#/opt/soft/mysql/bin/mysqladmin -p123456 shutdown

120130 18:31:50 mysqld_safe mysqld from pidfile /opt/soft/mysql/60137.localdomain.pid ended

[1]+ Done                    /opt/soft/mysql/bin/mysqld_safe–defaults-file=/opt/soft/mysql/config/my.cnf –user=mysql

 [root@localhost ~]# cd /home/soft/mysql/data/test/
[root@localhost test]# ll
total 1296
-rw-rw—-. 1 mysql mysql  8612 Jan 18 00:06 a.frm
-rw-rw—-. 1 mysql mysql 98304 Jan 18 00:24 a.ibd
-rw-rw—-. 1 mysql mysql  8624 Jan 30 08:34 area.frm
-rw-rw—-. 1 mysql mysql 98304 Jan 30 08:36 area.ibd
-rw-rw—-. 1 mysql mysql  8642 Jan 18 00:05 b.frm
-rw-rw—-. 1 mysql mysql 98304 Jan 18 00:08 b.ibd
-rw-rw—-. 1 mysql mysql  8693 Jan 30 18:27 ibdtest.frm
-rw-rw—-. 1 mysql mysql 98304 Jan 30 18:28 ibdtest.ibd
-rw-rw—-. 1 mysql mysql  8728 Jan  6 16:23 testa.frm
-rw-rw—-. 1 mysql mysql 98304 Jan 10 04:10 testa.ibd
-rw-rw—-. 1 mysql mysql  8693 Jan 30 14:30 testmc.frm
-rw-rw—-. 1 mysql mysql 98304 Jan 30 14:30 testmc.ibd
-rw-rw—-. 1 mysql mysql  8693 Jan 30 13:54 testme.frm
-rw-rw—-. 1 mysql mysql 98304 Jan 30 13:55 testme.ibd
-rw-rw—-. 1 mysql mysql  8693 Jan 30 14:40 testmm.frm
-rw-rw—-. 1 mysql mysql 98304 Jan 30 14:45 testmm.ibd
-rw-rw—-. 1 mysql mysql  8693 Jan 30 13:40 testmu.frm
-rw-rw—-. 1 mysql mysql 98304 Jan 30 13:40 testmu.ibd
-rw-rw—-. 1 mysql mysql  8693 Jan 30 11:08 testmv.frm
-rw-rw—-. 1 mysql mysql 98304 Jan 30 11:10 testmv.ibd
-rw-rw—-. 1 mysql mysql  8694 Jan  4 21:55 testuser.frm
-rw-rw—-. 1 mysql mysql 98304 Jan  4 22:04 testuser.ibd
-rw-rw—-. 1 mysql mysql  8644 Jan 14 21:55 user.frm
-rw-rw—-. 1 mysql mysql 98304 Jan 14 21:55 user.ibd
[root@localhost test]# cp ibdtest.ibd /home/download/
[root@localhost test]# cd /home/download/

#vim打開ibd,使用16進制查看
[root@localhost download]# vim -b ibdtest.ibd 
:%!xxd  

從下圖中能看到 此表在 當前mysql數據庫中的id為0x10,即16.

此時,我們假設災難發生,ibdata損壞…

隻剩下瞭ibdtest.ibd文,我們跳轉到另一個mysql服務器上,用同樣的建表語句創建ibdtest表.

這時我們打開這個mysql服務器下的ibdtest.ibd看看:

 

這個表的id為0x16,即為22,那麼,我們隻需將原有的ibdtest.ibd表id修改為0x16即可.

退出保存的時候一定要記得使用:%!xxd  -r

退出保存.

並將修改好的文件覆蓋掉新的ibdtest.ibd即可,

此mysql服務器會認為該表損毀,無法打開,沒關系,修改innodb_force_recovery = 6,

重啟mysql服務:

Select下,就知道數據是否恢復瞭沒有:

此時,無法執行寫操作,應盡快將數據dump出來,修改innodb_force_recovery = 0,重啟服務,創建新表後,把數據倒回去就ok瞭.恢復數據就不演示瞭.

摘自 ylqmf的專欄

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *