MySQL【Delete誤操作】數據恢復【轉】

来源:http://www.cnblogs.com/ajiangg/archive/2017/12/06/6560333.html
-Advertisement-
Play Games

前言: 操作資料庫時候難免會因為“大意”而誤操作,需要快速恢復的話通過備份來恢復是不太可能的,因為需要還原和binlog差來恢復,等不了,很費時。這裡先說明下因為Delete 操作的恢復方法:主要還是通過binlog來進行恢復,前提是binlog_format必須是Row格式,否則只能通過備份來恢復 ...


前言:
      
操作資料庫時候難免會因為“大意”而誤操作,需要快速恢復的話通過備份來恢復是不太可能的,因為需要還原和binlog差來恢復,等不了,很費時。這裡先說明下因為Delete 操作的恢復方法:主要還是通過binlog來進行恢復,前提是binlog_format必須是Row格式,否則只能通過備份來恢複數據了。
方法:
     條件:開啟Binlog,Format為Row。
     步驟:
1.通過MySQL自帶工具mysqlbinlog 指定導出操作的記錄:

mysqlbinlog --no-defaults --start-datetime='2017-03-16 14:56:00' --stop-datetime='2017-03-16 14:57:00' -vv mysql-bin.000001 > /tmp/restore/binlog.txt

2.數據取出來之後,需要把數據解析反轉,原始數據:

### DELETE FROM test.me_info
### WHERE
###   @1=2165974 /* INT meta=0 nullable=0 is_null=0 */
###   @2='1984:03:17' /* DATE meta=0 nullable=1 is_null=0 */
###   @3=NULL /* DATE meta=765 nullable=1 is_null=1 */
###   @4=2017-03-16 00:00:00 /* DATETIME meta=0 nullable=0 is_null=0 */
###   @5='' /* VARSTRING(765) meta=765 nullable=1 is_null=0 */
###   @6=0 /* TINYINT meta=0 nullable=1 is_null=0 */
###   @7='' /* VARSTRING(765) meta=765 nullable=1 is_null=0 */
###   @8=-1 (4294967295) /* INT meta=0 nullable=1 is_null=0 */
###   @9=0 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
###   @10=NULL /* MEDIUMINT meta=0 nullable=1 is_null=1 */
###   @11=2 /* TINYINT meta=0 nullable=1 is_null=0 */
###   @12=0 /* TINYINT meta=0 nullable=1 is_null=0 */
###   @13='' /* VARSTRING(765) meta=765 nullable=1 is_null=0 */
###   @14='' /* VARSTRING(765) meta=765 nullable=1 is_null=0 */
###   @15=0 /* MEDIUMINT meta=0 nullable=1 is_null=0 */
###   @16=320 /* INT meta=0 nullable=1 is_null=0 */
……………………
……………………
……………………

Row格式的binlog記錄的格式如上面所示,需要做的工作就是吧Delete的操作轉換成Insert操作,發上面的都是有一定規律的,並且需要註意的是:

1、欄位類型 DATETIME 日期。在日誌中保存的格式為 @4=2017-03-16 00:00:00,需要將2017-03-16 00:00:00加上引號。

2、負數。在日誌中保存的格式為 @1=-1 (4294967295), -2(4294967294),-3(4294967293),需要將括弧裡面的數據去掉,只保留@1=-1。

3、轉義字元集。如:'s,\,等。
上面3點清楚之後,可以寫一個腳本(水平有限,在提升中,寫的不好看):

