關於MySql數據庫誤操作數據找回的辦法


  先講個事,前段時間,系統長時間不用的一個功能被開放出來了,想當然的我沒有在測試平台上測試,直接操作了正式系統(的確是我不嚴謹),導致好多數據異常,頁面展示錯亂了。於是我想到的第一個就是進行備份還原。項目進行了7天的備份,每天凌晨自動備份,但是凌晨到現在的數據就會丟失了,這可是重大問題啊。我頓時慌了,於是只能尋求DBA的幫助。這邊省略五百字。。。

  最后問題解決了,讓我對數據恢復產生了興趣,聽DBA講用的方法是Flashback閃回工具,也簡單,於是我也自學了一下,這邊做個介紹。

  flashback可以把數據庫恢復到以前某個時間點(或者說某個binlog的某個pos)。比如忘了帶where條件的update、delete操作,傳統的恢復方式是利用全備+二進制日志前滾進行恢復,相比於傳統的全備+增備,flashback顯然更為快速、簡單。這里有個注意點,DDL語句是不支持進行flashback的,謹慎操作。

  先講講所謂的閃回是什么意思,了解他的原理是什么。

  其實很簡單,相當於回滾,MySQL的binlog以event的形式,記錄了MySQL中所有的變更情況,利用binlog我們就能夠重現所記錄的所有操作。flashback工具(-B 參數)可對rows格式的binlog可以進行逆向操作,將已執行的delete語句反向生成insert語句,將update語句生成反向update語句,將insert語句反向生成delete語句。這里提一句,binlog是有三種格式的:

  • statement,基於SQL語句的模式,一般來說生成的binlog尺寸較小,但是某些不確定性SQL語句或函數在復制過程可能導致數據不一致甚至出錯;
  • row,基於數據行的模式,記錄的是數據行的完整變化。相對更安全,推薦使用(但通常生成的binlog會比其他兩種模式大很多);
  • mixed,混合模式,可以根據情況自動選用statement抑或row模式;這個模式下也可能造成主從數據不一致。它屬於MySQL 5.1版本時期的過渡方案,已不推薦使用了。

  注意:使用mysqlbinlog flashback 工具必須設置:binlog_format = row。如果誤操作的事務是由多個event組成的,那么必須將整個事務倒序恢復,即從最后一個event恢復到第一個event。

  使用方法:

  第一步:安裝flashback

  MySQL本身是不自帶flashback的,我們需要進行自己安裝。下載地址:https://pan.baidu.com/s/1U33OO79RjBMJPSi0dDpKdg

  將mysqlbinlog文件移至mysql安裝路徑的bin目錄下,執行mysqlbinlog --help(自行解決報錯),無任何報錯后再執行mysqlbinlog -V,看是否mysql是否版本發生了變化,且多了一個 -B 參數,這樣就裝完了。

  第二步:測試效果

  隨便建一張表,比如叫frame_ou

  create table frame_ou(

    ouguid  varchar(50) not null,

    ouname varchar(20),

    oulevel  int(5)

  )

  我們往里面插入一條數據,insert into frame_ou values('111','組織部',1);

  看下binlog里面,可以看到這句插入語句mysqlbinlog -vv mysql-bin.000004 

1 ### INSERT INTO `test`.`frame_ou`
2 ### SET
3 ###   @ouguid=111 /* VARSTRING(50) meta=50 nullable=0 is_null=0  */
4 ###   @ouname='組織部' /* VARSTRING(50) meta=20 nullable=1 is_null=0 */
5 ###   @oulevel=1 /* SHORTINT meta=0 nullable=1 is_null=0 */

  然后執行下flashback   mysqlbinlog -vv mysql-bin.000004 -B,然后就會發現

### DELETE FROM `test`.`frame_ou`
### WHERE
###   @ouguid=111 /* VARSTRING(50) meta=50 nullable=0 is_null=0  */
###   @ouname='組織部' /* VARSTRING(50) meta=20 nullable=1 is_null=0 */
###   @oulevel=1 /* SHORTINT meta=0 nullable=1 is_null=0 */

  同理,delete操作將會被轉換為insert,update被轉換為反向的update;若在一個事務中既有insert、update、delete語句,通過使用-B參數后,不僅三種DML語句完成了逆向轉換,並且語句順序也會發生顛倒。

在binlog中找到誤操作的pos變化區間后,使用mysqlbinlog -B 恢復:

# mysqlbinlog -B --start-position=431 --stop-position=509 mysql-bin.000004 | mysql -uroot -p

  注意事項:

  1)        binlog_format=row

  2)        只支持insert、update、delete

  3)        不支持drop 、truncate、alter等DDL語句


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM