close
2009年6月19日,星期五接近中午的時候,一通電話聲劃破公司的寂靜。neo掛上電話後,只跟我說了一句:
"客戶說,訂單資料表被清空了!"
彷彿晴天霹靂一般的愣了好幾秒。不過因為該客戶網站已經在上線正常運作,在愣下去會越來越麻煩,因此便跟Jace跟neo緊急討論了處理方法。
先確認幾個要點:

1.最新一份完整備份資料庫資料夾檔案的建立時間 - db_back.tar.gz
2.mysql當初有開啟紀錄binlog的功能,可以透過dump出所有語法來還原訂單資料表
3.請客戶在適當時間點將網站換上維護公告避免新的資料持續進來
4.查看biglog中是否有TRUNCATE TABLE的指令並確認資料要復原到那個時間點

OK,先連到資料庫主機查看binlog資料。一般位置會放在 /var/log/mysql 下,檔名大概就長的像mysql-bin.003597這樣,會隨著檔案紀錄的大小自動產生新的檔案。
依據客戶打電話來通知的時間點比對binlog檔的建立時間開啟檔案,來搜尋TRUNCATE TABLE字樣。真的被找到了....確認該指令的時間點(ENDDATATIME)後,再確認db_back.rar的檔案建立時間點(STARTDATATIME)後,將這段時間的binlog檔案一一匯出成sql檔,指令如下:

mysqlbinlog mysql-bin.003598 | grep tablename > /tmp/binlog-dump-01.sql

我們透過mysqlbinlog指令抓取mysql-bin.003598中訂單資料表的指令後匯出到binlog-dump-01.sql這個檔案。待檔案都確認匯出後,把db_back.tar.gz解壓縮,然後新建一個資料庫(NEWDB), 之後停止mysql服務。再來把解壓縮出來資料庫檔案搬到剛才新建的資料庫在linux上的資料夾(/var/lib/mysql/NEWDB),然後變更檔案權限為660及擁有者為mysql,指令如下:

chmod 660 -R * 
chown mysql:mysql -R *

確認權限無誤後開啟mysql服務。此時記得在NEWDB中把訂單資料表先複製一份出來,以免待會使用biglog匯出的sql檔匯入時如果有問題又要重建資料表。再來就是把biglog匯出的sql檔匯入,指令如下:

mysql -u dauserid -p  --default-character-set=utf8  NEWDB< binlog-dump-01.sql

按下enter後輸入該db user的密碼後就開始跑sql指令。待所有sql檔都匯入後,查看新建的資料庫中訂單資料表的資料格式是否無誤。
因為正式資料庫中訂單資料表從被TRUNCATE後還是有一些訂單資料產生,而這些訂單的自動編號欄位從1開始重新編號,所以要做特別處理。將這些資料先匯出sql檔(order.sql)後,將該訂單資料表清空,然後再次停掉mysql服務。再將我們在NEWDB處理好的訂單資料庫檔案複製到正式資料庫的linux資料夾下,同樣的變更檔案權限為660及擁有者為mysql,再把mysql服務開啟。然後開啟我們剛剛匯出的order.sql,將自動編號的欄位移除,然後把該sql檔匯入到正式資料庫的訂單資料表。此時這些後來新增的訂單資料就會從還原的訂單資料後自動編號下去,到此訂單資料表已還原處理完畢。後續就是通知客戶訂單資料表已還原,並可以把維護公告拿掉恢復網站運作了。

後記

上面描述的過程其實在當時處理時並非這麼順利,一下子遇到將備份資料庫檔案複製到新建資料庫時發生硬碟空間滿了,只好把檔案先刪除再把復原動作移到另一台主機去做;再來在抓取復原資料的起始點也耗費了很多時間,因為一個正在運作網站的資料庫存取指令真的多的可怕,光過濾也耗費了很多時間跟精力。所以在此建議大家,phpmyadmin雖然是一套對mysql操作上很方便的工具,但相對方便來說,任何對資料庫的操作就更應該小心,特別是清空資料庫的動作更是要注意。所以如果在不確定自己的精神狀態是非常好的情況下,還是先不要開啟phpmyadmin來操作以防萬一。切記切記...
arrow
arrow
    全站熱搜

    山村有祐 發表在 痞客邦 留言(0) 人氣()