#!/bin/env python
# -*- encoding: utf-8 -*-
#-------------------------------------------------------------------------------
# Name:        restore_insert.py
# Purpose:     通過Binlog恢復Delete誤操作數據
#-------------------------------------------------------------------------------
def read_binlog(file,column_num):
    f=open(file)
    num = '@'+str(column_num)
    while True:
        lines = f.readline()
        if lines.strip()[0:3] == '###':
            lines=lines.split(' ',3)
            if lines[1] == 'DELETE' and lines[2] =='FROM':           #該部分替換Delete為Insert
                lines[1] = "INSERT"
                lines[2] = 'INTO'
                lines[-1] = lines[-1].strip()
            if lines[1].strip() == 'WHERE':
                lines[1] = 'VALUES ('
            if  ''.join(lines).find('@') <> -1 and lines[3].split('=',1)[0] <> num:          #num為列數,要是小於最大的列數,後面均加,
                lines[3] = lines[3].split('=',1)[-1].strip()
                if lines[3].strip('\'').strip().find('\'') <> -1:
                    lines[3] = lines[3].split('/*')[0].strip('\'').strip().strip('\'').replace('\\','\\\\').replace('\'','\\\'')  #這裡過濾掉轉義的字元串
                    lines[3] = '\'' + lines[3] + '\','
                elif lines[3].find('INT meta') <> -1:                #過濾Int類型的欄位為負數後帶的(),正數不受影響
                    lines[3] = lines[3].split('/*')[0].strip()
                    lines[3] = lines[3].split()[0] + ','
                elif lines[3].find('NULL') <> -1:
                    lines[3] = lines[3].split('/*')[0].strip()
                    lines[3] = lines[3] + ','
                else:
                    lines[3] = lines[3].split('/*')[0].strip('\'').strip().strip('\'').replace('\\','\\\\').replace('\'','\\\'')  #這裡過濾掉轉義的字元串
                    lines[3] = '\'' + lines[3].strip('\''' ') + '\','
            if  ''.join(lines).find('@') <> -1 and lines[3].split('=',1)[0] == num:          #num為列數,要是小於最大的列數,後面均加);
                lines[3] = lines[3].split('=',1)[-1].strip()
                if lines[3].find('\'') <> -1: 
                    lines[3] = lines[3].split('/*')[0].strip('\'').strip().strip('\'').replace('\\','\\\\').replace('\'','\\\'')  #同上
                    lines[3] = '\'' + lines[3] + '\');'
                elif lines[3].find('INT meta') <> -1:                #同上
                    lines[3] = lines[3].split('/*')[0].strip()
                    lines[3] = lines[3].split(' ')[0] + ');'
                elif lines[3].find('NULL') <> -1:
                    lines[3] = lines[3].split('/*')[0].strip()
                    lines[3] = lines[3] + ');'
                else:
                    lines[3] = lines[3].split('/*')[0].strip('\'').strip().strip('\'').replace('\\','\\\\').replace('\'','\\\'')  #同上
                    lines[3] = '\'' + lines[3].strip('\''' ') + '\');'
            print ' '.join(lines[1:])
        if lines == '':
            break
if __name__ == '__main__':
    import sys
    read_binlog(sys.argv[1],sys.argv[2])
View Code

執行腳本:方法:python 腳本名 binlog文件 欄位數目

python restore.py binlog.txt 36 > binlog.sql

命令行中的36 表示 需要還原的表的欄位有36個,效果:

INSERT INTO test.me_info
VALUES (
  2123269,
  '1990:11:12',
  NULL,
  2,
  '',
  0,
  '',
  -1,
  0,
  340800,
  1,
  0,
  '',
……
……
  1,
  NULL
);

 最後還原:

mysql test < binlog.sql

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Linux重要目錄,以思維導圖Xmind方式展現,附帶Xmind文件下載地址。 ...
  • @echo off&color 3a&set c=0123456789abcdefghijklmnopqrstuvwxyz title 批量替換文件(文件夾)名 echo. echo 此批處理可批量替換本文件所在文件夾下所有文件的文件名。 echo.echo.&set /p strtemp1= 請輸 ...
  • 企業級緩存系統varnish應用與實戰 環境背景:隨著公司業務快速發展,公司的電子商務平臺已經聚集了很多的忠實粉絲,公司也拿到了投資,這時老闆想通過一場類似雙十一的活動,進行一場大的促銷,屆時會有非常多的粉絲訪問網站,你的總監與市場部門開完會後,確定活動期間會有平常10倍以上的訪問請求,總監要求大幅 ...
  • Innodb中的鎖 共用鎖和排它鎖(Shared and Exclusive Locks) 共用鎖和排它鎖是行級鎖,有兩種類型的行級鎖 共用鎖(s lock)允許持有鎖的事務對行進行讀取操作 排它鎖(x lock)允許持有鎖的事務對行進行更新和刪除操作 事務a在行r上擁有共用鎖,則其他事務可以獲得r ...
  • 1.mongodb下載地址: https://www.mongodb.com/dr/fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-ssl-3.6.0-signed.msi 2.安裝後文件夾結構如下圖所示 2、在D:\MongoDB下新建 ...
  • 對這個游戲我想大家都不陌生 不管新手還是老手都會遇到難題基本上是處於不會玩的狀態下去亂押註又或者是被某某某帶著跟計劃玩一是直接拉你進群讓你去跟計 劃(沒有長期的計 劃跟計劃死的人很多,你也不例外)二是在微 信 群里發神經的亂下註(或許看到別人買什麼你也跟著買,微信群基本都是托) 那該如何對待這個游戲 ...
  • 通常情況下,ETL工程師創建一個Agent Job來周期性地執行Package,Agent底層調用SSISDB的存儲過程(catalog.start_execution)以同步模式來啟動執行實例,這就意味著,我們可以模擬Agent Job的行為,使用TSQL腳本執行Package。SSIS引擎每執行 ...
  • 瞭解事務和鎖 事務:保持邏輯數據一致性與可恢復性,必不可少的利器。 鎖:多用戶訪問同一資料庫資源時,對訪問的先後次序許可權管理的一種機制,沒有他事務或許將會一塌糊塗,不能保證數據的安全正確讀寫。 死鎖:是資料庫性能的重量級殺手之一,而死鎖卻是不同事務之間搶占數據資源造成的。 不懂的聽上去,挺神奇的,懂 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...