數(shù)據(jù)庫恢復(fù)不了? 不存在的!
工作中大家經(jīng)常會(huì)用到存儲(chǔ)服務(wù),比如mysql、mongo、redis等,有DBA的話還好,能幫我們管理維護(hù),定期備份等,但是我們往往自己在開發(fā)工具平臺(tái)時(shí)自己來搞數(shù)據(jù)庫,就忽略了定時(shí)備份,留下了安全隱患。果不其然,最近收到了團(tuán)隊(duì)小伙伴的求助,服務(wù)器掛了,重啟后mysql服務(wù)起不來了。關(guān)鍵是沒有備份!!
經(jīng)過一番折騰后將處理過程和踩的坑總結(jié)出來,供大家參考。MySQL crash 或者 MySQL 數(shù)據(jù)庫服務(wù)器 crash 會(huì)導(dǎo)致各種各樣的問題 ,比如日志損壞、數(shù)據(jù)文件損壞等等,本案例就是其中的一種,細(xì)心從日志中找的相關(guān)錯(cuò)誤提示,逐步解決即可。首先在出現(xiàn)問題的A機(jī)器啟動(dòng)mysql,看下情況。

查看mysql錯(cuò)誤日志,找找原因
從日志內(nèi)容分析來看,數(shù)據(jù)庫在機(jī)器crash 導(dǎo)致文件損壞,重啟之后無法正常恢復(fù),更無法正常對(duì)外提供服務(wù)。這里采用非常規(guī)手段,首先修改innodb_force_recovery參數(shù),使mysqld跳過恢復(fù)步驟,再將mysqld 啟動(dòng),把數(shù)據(jù)導(dǎo)出來,然后重新創(chuàng)建數(shù)據(jù)庫。
先來普及一下知識(shí)點(diǎn):
innodb_force_recovery可以設(shè)置為1-6,默認(rèn)是0,大的數(shù)字包含前面所有數(shù)字的影響。
1. (SRV_FORCE_IGNORE_CORRUPT):忽略檢查到的損壞頁。
2. (SRV_FORCE_NO_BACKGROUND):阻止主線程的運(yùn)行,如主線程需要執(zhí)行full purge操作,會(huì)導(dǎo)致crash。
3. (SRV_FORCE_NO_TRX_UNDO):不執(zhí)行事務(wù)回滾操作。
4. (SRV_FORCE_NO_IBUF_MERGE):不執(zhí)行插入緩沖的合并操作。
5. (SRV_FORCE_NO_UNDO_LOG_SCAN):不查看重做日志,InnoDB存儲(chǔ)引擎會(huì)將未提交的事務(wù)視為已提交。
6. (SRV_FORCE_NO_LOG_REDO):不執(zhí)行前滾的操作。
注意當(dāng)設(shè)置參數(shù)值大于0后,可以對(duì)表進(jìn)行select,create,drop操作,但insert,update、 delete這類操作是不允許的。
將/etc/my.cnf下innodb_force_recovery值修改為4后,啟動(dòng)mysql成功

馬上導(dǎo)出數(shù)據(jù)
- /usr/local/mysql/bin/mysqldump -uroot -h localhost -P 3306 -p --default-character-set=latin1 --add-drop-database --lock-tables --single-transaction -q --triggers -A --result-file=/home/fuhaitao/3306.sql
導(dǎo)出成功后找一臺(tái)B機(jī)器,在mysql實(shí)例里導(dǎo)入這個(gè)sql文件。
- mysql -uroot -p -S /tmp/mysql3333.sock --default-character-set=latin1 < 3306.sql
大功告成,馬上去看下數(shù)據(jù)是否正常

悲催。。。亂碼,查看mysql編碼方式

編碼是utf8,可是我在A機(jī)器導(dǎo)出的時(shí)候指定了字符集為latin1,所以修改編碼為L(zhǎng)atin1看下

在查看下數(shù)據(jù)還是亂碼么

不行,說明導(dǎo)入的數(shù)據(jù)編碼與數(shù)據(jù)庫的編碼不一致,而且發(fā)現(xiàn)由于機(jī)器使用人員較多,每個(gè)數(shù)據(jù)庫編碼都不一致,有utf8的有l(wèi)atin1的,那么只能挨個(gè)庫來導(dǎo)了。
回到A機(jī)器將剛才是亂碼的database指定utf8編碼導(dǎo)出
將sql文件傳到B機(jī)器

在B機(jī)器上進(jìn)行導(dǎo)入

執(zhí)行后在查看下數(shù)據(jù)是否正常

歐耶,成功。再將A機(jī)器mysql停掉,修改/etc/my.cnf 里的innodb_force_recovery值改為0。經(jīng)過一番折騰,終于把問題解決了,恢復(fù)了5年的數(shù)據(jù)。
***給大家提幾點(diǎn)建議:
1. 如果公司有DBA團(tuán)隊(duì),盡量使用DBA團(tuán)隊(duì)的存儲(chǔ)服務(wù),他們能夠提供專業(yè)的支持。
2. 數(shù)據(jù)庫要做定時(shí)備份,避免特殊情況發(fā)生導(dǎo)致文件損壞,數(shù)據(jù)丟失。
3. 導(dǎo)入數(shù)據(jù)時(shí)要查看編碼方式,保證數(shù)據(jù)庫、數(shù)據(jù)文件、編輯器等編碼方式統(tǒng)一。


























