.frm文件:保存了每個表的元數據,包括表結構的定義等;
.ibd文件:InnoDB引擎開啟了獨立表空間(my.ini中配置innodb_file_per_table = 1)產生的存放該表的數據和索引的文件。
1、安裝相同版本的mysql;
找回表結構
2、找回表結構(若有表結構,直接導入表即可)
- 建立同名的表(InnoDB),不知道列數的話隨意一個字段即可(如果字段個數不一致會報錯,去日志文件中查看有列數重復這些步驟)
- 關閉mysql服務
- 用需要恢復的.frm文件覆蓋新生成的.frm文件。
- 修改my.ini配置innodb_force_recovery = 6進入恢復模式(只讀)。
- 啟動mysql服務。
- desc tble_name或者show create table tbl_name獲取創建表結構語句。(直接查看表設計字段會導致數據庫異常)
- 復制建表sql,刪除表(不能直接刪.frm和.ibd會導致新建時報已存在,如果直接刪除文件,需要將frm文件拷貝回來,再drop表),執行sql創建表結構。(這個步驟要把innodb_force_recovery = 6注解掉或者回復為0,不然提示只讀)。
這里會出現啟動后沒有表結構,這是需要查看mysql的日志文件
找到日志文件位置:
show variables like '%error%'
這里的.是相對於mysql的,windows可以根據快捷方式找到mysql位置然后再找.err錯誤文件
找到報錯信息為
2018-12-18T08:52:30.314230Z 2 [Warning] InnoDB: Table bookkeeping/concategory contains 1 user defined columns in InnoDB, but 3 columns in MySQL.
意思是新建的有1列,但是復制過來的frm文件中含有3列。這時候知道列數,重做上述步驟。
恢復數據
刪除新建的表空間
單個執行刪除表空間語句
ALTER TABLE <table_name> DISCARD TABLESPACE;
批量刪除空間,執行以下語句。
SELECT CONCAT('ALTER TABLE ', table_name, ' DISCARD TABLESPACE;') FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'db_name';
獲得每個表的刪除表空間語句,直接全部選中復制(Navicat)
在前后加上外鍵約束檢查關閉和開啟執行
2.將待恢復的<table_name>.ibd文件copy到目標數據庫文件夾下(這時候在navicat中看不到表名,不要慌!!!),並修改文件權限(chown u:g file),批量修改權限chown mysql:mysql /usr/mysql/data/db_name/*
導入表空間
單個執行導入表空間語句
ALTER TABLE <table_name> IMPORT TABLESPACE;
批量導入表空間
SELECT CONCAT('ALTER TABLE ', table_name, ' IMPORT TABLESPACE;') FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'db_name';
這里和刪除一樣,不贅述,復制所選語句,加上關閉開啟檢查,執行
可能出現問題
1.mysql 1808錯誤:這是由於mysql 5.6的文件恢復到mysql 5.7版本導致的錯誤,需要在建表語句后面添加ROW_FORMAT=COMPACT
2.mysql 1812錯誤:copy的ibd文件沒有賦權,用chown u:g file
3.mysql 1451錯誤: Cannot delete or update a parent row: a foreign
在前后加上
SET foreign_key_checks = 0; -- 先設置外鍵約束檢查關閉 SET foreign_key_checks = 1; -- 開啟外鍵約束檢查,以保持表結構完整性
總結
1.建立表結構(有備份直接用,跳過第一步的找回表結構)
2.刪除新建的表空間
3.拷貝.ibd數據文件覆蓋新建的文件
4.導入表空間
以下內容和技術無關(身體是革命的本錢,不可用命換錢):
今日烹飪經驗
土豆燒肉燒時,肉要順着紋理切(不然容易碎),燒時可以多放生抽(提鮮),但是老抽千萬不能超過半鏟子(不然會變成碳),圖就不放了,影響大家胃口。