例如,名稱為“ziliao.ibd”的數(shù)據(jù)表文件發(fā)生損壞,當(dāng)MySQL數(shù)據(jù)庫(kù)重啟之后,執(zhí)行“select* from ziliao;”之類的命令,對(duì)該數(shù)據(jù)表進(jìn)行查詢 時(shí),會(huì) 顯 示“MySQL server has gone away”等提示信息,說(shuō)明訪問(wèn)連接已經(jīng)斷開(kāi),數(shù)據(jù)庫(kù)實(shí)際上崩潰了,自然無(wú)法從中讀取數(shù)據(jù)。執(zhí)行“vi /etc/my.cnf” 命 令,打開(kāi)MySQL配置文件,在其 中 的“[mysqld]” 節(jié)中 添 加“innodb_force_recovery=1”,表示采用第一種修復(fù)模式。輸入“:wq”保存該文件。執(zhí)行“service mysql restart”命令,重啟MySQL數(shù)據(jù)庫(kù)。
如果直接執(zhí)行“select* from ziliao;”命令,依然無(wú)法順利執(zhí)行。為了可以嘗試讀取該表中前一些行的記錄。例如執(zhí)行“select* from ziliao limit 500”命令,來(lái)讀取其前500行數(shù)據(jù)。當(dāng)讀取成功后,執(zhí)行“create table repairzl(xxx)engine=myisam;”命令,使用MYISAM引擎創(chuàng)建名為“repairzl”的新表,字段結(jié)構(gòu)應(yīng)該和“ziliao”表完全相同,其中的“xxx”表示具體的字段。執(zhí)行“insert into repairzl select *ziliao limit 500;”命令,從“資料”表中讀取前500行數(shù)據(jù),將其導(dǎo)入到“repairzl”表 中。 執(zhí) 行“drop table ziliao;”命令,將“ziliao”表刪除。執(zhí)行“rename table repairzl to ziliao;” 命令,將“repair”表更名為“ziliao”表。
按照上述方法編輯“my.cnf” 文 件, 將“innodb_force_recovery=1”一 行 刪除。 執(zhí) 行“service mysql restart”命令,重啟MySQL數(shù)據(jù)庫(kù)。執(zhí)行“alter table ziliao=innodb;”命令,將數(shù)據(jù)庫(kù)引擎修改為InnoDB。這樣,受損的“ziliao”數(shù)據(jù)表就修復(fù)完成了。注意,對(duì)于數(shù)據(jù)表的修復(fù)是無(wú)法完整無(wú)缺地找回?cái)?shù)據(jù)的,只能是盡可能地讀取并導(dǎo)出數(shù)據(jù)。如果,存在備份或者二進(jìn)制日志的話,那么就可以完整地找回?cái)?shù)據(jù)。如果在數(shù)據(jù)表中部等位置出現(xiàn)損壞,就需要手工逐行進(jìn)行探測(cè),來(lái)發(fā)現(xiàn)大致的損壞位置。
例如,數(shù)據(jù)表中存在1000行記錄,在其中的600行處出現(xiàn)問(wèn)題,可以按照上述方法進(jìn)行修復(fù),現(xiàn)將前599行讀取出來(lái)并導(dǎo)入到新表中。之后再處理之后的記錄行,方法基本相同,所不同的地方在于在導(dǎo)入數(shù)據(jù)時(shí),可以執(zhí)行諸如“insert ignore into repairzl select* from ziliao recno>600;”命令,將行號(hào)大于600之后的數(shù)據(jù)導(dǎo)入進(jìn)來(lái),這里的“recno”字段為行號(hào)。雖然修復(fù)操作可以找回盡可能多的數(shù)據(jù),不過(guò)為了數(shù)據(jù)庫(kù)的安全,最好及時(shí)對(duì)數(shù)據(jù)庫(kù)進(jìn)行備份。有了備份以及二進(jìn)制日志文件,就可以很輕松地將數(shù)據(jù)庫(kù)恢復(fù)到損壞之前的狀態(tài)。