MySQL資料恢復的九把瑞士軍刀

2021-09-23 16:56:09 字數 4116 閱讀 7608

作者介紹

李輝,

注:高危操作請勿在沒有測試的情況下,直接在生產環境使用。

工具一:完全備份+binlog

恢復資料最常見的做法,只要有這兩樣東西,無論是誤操作還是資料庫損壞等,都能恢復資料到指定的時間節點,能覆蓋大多數的恢復場景,也是dba手中最重要的資產。恢復方法比較簡單這裡就不過多贅述了。

工具二:業務邏輯反推恢復update誤操作

這種方法適合做了誤操作但停機會造成更大影響的場景,通過邏輯反推可以迅速恢復資料到正常狀態。下面我們以使用者充值表為例,來看看如何恢復誤操作。

充值狀態說明:0未充值,1已充值,2充值失敗,3充值異常。

示例1:

某開發在處理使用者充值故障時漏掉了使用者id,導致大面積的使用者充值狀態被篡改。由於此表中有last_update_time欄位,所以我們可以根據最後修改時間恢復這次的誤操作。

示例2:

某開發在處理使用者充值狀態時,漏掉了where條件,導致全表被更新。

執行時丟失了where條件,此時就要根據其它表中記錄的使用者最後的充值status來進行恢復了,比如使用者充值歷史表,先從使用者充值歷史表中取得使用者最後一次充值的記錄,分析此次充值的status,恢復到使用者充值表即可。這種恢復方法和業務邏輯密切相關。

從這裡我們也可以看出此方法並不是很嚴謹,比較適合小規模的恢復。

工具三:mysql flashback

最早的相關資料是在彭立勛的部落格上,隨後他提交給了mariadb,網易等大廠在自己的分支中也實現了該功能。對於仍然在使用官方主流版本的同學來說,業內開源的mysqlbinlog_flashback和binlog2sql這兩個閃回工具是個不錯的選擇,作者已經在github上開源。

其原理主要是由於binlog中會記錄update和delete語句在更改前後的所有狀態(如下圖),對binlog進行解析和處理即可得到原始sql、回滾sql、insert語句等,可以恢復update和delete誤操作。

工具四:innodb_force_recovery

mysql非正常重啟或者磁碟故障等原因可能導致mysql資料檔案損壞,損壞後會導致mysql server無法啟動。如果也沒有備份檔案,可以使用這個選項強制innodb啟動,阻止一些後台操作的執行,從而dump出資料庫中的資料。

innodb_force_recovery可選的值為0-6,預設情況下的值為0,大的數字包含前面所有數字的影響。當設定引數值大於0後,可以對錶進行select,create,drop操作,但insert,update或者delete這類操作是不允許的。

srv_force_ignore_corrupt:忽略檢查到的corrupt頁

srv_force_no_background:阻止主線程的執行,如主線程需要執行full purge操作,會導致crash

srv_force_no_trx_undo:不執行事務回滾操作

srv_force_no_ibuf_merge:不執行插入緩衝的合併操作

srv_force_no_undo_log_scan:不檢視重做日誌,innodb儲存引擎會將未提交的事務視為已提交

srv_force_no_log_redo:不執行前滾的操作。

[mysqld]中加入此引數,嘗試啟動mysql,如果啟動失敗就逐步增加引數的值,直到啟動為止,當然其資料一致性也會越來越差。資料庫啟動後,innodb型別的表只能讀不能寫,此時把表中的資料dump出來,或匯入myisam表裡面,即可恢復損壞的資料。

工具五:discard、import tablespace

這種方法適用於修復frm檔案損壞,或者誤操作、ibd損壞但是有物理備份的情況。修復資料要分兩種情況討論:

這種情況下恢復是比較簡單的,物理備份中的ibd、資料庫中ibd的space id和index id,都是和ibdata檔案中的space id和index id一致的,所以可以直接拿物理備份中的ibd覆蓋資料庫中的ibd。

操作過程:

備份資料庫中的ibd:cp test.ibd test.bak

丟棄資料庫中的ibd:alter table test discard tablespace;

複製物理備份中的ibd到資料庫目錄:cp /bak/test.ibd /data/test/; chown mysql:mysql /data/test/test.ibd

匯入ibd:alter table test import tablespace;

