概述
之所以做這個實驗,也是有個朋友誤刪了某張表的frm和ibd文件,然後要導入數據的時候一直提示無法重新創建這張表,這時候應該怎麼解決呢?我們用一個實驗來看看。。
一、環境準備
CREATE TABLE `t` ( `id` int(11) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8;CREATE TABLE `t2` ( `id` int(11) DEFAULT NULL) ENGINE=myisam DEFAULT CHARSET=utf8;insert into t values(1);insert into t values(2);insert into t values(3);insert into t2 values(1);insert into t2 values(2);
二、手動刪除frm和ibd文件
rm -rf t.frm t.ibdrm -rf t2.frm t2.MYD t2.MYI
三、在沒關閉資料庫且會話窗口沒關閉的情況下查看
select * from t;select * from t2;
四、新開會話窗口(未關閉資料庫)
以下ERROR 29 (HY000): File './test/t2.MYD' not found (Errcode: 2 - No such file or directory)提示表明t2資料庫文件損壞了
測試在t表表結構不存在的時候插入數據,發現可以插入成功
mysql> insert into t values(4);Query OK, 1 row affected (0.06 sec)mysql> select * from t;
五、備份t表
重啟之前得在其他資料庫新建t表結構,然後複製frm文件到原資料庫即可
六、重新創建t2表及數據
因為myisam不需要記錄信息到數據字典,所以drop後重建就行了
drop table t2;CREATE TABLE `t2` ( `id` int(11) DEFAULT NULL) ENGINE=myisam DEFAULT CHARSET=utf8;insert into t2 values(1);insert into t2 values(2);
此時t2表結構和數據已經恢復
七、重啟資料庫後測試
# systemctl restart mysqldmysql> select * from t;ERROR 1146 (42S02): Unknown error 1146mysql> drop table t;ERROR 1051 (42S02): mysql> CREATE TABLE `t` ( -> `id` int(11) DEFAULT NULL -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;ERROR 1050 (42S01): Unknown error 1050
八、測試一下修復表
可以發現修復不成功
mysql> check table t;mysql> repair table t;
九、不停機情況下拷貝其他庫的t表
考慮到在使用innoDB引擎的資料庫中,其實際數據不是存放在資料庫目錄下的,而是放在一個叫ibdata1的文件內(默認配置時),其目錄下只是放置了資料庫的表及表結構相關的信息。這裡在其他庫上建立t表及數據,然後將這個表複製到test庫下
use mysql;CREATE TABLE `t` ( `id` int(11) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8;insert into t values(1);insert into t values(2);insert into t values(3);insert into t values(4);# cp t.frm ../test/# mysql -uroot -pmysql> select * from t;ERROR 1017 (HY000): Unknown error 1017
拷貝後發現還是沒有恢復成功
十、資料庫升級
升級後還是沒有恢復成功
mysql_upgrade -uroot -p --forcemysql> select * from t;ERROR 1017 (HY000): Unknown error 1017
十一、重新創建t表(引擎為myisam)(該方法不能恢復為innodb引擎,廢棄)
因為共享表空間記錄了信息
CREATE TABLE `t` ( `id` int(11) DEFAULT NULL) ENGINE=myisam DEFAULT CHARSET=utf8;insert into t values(1);insert into t values(2);insert into t values(3);insert into t values(4);alter table t engine=innodb;drop table t;
十二、修改配置文件恢復(最終選擇)
配置文件的一個參數:innodb_force_recovery
innodb_force_recovery 會影響整個InnoDB存儲引擎的恢復狀況。默認為0,表示當需要恢復時執行所有的
innodb_force_recovery可以設置為1-6,大的數字包含前面所有數字的影響。當設置參數值大於0後,可以對表進行
select,create,drop操作,但insert,update或者delete這類操作是不允許的。
(SRV_FORCE_IGNORE_CORRUPT):忽略檢查到的corrupt頁。(SRV_FORCE_NO_BACKGROUND):阻止主線程的運行,如主線程需要執行full purge操作,會導致crash。(SRV_FORCE_NO_TRX_UNDO):不執行事務回滾操作。(SRV_FORCE_NO_IBUF_MERGE):不執行插入緩衝的合併操作。(SRV_FORCE_NO_UNDO_LOG_SCAN):不查看重做日誌,InnoDB存儲引擎會將未提交的事務視為已提交。(SRV_FORCE_NO_LOG_REDO):不執行前滾的操作。
1、在mysql庫創建t表及數據
use mysql;CREATE TABLE `t` ( `id` int(11) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8;insert into t values(1);insert into t values(2);insert into t values(3);insert into t values(4);
2、停止資料庫
systemctl stop mysqld
3、複製frm和ibd文件
# cp -a ../mysql/t.frm .# cp -a ../mysql/t.ibd .
4、修改參數
在my.cnf設置參數innodb_force_recovery = 6
5、兩次啟動資料庫
啟動mysql,再關閉mysql 把配置innodb_force_recovery = 6給刪除了,然後啟動mysql
6、drop 表後重建
提示ERROR 1813 (HY000): Tablespace '`test`.`t`' exists或ERROR 1813 (HY000): Unknown error 1813都是表空間問題
此時只需要刪除對應的.ibd文件即可或者alter table t discard tablespace;來刪除
綜上:
1、誤刪數據文件時不要忙著重啟資料庫,先查看錶是否存在,做一下備份
2、定期備份是很重要的
3、以上innodb表實際上只恢復了表結構,表數據並沒有恢復,可以考慮通過mysqlbinlog進行回退
覺得有用的朋友多幫忙轉發哦!後面會分享更多devops和DBA方面的內容,感興趣的朋友可以關注下~