自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

從刪庫到跑路or恢復,記一次MySQL數(shù)據(jù)庫文件損壞恢復經(jīng)歷

數(shù)據(jù)庫 MySQL
這是工作7年來出的最大一次事故,去年給自己定的一個目標今年寫12篇有質(zhì)量的文章反饋給互聯(lián)網(wǎng),都快過半年了一篇還沒有寫,沒想到第一篇竟然是以這種方式書寫的。 不知道這篇算不算是有質(zhì)量,希望能幫到更多的人。

從刪庫到跑路or恢復,記一次MySQL數(shù)據(jù)庫文件損壞恢復經(jīng)歷

一、 前言

2018年5月28日,北京晴有輕度沙塵暴。 坐上公交車走在上班的路上,想起老羅經(jīng)常說起的一句話:想成盛田昭夫時代的索尼,想成喬布斯時代的蘋果,于是繼續(xù)研讀著 《日本制造:盛田昭夫的日式經(jīng)營學》。

到了人大西門在西區(qū)食堂吃了個早餐,穿過人民大學很快就來到了公司。坐在工位上打開電腦登上QQ,不一會運營的CC的頭像就開始閃動,“mooc平臺登錄不了”,“你看看”。又一會領導的頭像開始閃動,“xxx說慕課平臺不能登錄了”。 額… 這事都驚動領導了?

二、 排查問題

打開chrome瀏覽器開始預覽,等了好久代理服務器才反饋。

  1. Time out! 

使用 SecureCRT 連接了一下服務器,首先重新啟動了一下Nginx代理服務器。 

  1. service nignx stop // 關閉Nginx服務  
  2. service nginx start // 開啟Nginx服務 

去前臺刷新了幾下沒有恢復。 那就在重啟一下php吧,于是就: 

  1. service php-fpm stop // 關閉PHP服務  
  2. service php-fpm start // 開啟PHP服務 