這種情況有點複雜,因為表被drop後元資料中的space id和index id已經被刪除。但space id和index id會留空,不會被新建立的table占用,給我們留下了恢復的機會。只需要重建表結構,然後在ibdata中還原該錶的space id即可,還原過程需要percona recovery tool的協助。

操作過程:

資料庫中重建表:create table test(id int);

關閉資料庫

用物理備份中的ibd覆蓋資料庫中的ibd

使用percona recovery tool修改ibdata:~/percona-data-recovery-tool-for-innodb-0.5/ibdconnect -o /data/ibdata1 -f /data/test/test.ibd -d test -t test

使用percona recovery tool對ibdata做checksum:~/percona-data-recovery-tool-for-innodb-0.5/innochecksum -f /data/ibdata1

重複執行執行步驟6,直到沒有任何輸出為止

啟動mysql

工具六:手工修改ibd

這種方法適用於只有ibd檔案和表結構了,frm和ibdata全部損壞的情況。其原理是在新資料庫上建立表,然後修改待恢復的ibd的檔案頭,使之適應新錶的space id和index id,從而讀取出ibd中的資料。

操作過程:

1、新建資料庫,建立需要恢復的資料庫的表結構。

2、使用vim開啟此表的ibd檔案,16進製制檢視。

3、使用vim開啟要恢復的ibd檔案,16進製制檢視

4、修改要恢復的ibd檔案,將紅方框中的值修改的和剛剛建立的新錶的ibd檔案一致。看到後面大段的0000沒,我們只需要修改檔案頭就可以了。00000c0偏移量以後的不用修改。

[root@localhost test]# vim -b tmp.ibd

:%!xxd -r     #一定要先執行這一步

:wq5、把待恢復的ibd檔案覆蓋剛剛建立的新錶的ibd檔案。修改檔案許可權為mysql使用者。

6、重啟mysql,重啟時加上引數innodb_force_recovery。

7、將資料dump出來,找回資料成功。

工具七:extundelete

這個工具是基於linux的檔案恢復工具,可以用來恢復誤刪除的表,對於dml和truncate操作無能為力。其主要原理是在linux檔案系統中,刪除檔案只是刪除了檔案系統的inode資訊,物理檔案仍然在磁碟上,通過此工具即可將誤刪除的檔案恢復正常。當然前提是物理檔案沒有被覆蓋。類似的工具還有ext3grep、debugfs等,不再贅述。

工具八:percona data recovery tool for innodb

這個工具是percona公司開發的一款innodb資料恢復工具,目前已經停止開發,但是仍然可用。它通過在原始資料檔案(ibd) 中直接提取表的行記錄,實現我們從損壞的表恢復資料的目的。要完成這類恢復,前提是要知道待恢復的表結構。percona data recovery tool for innodb直接讀取innodb的物理頁,按照我們給出的表定義,把資料恢復成類csv檔案。恢復後的資料可能包含正確的行記錄,也可能包含不正確的行記錄,並且拿到的資料比較亂,需要做進一步的處理才能匯入到資料庫中。這個辦法是沒有辦法中的辦法了,不得已而為之,希望大家都不會用到這個工具。

原文發布時間為:

2017-04-26

mysql的資料備份和恢復

一,資料備份 mysqldump是mysql提供的乙個很有用的資料庫備份工具。mysqldump執行時,可以將資料庫備份成乙個文字檔案,該檔案中實際包括了多個create和insert語句,使用這些語句 可以重新建立表和插入語句。mysqldump u user h host ppassword d...

MYSQL資料的備份與恢復

mysql資料的備份與恢復 1 sql資料匯入匯出 實驗內容 1 使用sql語句將 etc passwd檔案匯入userdb庫userlist表,並給每條記錄新增自動編號。2 將userdb庫userlist表中uid小於100的前10條記錄匯出,存為 dbak ulist.txt檔案。實驗實現 1...

MySQL 資料的備份與恢復

1 從物理與邏輯的角度 物理備份分為 離線備份 冷備份 和 聯機備份 熱備份 冷備份 是在關閉資料庫的時候進行 熱備份 資料庫處於執行狀態,依賴於資料庫的日誌檔案 2 從資料庫的備份策略角度 優點 備份與恢復操作簡單方便 缺點 資料存在大量的重複 占用大量的備份空間 備份與恢復時間長 優點 只需備份...