mysql數(shù)據(jù)損壞,如何通過(guò)ibd和frm文件批量恢復(fù)數(shù)據(jù)庫(kù)數(shù)據(jù)
問(wèn)題描述
客戶那邊的測(cè)試服務(wù)器下午3:00左右因不明原因,所有服務(wù)訪問(wèn)不了,ssh也無(wú)法連接,客戶手動(dòng)進(jìn)行強(qiáng)制重啟服務(wù)器,重啟后將所有應(yīng)用、中間件重啟,重啟nacos時(shí)發(fā)現(xiàn)無(wú)法連接數(shù)據(jù)庫(kù),通過(guò)賬號(hào)密碼登錄到數(shù)據(jù)庫(kù)發(fā)現(xiàn)可以正常登錄,但是奇怪的問(wèn)題來(lái)了。。。
show tables
時(shí)可以正常看到表,但是查詢表中數(shù)據(jù)時(shí)發(fā)現(xiàn)提示表不存在。。
如下圖:
查看mysql日志:
作為一名mysql菜的不能再菜的小白。。這屬實(shí)難到我了,看起來(lái)像是數(shù)據(jù)損壞。。沒(méi)辦法,通過(guò)多方查詢資料,解決辦法如下:
解決辦法
首先了解InnoDB引擎創(chuàng)建數(shù)據(jù)庫(kù)會(huì)產(chǎn)生的文件:
.ibd
:包含每個(gè)表的數(shù)據(jù)和索引.frm
:描述表的結(jié)構(gòu)ibdata1
:包含所有表的字典和歷史操作
在test目錄下,包含每個(gè)表的.ibd和.frm文件
恢復(fù)前提:ibd文件的數(shù)據(jù)都是正常的
之后也是需要通過(guò)這些文件進(jìn)行恢復(fù),我這邊新啟了一個(gè)mysql實(shí)例,過(guò)程略,
大體的恢復(fù)步驟如下:
1.在新的mysql實(shí)例中創(chuàng)建數(shù)據(jù)庫(kù),需要跟原數(shù)據(jù)庫(kù)的庫(kù)名和字符集保持一致
2.創(chuàng)建數(shù)據(jù)表,表名要求一致,對(duì)應(yīng)原庫(kù)data目錄下的表名(我這里用工具對(duì)原庫(kù)表的表結(jié)構(gòu)導(dǎo)出創(chuàng)建的)
3.通過(guò).ibd文件批量恢復(fù)表數(shù)據(jù)信息
- 3.1 讓表結(jié)構(gòu)和表空間脫離
- 3.2 將需要恢復(fù)的.ibd替換到新實(shí)例的/data的對(duì)應(yīng)庫(kù)下
1、安裝mysqlfrm 工具
下載鏈接:
wget https://cdn.mysql.com/archives/mysql-utilities/mysql-utilities-1.6.5.tar.gz tar -xvf mysql-utilities-1.6.5.tar.gz cd mysql-utilities-1.6.5/ 安裝(需要Python環(huán)境,python2.6及以上) python ./setup.py build python ./setup.py install 檢查是否安裝成功 mysqlfrm --version
2、使用mysqlfrm查看表結(jié)構(gòu)創(chuàng)建語(yǔ)句
mysqlfrm 有–basedir模式以及–server 模式,推薦–server,能夠還原最為準(zhǔn)確的信息
使用方式(需要啟動(dòng)原mysql):
格式:mysqlfrm --server=用戶名:密碼@數(shù)據(jù)庫(kù)地址:端口 需恢復(fù)的frm文件目錄 --diagnostic > 保存SQL文件名.sql
mysqlfrm --server=root:password@x.x.x.x:13306 /home/mysql/data/test/*.frm --diagnostic > test_frm.sql
執(zhí)行所生成的SQL文件
注:mysqlfrm僅僅顯示整個(gè)數(shù)據(jù)庫(kù)的表結(jié)構(gòu)創(chuàng)建語(yǔ)句,可以顯示在控制臺(tái)也可以輸出到文件,不過(guò)需要手動(dòng)執(zhí)行這些表的創(chuàng)建SQL語(yǔ)句。
先創(chuàng)建數(shù)據(jù)庫(kù)
CREATE database test;
可以查看生成的sql文件手動(dòng)刪除相關(guān)無(wú)用信息等,可命令行執(zhí)行或者客戶端執(zhí)行等
命令行導(dǎo)入:
mysql -uroot -ppassword test < test_frm.sql
此時(shí)執(zhí)行完就可以通過(guò)desc命令查看到表結(jié)構(gòu)了(報(bào)錯(cuò)1:這步我遇到報(bào)錯(cuò),下面有解決方法)
3、通過(guò).ibd文件批量恢復(fù)表數(shù)據(jù)信息
1)讓表結(jié)構(gòu)和表空間脫離生
成表結(jié)構(gòu)和表空間脫離的sql:
mysql -uroot -ppassword -h x.x.x.x -P 13306 -e " SELECT concat('alter table ', table_name, ' discard tablespace;') FROM information_schema.tables WHERE table_schema = 'test';" > /root/test.sql
將sql文件中沒(méi)有用的內(nèi)容刪除
sed '/^c/d' /root/test.sql> /root/test_discard_new.sql
將sql文件導(dǎo)入到新庫(kù)
mysql -uroot -ppassword -h x.x.x.x -P 13307 test_AII < test_discard_new.sql
2)將需要恢復(fù)的.ibd文件替換到新庫(kù)所在的/data/庫(kù)名 目錄下
cp /home/mysql/data/test/*.ibd /home/mysql-test/data/test/
3)權(quán)限設(shè)置
chown -R mysql. /home/mysql-test/data/test
4)導(dǎo)入表空間
mysql -uroot -ppassword -h x.x.x.x -P 13306 -e " SELECT concat('alter table ', table_name, ' import tablespace;') FROM information_schema.tables WHERE table_schema = 'test';" > /root/tem_import.sql
清除沒(méi)用的數(shù)據(jù)
sed '/^c/d' /root/tem_import.sql > /root/config_import.sql
將sql文件導(dǎo)入(報(bào)錯(cuò)2:有報(bào)錯(cuò),下面有解決方法)
mysql -uroot -ppassword -h x.x.x.x -P 13307 test_aii < /root/config_import.sql
此時(shí)如果操作沒(méi)問(wèn)題,查看數(shù)據(jù)庫(kù)表已經(jīng)有了原始數(shù)據(jù)了(報(bào)錯(cuò)3:有報(bào)錯(cuò),查看下面解決方法)
恢復(fù)過(guò)程中遇到的問(wèn)題
報(bào)錯(cuò)1、在導(dǎo)入創(chuàng)建表結(jié)構(gòu)語(yǔ)句的時(shí)候報(bào)錯(cuò)了,顯示語(yǔ)法錯(cuò)誤我的創(chuàng)建表語(yǔ)句如下:
1064 - 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, COMMENT 'config_info'' at line 21, Time: 0.011000s
建表語(yǔ)句:
CREATE TABLE `test_config`.`config_info` ( `id` bigint(20) NOT NULL AUTO_INCREMENT comment 'id', `data_id` varchar(255) COLLATE `utf8_bin` NOT NULL comment 'data_id', `group_id` varchar(255) COLLATE `utf8_bin` DEFAULT NULL, `content` longtext COLLATE `utf8_bin` comment 'content', `md5` varchar(32) COLLATE `utf8_bin` DEFAULT NULL comment 'md5', `gmt_create` datetime NOT NULL comment '創(chuàng)建時(shí)間', `gmt_modified` datetime NOT NULL comment '修改時(shí)間', `src_user` text COLLATE `utf8_bin` DEFAULT NULL comment 'source user', `src_ip` varchar(50) COLLATE `utf8_bin` DEFAULT NULL comment 'source ip', `app_name` varchar(128) COLLATE `utf8_bin` DEFAULT NULL, `tenant_id` varchar(128) COLLATE `utf8_bin` DEFAULT NULL comment '租戶字段', `c_desc` varchar(256) COLLATE `utf8_bin` DEFAULT NULL, `c_use` varchar(64) COLLATE `utf8_bin` DEFAULT NULL, `effect` varchar(64) COLLATE `utf8_bin` DEFAULT NULL, `type` varchar(64) COLLATE `utf8_bin` DEFAULT NULL, `c_schema` text COLLATE `utf8_bin` DEFAULT NULL, `encrypted_data_key` text COLLATE `utf8_bin` comment '秘鑰', PRIMARY KEY `PRIMARY` (`id`) USING BTREE, UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`(255),`group_id`(255),`tenant_id`(128)) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8, ROW_FORMAT = 5, COMMENT 'config_info';
解決方法:
將ROW_FORMAT 改為COMPACT或DYNAMIC就可以解決
報(bào)錯(cuò)2:導(dǎo)入表空間時(shí),報(bào)錯(cuò)
ERROR 1812 (HY000): Tablespace is missing for table ops.tt7.
解決方法:查看從原庫(kù)/data/目錄copy的.ibd文件的屬主和屬組是否是mysql的啟動(dòng)用戶,不是則修改即可
報(bào)錯(cuò)3:所有步驟執(zhí)行完成后,重啟mysql時(shí)啟動(dòng)失敗,查看mysql日志如下報(bào)錯(cuò):
[InnoDB] [FATAL] Tablespace id is xx in the data dictionary but in file .\test\config.ibd it is xx!
這個(gè)錯(cuò)誤意思就是庫(kù)名表名一致,但是表空間id已經(jīng)不同了,說(shuō)明上面的執(zhí)行步驟有錯(cuò)誤,導(dǎo)致表空間id記錄在兩個(gè)地方,一個(gè)在系統(tǒng)表空間中的字典表,一個(gè)記錄在表對(duì)應(yīng)的ibd文件里。這個(gè)時(shí)候,不管出于何種原因,ibd文件使用了舊文件,就會(huì)報(bào)這個(gè)錯(cuò)誤。并且導(dǎo)致mysqld進(jìn)程崩潰退出。
解決方法:
將對(duì)應(yīng)的庫(kù)中的某個(gè)表刪除,并重新生成表結(jié)構(gòu)并創(chuàng)建表,然后重新將原表結(jié)構(gòu)和表空間脫離并重新導(dǎo)入表空間,操作上面都有,重新執(zhí)行即可
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- MySQL通過(guò)binlog實(shí)現(xiàn)恢復(fù)數(shù)據(jù)
- Python MySQL如何通過(guò)Binlog獲取變更記錄恢復(fù)數(shù)據(jù)
- MySQL通過(guò)日志恢復(fù)數(shù)據(jù)的操作步驟
- MySQL通過(guò)ibd文件恢復(fù)數(shù)據(jù)的操作過(guò)程
- MySQL開啟配置binlog及通過(guò)binlog恢復(fù)數(shù)據(jù)步驟詳析
- mysql binlog如何恢復(fù)數(shù)據(jù)到某一時(shí)刻
- MySQL誤刪后使用binlog恢復(fù)數(shù)據(jù)的實(shí)現(xiàn)方法
- Mysql如何通過(guò)ibd文件恢復(fù)數(shù)據(jù)
- mysql如何根據(jù).frm和.ibd文件恢復(fù)數(shù)據(jù)表
- 一步步教你如何使用mysql?binlog恢復(fù)數(shù)據(jù)
- MySql恢復(fù)數(shù)據(jù)方法梳理講解
- Mysql通過(guò)ibd文件恢復(fù)數(shù)據(jù)的詳細(xì)步驟
- MySQL數(shù)據(jù)庫(kù)通過(guò)Binlog恢復(fù)數(shù)據(jù)的詳細(xì)步驟
- Mysql如何通過(guò)binlog日志恢復(fù)數(shù)據(jù)詳解
- mysql5.7使用binlog 恢復(fù)數(shù)據(jù)的方法
- MySQL通過(guò)binlog恢復(fù)數(shù)據(jù)
- mysql8.0無(wú)備份通過(guò)idb文件恢復(fù)數(shù)據(jù)的方法、idb文件修復(fù)和tablespace?id不一致處理
相關(guān)文章
云服務(wù)器安裝mysql的實(shí)現(xiàn)步驟
在當(dāng)前的互聯(lián)網(wǎng)時(shí)代,云計(jì)算已經(jīng)成為重要的平臺(tái)支撐,本文就來(lái)介紹一下云服務(wù)器安裝mysql的實(shí)現(xiàn)步驟,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01Mysql 5.6.37 winx64安裝雙版本mysql筆記記錄
機(jī)器上現(xiàn)在已經(jīng)存在5.0版本MySQL的情況下裝一個(gè)最新版的mysql,下文通過(guò)實(shí)例代碼給大家介紹Mysql 5.6.37 winx64安裝雙版本mysql筆記記錄,感興趣的朋友一起看看吧2017-07-07mysql定時(shí)刪除過(guò)期數(shù)據(jù)記錄的簡(jiǎn)單方法
今天小編就為大家分享一篇mysql定時(shí)刪除過(guò)期數(shù)據(jù)記錄的簡(jiǎn)單方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-08-08MySQL數(shù)據(jù)庫(kù)遠(yuǎn)程連接開啟方法
有時(shí)候需要遠(yuǎn)程連接mysql數(shù)據(jù)庫(kù),默認(rèn)是不可以的,大家可以參考下面的方法,解決下。2010-08-08