不少時候由於 MySQL 數據庫不能啓動而形成數據沒法訪問,但應用的數據一般沒有丟失,只是系統表空間等其它文件損壞了,或者遇到 MySQL 的 bug。
這個時候若是沒有備份,不少人就覺得數據丟失了,但實際上大部分時候數據仍是有救的。
對於 MyISAM 引擎的表空間,直接把對應的數據文件拷貝到一個新的數據庫就好了,數據就能夠恢復了。
對於 InnoDB 引擎的數據庫表空間能夠採用傳輸表空間的方式把數據救回來.
前提是MySQL開啓了參數 innodb_file_per_table = 1 獨立表空間文件html
當MySQL的數據表空間文件ibdata文件損壞或者是被無修改和刪除,致使MySQL服務重啓失敗。同時MySQL的數據又沒有及時備份,此時如何儘量多的找回MySQL數據呢??mysql
for n in `mysql -e "use db_bbs;show tables;"|sed '1d'`;do echo $n; mysql -e "use db_bbs;select count(*) from $n;";done >test.txt
確認MySQL故障前,庫中一共有多少張表:sql
一共是39張表: [root@10-10-127-11 ~]# mysql -e "use db_bbs;show tables;"|sed '1d'|wc -l 39
刪除ibdata文件(生產環境禁止這麼幹)數據庫
innodb_force_recovery =6 利用MySQL的強制啓動參數來啓動此時的MySQL服務,可是已是無濟於事。因爲是數據表空間文件ibdata文件被刪除了.因此啓動不了此時的MySQL服務。
因爲此MySQL採用的innodb引擎。並且開啓了獨立表空間參數 innodb_file_per_table = 1 。因此此時能夠採用採用傳輸表空間的方式把數據救回來。vim
首先來建立已經丟失的表結構:服務器
先要在故障的MySQL服務器上 安裝 mysql-utilities。
yum -y install mysql-utilities
使用 mysqlfrm 從 .frm 文件裏面找回建表語句:app
分析一個 .frm 文件生成建表的語句ide
mysqlfrm --diagnostic [root@test02 db_bbs]# mysqlfrm --diagnostic /data/mysql/data/db_bbs/t_admin.frm |grep -v "^#" CREATE TABLE `db_bbs`.`t_admin` ( `f_id` int(4) NOT NULL AUTO_INCREMENT, `f_type` tinyint(1) NOT NULL, `f_username` varchar(80) NOT NULL, `f_password` varchar(80) NOT NULL, `f_nick_name` varchar(80) NOT NULL, `f_real_name` varchar(80) NOT NULL, `f_create_time` bigint(4) NOT NULL, `f_update_time` bigint(4) NOT NULL, `f_last_login_time` bigint(4) DEFAULT NULL, `f_last_login_ip` varchar(80) DEFAULT NULL, `f_status` tinyint(1) NOT NULL, PRIMARY KEY `PRIMARY` (`f_id`) USING BTREE ) ENGINE=InnoDB ROW_FORMAT = 2;
把所有的建表語句導入到/tmp/create.sql 文件:post
[root@test02 ~]# cd /data/mysql/data/db_bbs/ [root@test02 db_bbs]# for n in `ls -l /data/mysql/data/db_bbs/*.frm|awk -F '/' '{print $NF}'|xargs -n 40`;do mysqlfrm --diagnostic $n|grep -v "^#" >>/tmp/create.sql;done
把生產的建表語句導入到新MySQL實例庫中:spa
[root@10-10-127-11 ~]# mysql db_bbs < create.sql ERROR 1064 (42000) at line 2: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '5' at line 10 緣由是獲取到的建表sql中包含了ROW_FORMAT = 2 這樣的參數致使的
###去掉建表語句中的包含ROW_FORMAT = 2, ROW_FORMAT = 5這些字符.從新導入建表語句###
批量替換命令以下:
cat /tmp/create.sql|sed -e 's/ENGINE=InnoDB ROW_FORMAT = 2;/ENGINE=InnoDB ;/g'|grep ROW_FORMAT |uniq -c cat /tmp/create.sql|sed -e 's/ENGINE=InnoDB ROW_FORMAT = 5;/ENGINE=InnoDB ;/g'|grep ROW_FORMAT |uniq -c sed -i 's/ENGINE=InnoDB ROW_FORMAT = 2;/ENGINE=InnoDB ;/g' /tmp/create.sql sed -i 's/ENGINE=InnoDB ROW_FORMAT = 5;/ENGINE=InnoDB ;/g' /tmp/create.sql cat /tmp/create.sql|grep ROW_FORMAT |uniq -c
導出建表語句到新MySQL實例db_bbs庫報錯字段太長:
[root@10-10-127-11 ~]# mysql db_bbs -f < create.sql ERROR 1074 (42000) at line 232: Column length too big for column 'f_content' (max = 16383); use BLOB or TEXT instead ERROR 1074 (42000) at line 299: Column length too big for column 'f_desc' (max = 16383); use BLOB or TEXT instead ERROR 1074 (42000) at line 365: Column length too big for column 'f_body_image' (max = 16383); use BLOB or TEXT instead ERROR 1074 (42000) at line 406: Column length too big for column 'f_content' (max = 16383); use BLOB or TEXT instead ERROR 1074 (42000) at line 433: Column length too big for column 'f_summary' (max = 16383); use BLOB or TEXT instead
修改完字段長度類型,從新導入建表sql到全新的MySQL庫中
[root@10-10-127-11 ~]# mysql db_bbs -f < create.sql [root@10-10-127-11 ~]# [root@10-10-127-11 ~]# [root@10-10-127-11 ~]# mysql -e "use db_bbs;show tables;"|sed '1d'|wc -l 39
###將新建的MySQL實例的 沒有包括數據的 .ibd 文件拋棄掉,而後再導入故障數據庫的.idb文件###
拋棄掉新建庫的數據.ibd文件:
mysql -e "show tables from db_bbs" | grep -v Tables_in_db_bbs| while read a; do mysql -e "ALTER TABLE db_bbs.$a DISCARD TABLESPACE" ;done
[root@10-10-127-11 db_bbs]# ll *.ibd|wc -l 39 [root@10-10-127-11 db_bbs]# mysql -e "show tables from db_bbs" | grep -v Tables_in_db_bbs| while read a; do mysql -e "ALTER TABLE db_bbs.$a DISCARD TABLESPACE" ;done [root@10-10-127-11 db_bbs]# ll *.ibd|wc -l ls: cannot access *.ibd: No such file or directory
*能夠看到全部的 .idb 文件都已經被拋棄了。而後把舊的有數據的 .ibd 文件拷貝到這個新MySQL實例的 ./data/db_bbs/ 目錄下面,別忘了把屬主改過來:chown mysql. ,再把這些數據文件 import 到數據庫中**。
[root@test02 db_bbs]# scp *.ibd root@10.10.127.11:/data/mysql/data/db_bbs/ root@10.10.127.11's password: browse_record.ibd 100% 100MB 50.0MB/s 00:02 t_admin.ibd ........ ........
[root@10-10-127-11 db_bbs]# ll *.ibd|wc -l 39 [root@10-10-127-11 db_bbs]# ll *.ibd -rw-r----- 1 root root 104857600 Mar 14 21:56 browse_record.ibd -rw-r----- 1 root root 98304 Mar 14 21:56 t_admin.ibd -rw-r----- 1 root root 98304 Mar 14 21:56 t_anonymous_code.ibd -rw-r----- 1 root root 98304 Mar 14 21:56 t_apply.ibd -rw-r----- 1 root root 9437184 Mar 14 21:56 t_attach.ibd -rw-r----- 1 root root 147456 Mar 14 21:56 t_banner.ibd -rw-r----- 1 root root 163840 Mar 14 21:56 t_banner_log.ibd -rw-r----- 1 root root 114688 Mar 14 21:56 t_black_ip.ibd -rw-r----- 1 root root 98304 Mar 14 21:56 t_black_user.ibd -rw-r----- 1 root root 98304 Mar 14 21:56 t_block_userbaseinfo.ibd -rw-r----- 1 root root 98304 Mar 14 21:56 t_collect.ibd -rw-r----- 1 root root 98304 Mar 14 21:56 t_country_code.ibd -rw-r----- 1 root root 163840 Mar 14 21:56 t_ct_goods.ibd -rw-r----- 1 root root 131072 Mar 14 21:56 t_ct_goods_record.ibd -rw-r----- 1 root root 9437184 Mar 14 21:56 t_ct_integral.ibd -rw-r----- 1 root root 46137344 Mar 14 21:56 t_ct_integral_record.ibd -rw-r----- 1 root root 27262976 Mar 14 21:56 t_ct_news.ibd -rw-r----- 1 root root 9437184 Mar 14 21:56 t_ct_order.ibd -rw-r----- 1 root root 98304 Mar 14 21:56 t_feedback.ibd -rw-r----- 1 root root 98304 Mar 14 21:56 t_lexicon.ibd -rw-r----- 1 root root 327680 Mar 14 21:56 t_logs.ibd -rw-r----- 1 root root 98304 Mar 14 21:56 t_manage.ibd -rw-r----- 1 root root 98304 Mar 14 21:56 t_module.ibd -rw-r----- 1 root root 9437184 Mar 14 21:56 t_post_extend.ibd -rw-r----- 1 root root 12582912 Mar 14 21:56 t_post.ibd -rw-r----- 1 root root 98304 Mar 14 21:56 t_post_video.ibd -rw-r----- 1 root root 98304 Mar 14 21:56 t_realtime_message.ibd -rw-r----- 1 root root 98304 Mar 14 21:56 t_recommend.ibd -rw-r----- 1 root root 46137344 Mar 14 21:56 t_reply.ibd -rw-r----- 1 root root 98304 Mar 14 21:56 t_reward.ibd -rw-r----- 1 root root 196608 Mar 14 21:56 t_sensitive_word.ibd -rw-r----- 1 root root 98304 Mar 14 21:56 t_system_message.ibd -rw-r----- 1 root root 9437184 Mar 14 21:56 t_userbaseinfo.ibd -rw-r----- 1 root root 344064 Mar 14 21:56 t_userextendinfo.ibd -rw-r----- 1 root root 12582912 Mar 14 21:56 t_user_health.ibd -rw-r----- 1 root root 98304 Mar 14 21:56 t_user_message.ibd -rw-r----- 1 root root 442368 Mar 14 21:56 t_user_read_module_log.ibd -rw-r----- 1 root root 17825792 Mar 14 21:56 t_viewpoint.ibd -rw-r----- 1 root root 114688 Mar 14 21:56 t_white_ip.ibd [root@10-10-127-11 db_bbs]# chown mysql.mysql *.ibd mysql -e "show tables from db_bbs" | grep -v Tables_in_db_bbs| while read a; do mysql -e "ALTER TABLE db_bbs.$a import TABLESPACE" ;done
導入每一個表的表空間時,出現個別表報錯:
[root@10-10-127-11 db_bbs]# mysql -e "show tables from db_bbs" | grep -v Tables_in_db_bbs| while read a; do mysql -e "ALTER TABLE db_bbs.$a import TABLESPACE" ;done ERROR 1808 (HY000) at line 1: Schema mismatch (Table has ROW_TYPE_DYNAMIC row format, .ibd file has ROW_TYPE_COMPACT row format.)
校驗表文件,發現只有browse_record表導入獨立表表空間時報錯致使此表恢復數據失敗
[root@10-10-127-11 db_bbs]# mysqlcheck -c db_bbs db_bbs.browse_record Warning : InnoDB: Tablespace has been discarded for table 'browse_record' Error : Tablespace has been discarded for table 'browse_record' error : Corrupt db_bbs.t_admin OK db_bbs.t_anonymous_code OK db_bbs.t_apply OK db_bbs.t_attach OK db_bbs.t_banner OK db_bbs.t_banner_log OK db_bbs.t_black_ip OK db_bbs.t_black_user OK db_bbs.t_block_userbaseinfo OK db_bbs.t_collect OK db_bbs.t_country_code OK db_bbs.t_ct_goods OK db_bbs.t_ct_goods_record OK db_bbs.t_ct_integral OK db_bbs.t_ct_integral_record OK db_bbs.t_ct_news OK db_bbs.t_ct_order OK db_bbs.t_feedback OK db_bbs.t_lexicon OK db_bbs.t_logs OK db_bbs.t_manage OK db_bbs.t_module OK db_bbs.t_post OK db_bbs.t_post_extend OK db_bbs.t_post_video OK db_bbs.t_realtime_message OK db_bbs.t_recommend OK db_bbs.t_reply OK db_bbs.t_reward OK db_bbs.t_sensitive_word OK db_bbs.t_system_message OK db_bbs.t_user_health OK db_bbs.t_user_message OK db_bbs.t_user_read_module_log OK db_bbs.t_userbaseinfo OK db_bbs.t_userextendinfo OK db_bbs.t_viewpoint OK db_bbs.t_white_ip OK
上面的browse_record 表恢復失敗 報錯解決辦法以下:
參考:https://blog.csdn.net/weixin_30607659/article/details/94987901
刪除導入到新MySQL實例的表browse_record,而後執行下面的建表語句,新建browse_record表:
CREATE TABLE `browse_record` ( `id` int(4) unsigned NOT NULL AUTO_INCREMENT, `post_id` int(4) unsigned NOT NULL, `user_id` int(4) unsigned NOT NULL, `status` tinyint(1) unsigned NOT NULL, `update_time` bigint(4) unsigned NOT NULL, `create_time` bigint(4) unsigned NOT NULL, PRIMARY KEY (`id`) USING BTREE, KEY `browse` (`post_id`,`user_id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 row_format=compact;
提示:若是在新MySQL實例單獨刪除表browse_record,刪除失敗的話,那就直接drop掉新MySQL實例上的db_bbs庫,從新導入db_bbs全部表的建表語句,而後再執行下面的命令:
mysql -e "show tables from db_bbs" | grep -v Tables_in_db_bbs| while read a; do mysql -e "ALTER TABLE db_bbs.$a DISCARD TABLESPACE" ;done
從新導入表空間到新實例MySQL中:
[root@10-10-127-11 db_bbs]# mysql -e "show tables from db_bbs" | grep -v Tables_in_db_bbs| while read a; do mysql -e "ALTER TABLE db_bbs.$a import TABLESPACE" ;done [root@10-10-127-11 db_bbs]#
到此處數據修復完成
校驗MySQL db_bbs庫中的表:
[root@10-10-127-11 db_bbs]# mysqlcheck -c db_bbs db_bbs.browse_record OK db_bbs.t_admin OK db_bbs.t_anonymous_code OK db_bbs.t_apply OK db_bbs.t_attach OK db_bbs.t_banner OK db_bbs.t_banner_log OK db_bbs.t_black_ip OK db_bbs.t_black_user OK db_bbs.t_block_userbaseinfo OK db_bbs.t_collect OK db_bbs.t_country_code OK db_bbs.t_ct_goods OK db_bbs.t_ct_goods_record OK db_bbs.t_ct_integral OK db_bbs.t_ct_integral_record OK db_bbs.t_ct_news OK db_bbs.t_ct_order OK db_bbs.t_feedback OK db_bbs.t_lexicon OK db_bbs.t_logs OK db_bbs.t_manage OK db_bbs.t_module OK db_bbs.t_post OK db_bbs.t_post_extend OK db_bbs.t_post_video OK db_bbs.t_realtime_message OK db_bbs.t_recommend OK db_bbs.t_reply OK db_bbs.t_reward OK db_bbs.t_sensitive_word OK db_bbs.t_system_message OK db_bbs.t_user_health OK db_bbs.t_user_message OK db_bbs.t_user_read_module_log OK db_bbs.t_userbaseinfo OK db_bbs.t_userextendinfo OK db_bbs.t_viewpoint OK db_bbs.t_white_ip OK
[root@10-10-127-11 ~]# for n in `mysql -e "use db_bbs;show tables;"|sed '1d'`;do echo $n; mysql -e "use db_bbs;select count(*) from $n;";done >test.txt11 和原來的庫test.txt表記錄文件對比。 [root@test02 ~]# vimdiff test.txt11 test.txt 表記錄徹底一致
到此處MySQL的數據修復完畢
參考資料:
https://mp.weixin.qq.com/s/r3KTPsFay292JnO0lgTLUg
https://www.cnblogs.com/jiangxu67/p/4744283.html
https://blog.csdn.net/Sonny_alice/article/details/80198200
https://www.cnblogs.com/jiangxu67/p/4744283.html