又去前臺試了試還是沒有恢復。(有人會問為什么不直接用 service xxx restart 來重啟各服務呢? 我也不知道為什么,個人愛好吧?。┠侵挥幸环N可能數(shù)據(jù)庫出問題了。

打開 Navicat 連接了一下數(shù)據(jù)庫,發(fā)現(xiàn)可以正常連接而且可以看到所有的表,隨便打開了一張表能看到里面的數(shù)據(jù),但是彈出了一個錯誤的提示。 

  1. Got error 28 from storage engine 

大概是這個錯誤提示,當時也沒在意,心想反正提示錯誤了那就重啟一下物理服務器吧,這里是物理服務器?。?!隨后執(zhí)行了這個命令(為什么不直接重啟MySQL服務呢? 事后想了想我也不知道為什么。 而且如果當時注意看看這個錯誤,是因為磁盤空間問題引起的,也許后面就不會有那么多驚心動魄了?。?nbsp;

  1. reboot // 重啟物理服務器 

執(zhí)行完以后所有的服務都正常關閉了,只有Mysql數(shù)據(jù)庫服務。 

  1. Shutdown MySQL ………………………………………………. 

引號已經(jīng)5排了,實在是等不下去了。 斷電!?。。∕ySQL沒有安全關閉,直接斷電會出問題的?。。。?/p>

三、 恢復進程

等了一會,物理服務器啟動起來了。一切的應用服務都正常啟動了,只看到在啟動MySQL數(shù)據(jù)庫的時候出現(xiàn)了。 

  1. The server quit without updating pid file (/var/lib/mysql/localhost.localdomain.pid) 

等到全部服務加載完成以后手動又進行了一次MySQL數(shù)據(jù)庫啟動: 

  1. service mysql start 

依然報前面那樣的錯誤,此時心里開始緊張了起來。 Google了一下這個錯誤,網(wǎng)上提供了幾種解決的方案:

1、 Mysql權限問題 

  1. chown -R mysql:mysql /var/lib/mysql/*  
  2. chmod -R 660 /var/lib/mysql/* 

2、 Mysql 服務已開啟 

  1. ps -ef|grep mysqld // 查看是否有mysqld進程  
  2. kill -9 進程號 // 強制殺死進程 

3、 殘余數(shù)據(jù)影響了Mysql服務的啟動

    刪除數(shù)據(jù)庫目錄(我的數(shù)據(jù)庫目錄為rpm安裝默認目錄:/var/lib/mysql)下的 mysql-bin.index 文件

4、 Mysql配置文件(默認為:/etc/my.cnf)

    配置文件里面沒有配置數(shù)據(jù)庫目錄,這個問題一般在剛安裝MySQL時候會出現(xiàn)

5、 skip-federated字段問題

    MySQL配置文件注釋掉skip-federated字段

6、 selinux的問題

    centos6.8以上默認會開啟selinux服務,加強版軍用級防火墻。為了查問題可以直接關掉

  1. /usr/sbin/setenforce 0 

以上解決方案全部都已經(jīng)使用過了,都沒有解決問題,依然開啟服務會報錯。 此時的心開始涼了。

回頭看了看往期的備份,xxxx_20171208.sql。 都快2018年6月份了,我的上次備份竟然是17年12月份的,半年了!都半年沒備份過了! (我視乎隱約的感覺前段時間是有備份的,備份的服務器硬盤好像被我清理了)。

進入到數(shù)據(jù)庫目錄下,看到了除了上述說的 mysql-bin.index 文件以外還有其他的幾個文件:mysql-bin.~rec~ 、 ib_logfile1、 ib_logfile0、 ibdata1 想了想是不是這幾個也是一些殘余文件,全部刪了試試。 嘗試把這幾個文件轉(zhuǎn)移到了其他的目錄(使用的mv命令)模擬刪除效果,同時還相當于備份。 

  1. service mysql start 

竟然MySQL數(shù)據(jù)庫服務正常啟動了! 心里的喜悅涌了上來,趕緊使用Navicat連接一下看看,能夠正常連接,看到了數(shù)據(jù)庫。 打開數(shù)據(jù)庫以后所有的表都沒有了! 此時心又酸了起來。 一轉(zhuǎn)眼11:30了,時間過的可真快啊,同事叫著一起吃飯,此時的我已經(jīng)全無吃飯的心情了。

恢復表結(jié)構(gòu)

把剛才移走的幾個文件又恢復到了原目錄里,既然恢復MySQL進程現(xiàn)在沒什么希望了,那就想辦法恢復數(shù)據(jù)吧。 進入到數(shù)據(jù)庫目錄(/var/lib/mysql)下找到了我的數(shù)據(jù)庫名字以目錄的形式存放。 進去該目錄以后發(fā)現(xiàn)里面都是以擴展名為:xxxx表.frm文件,這些不都是我的數(shù)據(jù)庫表嗎? 里面是不是就存放了所有的數(shù)據(jù)? 是不是直接拿這些文件就可以恢復數(shù)據(jù)呢?Google了一下,果然有這方面的文章,大致說: “frm可以恢復表結(jié)構(gòu),同時InnoDB數(shù)據(jù)庫引擎和MyISAM數(shù)據(jù)庫引擎恢復的方式不一樣”。

1、 InnoDB數(shù)據(jù)庫引擎

  1. 在一個正常的MySQL數(shù)據(jù)庫服務器(new_server)下建立數(shù)據(jù)庫(new_db),該數(shù)據(jù)庫的名稱和異常服務器(old_server)數(shù)據(jù)庫(old_db)保持一致。
  2. 在new_db數(shù)據(jù)庫中建立一張表與old_db的表名稱(t_user)一致。
  3. 將new_server服務器的MySQL數(shù)據(jù)庫服務關閉。
  4. 從old_server服務器下old_db的數(shù)據(jù)庫目錄下復制t_user.frm文件到new_server服務器下new_db的數(shù)據(jù)庫目錄下替換t_user.frm文件。
  5. 開啟new_server服務器的MySQL數(shù)據(jù)庫服務。
  6. 使用連接工具連接new_server就可以看到new_db下的表及表結(jié)構(gòu)。

2、 MyISAM數(shù)據(jù)庫引擎

    其他和InnoDB數(shù)據(jù)庫引擎操作基本一致,只是在new_server服務器下new_db的數(shù)據(jù)庫目錄下創(chuàng)建兩個空的文件:t_user.MYD 和 t_user.MYI。

我使用的數(shù)據(jù)庫為InnoDB引擎,無奈的我以上兩種方法都使用了,沒有恢復任何表結(jié)構(gòu)更沒有數(shù)據(jù),也許可能是我操作有問題吧。 此時看到了目錄下有一個文件: ibdata1 Google了一下,可以和xxx.frm配合使用,又一次將new_server服務器的MySQL數(shù)據(jù)庫服務關閉。 直接把old_server服務器下old_db的數(shù)據(jù)庫目錄下復制ibdata1文件到new_server服務器下new_db的數(shù)據(jù)庫目錄下替換ibdata1文件。 

  1. service mysql start 

新的服務器也出現(xiàn)了這樣的錯誤,導致錯誤的很大原因可能是ibdata1文件損壞引起的。

今天北京的天氣已經(jīng)達到了35攝氏度,但此時我的心已經(jīng)涼了一半了,雖然沒有按時備份數(shù)據(jù)及服務器異常崩潰造成數(shù)據(jù)丟失比直接刪庫的責任小了點,但是也辦法向公司交代,真的需要開始準備 “離職申請” 了嗎?

binlog日志

打開微信

    我:你們公司用的是什么數(shù)據(jù)庫,是MySQL嗎

    好友LZ:是的

    我:公司的MySQL壞了,啟動不了了; 數(shù)據(jù)沒有備份; 有什么好辦法把數(shù)據(jù)拿回來嗎

    好友LZ:你們之前數(shù)據(jù)的binlog還有嗎;通過這個應該可以恢復

    我:都有

    好友LZ:我也沒弄過數(shù)據(jù)恢復,都是DBA搞,感覺應該可以的;你先查查看網(wǎng)上有沒有解決方案,我這會在上線。

    我:嗯

本來想說:“你能不能問問好友LZ你們DBA遇到過這種情況嗎,幫忙給個方案”;最后還是沒有好意思開出口。 不過binlog這個名字讓我突然想起了數(shù)據(jù)庫目錄(/var/lib/mysql)下面幾個較大的文件。

這十幾個文件就是binlog日志文件,每臺服務器上面的個數(shù)應該不一樣,這個文件只有每次重啟MySQL服務或者刷新日志(MySQL命令:show master logs)的時候才會新增一個。看了一下我最近的幾個文件,2018年1月16、 2018年3月18、 2018年4月18、 2018年5月28這幾個時間點產(chǎn)生了新的文件,說明MySQL服務器這幾個日期都進行過關閉又開啟的操作。

binlog使用:

    binlog文件簡介(網(wǎng)上摘抄)

    MySQL的二進制日志可以說是MySQL最重要的日志了,它記錄了所有的DDL和DML(除了數(shù)據(jù)查詢語句)語句,以事件形式記錄,還包含語句所執(zhí)行的消耗的時間,MySQL的二進制日志是事務安全型的。

    binlog作用(網(wǎng)上摘抄)

    MySQL Replication在Master端開啟binlog,Mster把它的二進制日志傳遞給slaves來達到master-slave數(shù)據(jù)一致的目的。

    數(shù)據(jù)恢復,通過使用mysqlbinlog工具來使恢復數(shù)據(jù)。

使用binlog恢復數(shù)據(jù)之前需要確定MySQL是否開啟binlog日志:

  1. show variables like 'log_%'

狀態(tài) OFF 為未開啟,狀態(tài) ON 表示已開啟。

可以通過MySQL配置文件(默認路徑:/etc/my.cnf)開啟或關閉binlog日志。 

  1. vi /etc/my.cnf 

使用加上#可以關閉,去掉開啟。 修改后需要重啟MySQL服務(service mysql restart)才可以生效。

恢復數(shù)據(jù)(binlog日志方式)

初試mysqlbinlog工具

看到上面的那么多mysql-bin文件,很顯然使用centos6.5下rpm方式安裝的MySQL默認是打開binlog日志的。 這時我們就需要用到MySQL的 mysqlbinlog 工具,想使用它首先需要確保已經(jīng)安裝MySQL服務,然后我們需要找到它的位置。

  1. find / -name mysql 

    2 表示為MySQL可執(zhí)行文件的目錄

    3 表示為MySQL的數(shù)據(jù)庫目錄

那我們先簡單的使用一下:

  1. cd /var/lib/mysql  
  2. mysqlbinlog mysql-bin.000001 > mysql-bin.000001.sql 

很顯然我在使用mysqlbinlog的時候是,直接執(zhí)行的mysqlbinlog命令,前面并沒有增加任何路徑。 因為默認centos系統(tǒng)會將/usr/bin這個目錄配置到環(huán)境標量中,若我們使用的是rpm方式安裝的MySQL,默認是安裝到/usr/bin目錄下的。 可以直接在任何路徑下使用/usr/bin目錄里的文件。 執(zhí)行完上面的語句后會發(fā)現(xiàn)在當前目錄生成一個mysql-bin.000001.sql的文件, 打開文件可以看到很多sql語句。

對于我當前的情況來看并不需要把所有的binlog都處理一遍,上面提到我上次的備份是在2017年12月8日的時候(xxxx_20171208.sql)因此我只需要從 mysql-bin.000009 這個binlog文件開始就可以了。

首先我在另外一臺服務器上面重新搭建了一個MySQL服務,把mysql-bin.000009以后的幾個binlog都拷貝到了這臺新的服務器上面去。(服務器出現(xiàn)任何問題,建議不要對該服務器做任何操作,換一臺新的電腦或服務來處理,為了保護數(shù)據(jù)的完整性!)

使用備份文件恢復數(shù)據(jù)

在新的MySQL上面建了一個和以前一樣名稱的數(shù)據(jù)庫。

    mysql -u數(shù)據(jù)庫用戶名 -p數(shù)據(jù)庫密碼 數(shù)據(jù)庫名稱 --default-character-set=utf8 < xxxx_20171208.sql

    例:mysql -uroot -proot xxxx --default-character-set=utf8 < xxxx_20171208.sql

使用binlog恢復數(shù)據(jù)

這時數(shù)據(jù)庫有了,數(shù)據(jù)表及表結(jié)構(gòu)也有了,那就開始恢復數(shù)據(jù)吧。   

  1. mysqlbinlog mysql-bin.000009 | mysql -uroot -proot 

回車馬上就出錯了,遇到了兩種錯誤,一種是PRIMARY的錯誤,一種是找不到記錄的錯誤。 mysqlbinlog在執(zhí)行mysql-bin.000009文件里的插入語句時出錯了。 看了一下mysql-bin.000009文件的創(chuàng)建時間是2017年11月12日,我的備份文件是2017年12月8日,他們兩個時間差了二十幾天,執(zhí)行上面恢復語句肯定會出現(xiàn)重復插入的問題,數(shù)據(jù)庫里的某些表是由PRIMARY KEY的約束的,所以會導致PRIMARY錯誤。 這時我們需要用到mysqlbinlog的參數(shù): start-datetime 和 end-datetime,顧名思義一個是開始時間一個是結(jié)束時間。

  1. mysqlbinlog --start-datetime="2017-12-08 10:00:00" mysql-bin.000009 | mysql -uroot -proot 

看了一下我備份的xxxx_20171208.sql大致是2017年12月8日的10左右,沒有添加 end-datetime 參數(shù)的話默認為該binglog文件下的最后一個時間點。 執(zhí)行了以后報了一個找不到記錄的異常。 應該是執(zhí)行刪除或更新語句的時候沒有找到某條記錄,時間還是不對。 于是我就查看了數(shù)據(jù)庫的日志表,最后的時間是2017年12月8日9點32分41秒,又執(zhí)行了一次。 

  1. mysqlbinlog --start-datetime="2017-12-08 09:32:41" mysql-bin.000009 | mysql -uroot -proot 

依然報錯,那怎么辦呢,難道這個方法不行? 

  1. mysqlbinlog mysql-bin.000009 > mysql-bin.000009.sql 

此時打開mysql-bin.000009.sql里面擁有大量的sql語句,發(fā)現(xiàn)好多條sql語句在這個時間點下。 看來使用參數(shù)來控制行不通。 還好mysqlbinlog工具給我們提供了另外兩個參數(shù)start-position 和 end-position

修改了一下命令: 

  1. mysqlbinlog --start-position="123456" mysql-bin.000009 | mysql -uroot -proot 

果然一切都正常了,執(zhí)行這個命令需要很久,它要把你這段時間所有的增加、刪除、更新都執(zhí)行一遍。 這里可能還會遇到一個問題,我的這個MySQL服務器里面這有一個數(shù)據(jù)庫,MySQL的binlog文件記錄的是所有數(shù)據(jù)庫的增加、刪除、更新記錄,那怎樣只針對某個數(shù)據(jù)庫來操作呢? 這時我們需要用到mysqlbinlog的database參數(shù)。

  1. mysqlbinlog --database=xxxx --start-position="123456" mysql-bin.000009 | mysql -uroot -proot 

半年的數(shù)據(jù),就這么一個一個的binlog文件進行處理的,從晚上6點到夜里的12點完成所有文件的恢復,數(shù)據(jù)量不是很大,服務器的性能也不是太高,中間出了點問題,不過都是服務器中斷的問題。 最后把所有的數(shù)據(jù)全部恢復了回來,這心驚肉跳的一天!

這是工作7年來出的最大一次事故,去年給自己定的一個目標今年寫12篇有質(zhì)量的文章反饋給互聯(lián)網(wǎng),都快過半年了一篇還沒有寫,沒想到第一篇竟然是以這種方式書寫的。 不知道這篇算不算是有質(zhì)量,希望能幫到更多的人。

總結(jié)

遇到問題不要盲目,保持清醒的頭腦,找清問題,整理好思路才能更有效的解決問題。 對于數(shù)據(jù)平時不要怕麻煩,注意備份。

備注

我的服務器及各軟件的版本

  • 操作系統(tǒng):** centos6.5
  • MySQL:** 5.5.49
  • 安裝MySQL方式:** rpm 
責任編輯:龐桂玉 來源: OSC李強的個人空間
相關推薦

2018-07-11 10:24:33

數(shù)據(jù)恢復數(shù)據(jù)刪除

2018-02-23 13:41:05

數(shù)據(jù)庫MySQL數(shù)據(jù)恢復

2019-08-20 14:20:19

MySQL數(shù)據(jù)恢復數(shù)據(jù)庫

2020-08-05 11:50:47

刪庫MySQL數(shù)據(jù)庫

2024-03-29 08:08:25

2025-04-17 03:30:00

MySQL數(shù)據(jù)備份

2010-06-09 15:40:59

MySQL數(shù)據(jù)庫文件

2017-03-14 14:09:08

數(shù)據(jù)庫Oracle備份

2020-08-25 17:30:32

MySQL數(shù)據(jù)庫數(shù)據(jù)恢復

2018-12-06 16:25:39

數(shù)據(jù)庫服務器線程池

2009-03-17 16:00:47

Oracle數(shù)據(jù)庫備份

2011-05-20 09:35:24

Oracle數(shù)據(jù)庫恢復備份

2011-03-24 11:14:46

2010-11-30 13:37:02

數(shù)據(jù)庫壓縮

2019-06-12 08:57:43

Oracle數(shù)據(jù)庫恢復

2017-09-11 10:09:59

刪庫DBA淘汰

2019-11-22 08:05:01

數(shù)據(jù)庫mysql分區(qū)

2019-11-18 13:42:55

MySQL數(shù)據(jù)庫遷移

2019-09-11 08:22:57

MySQL數(shù)據(jù)庫遠程登錄

2010-05-28 10:03:33

MySQL數(shù)據(jù)庫
點贊
收藏

51CTO技術棧公眾號