phpmyadmin誤刪表後的恢復過程(心驚膽跳啊)

話說今天不知道是抽風了仍是失魂了,在用phpmyadmin刪除測試數據時,居然將整個表刪除了:php

等程序運行出錯時,纔出現整個表都沒有了,並且以前也沒有備份好!這下蛋疼了,這個但是production服務器,裏面的數據可不能丟啊!
 
服務器是linux的,我不是很熟悉,也不知道mysql裝在哪。
無奈之下,google,發現有很多人也有像我同樣犯傻的一回,可是幾乎沒有看到具體的解決方法(有說用硬盤軟件找回,也有說用二進制文件找回),可是我自己對服務器不大懂,以爲好糾結,那邊又在催說數據怎麼沒有了,還說必定得找回來。
這下我更急了,晚飯都沒心情吃。
 
這時,我找到了一些專門幫人恢復數據的技術人員。
他問了我數據量,數據庫引擎,當我說是‘myisam’時,他來了句:那無解了。。
當時我一會兒懵了。
 
情急之下,我想到了,以前在testing服務器裏面有一個副本數據庫,可是那裏的數據已經有些時日了,根本沒有最新一個月的數據。
這根本沒法解救我!
 
這裏我在phpmyadmin中看到了這個:
 
腦裏出來了google上說的用二進制恢復,就點開看一下。結果大喜!OMG,服務器開通了日誌!
裏面有數據庫的操做日誌,並且仍是sql格式的!!!
我以前沒有接觸過這個東西,但這時它就是個人救命稻草。
我瀏覽了一下,裏面有近一個月的更新記錄,已經足夠了。不過有一個問題,在phpmyadmin裏面看,只能顯示其中一小部分內容,面對10幾w的數據行,想要一個個找出被刪表的數據,太難了。
 
這時,我想到了能夠從服務器中下載這些文件,而後獲得其中的數據。
說幹就幹,我登陸服務器,搜索這些二進制文件:
上圖中紅圈的就是了
 
而後將這些文件一個個導出成能夠閱讀的sql:
這樣將這些二進制文件一個個輸出成了正常的sql文件。
 
這時,就是要從這些文件中找到被刪表相關的數據了,因而我寫了個java程序幫我作這個事情:
package com.nerve.sql.reload;
 
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
 
import org.nerve.util.NumberUtil;
 
/**
 * @project: cloudOffice_swing
 * @file: ReloadWorker.java
 * @package: com.nerve.sql.reload
 * @description:
 *    將二進制日誌導出的文件中相應表的操做記錄提出出來
 * @author: 集成顯卡    1053214511@qq.com
 * @date&time: Jan 23, 2014
 * @change log:
 */
public class ReloadWorker {
    
    public void read(List<String> orgF, String targetF, String table) throws Exception{
        BufferedWriter bw = new BufferedWriter(new FileWriter(targetF, true));
        
        for(String or:orgF){
            BufferedReader br = new BufferedReader(new FileReader(or));
            String t = null;
            String t2 = null;
            table = table.toUpperCase();
            while((t=br.readLine())!=null){
                t2 = t.toUpperCase();
                /*
                 * 若是是update操做,直接提出
                 */
                if(t2.startsWith("UPDATE "+table)){
                    bw.append(t+";\n");
                }
                /*
                 *  若是是insert語句,由於有一些舊服務器的數據
                 *  因此要先執行delete操做
                 */
                else if(t2.startsWith("INSERT INTO "+table)){
                    String ids = t2.substring(t2.lastIndexOf(","));
                    bw.append("delete from "+table+" where id="+NumberUtil.toDigital(ids)+";\n");
                    bw.append(t+";\n");
                }
                /*
                 * sql語句後面都要加 ; ,由於原來沒有,不加的話,在導入到數據庫時,出錯
                 */
            }
            br.close();
        }
        
        bw.flush();
        bw.close();
    }
    
    public static void main(String[] args) throws Exception{
        long sd = System.currentTimeMillis();
        ReloadWorker w = new ReloadWorker();
        List<String> orgs = new ArrayList<String>();
        orgs.add("C:/Users/IBM_ADMIN/Desktop/000015.txt");
        orgs.add("C:/Users/IBM_ADMIN/Desktop/000016.txt");
        orgs.add("C:/Users/IBM_ADMIN/Desktop/000017.txt");
        orgs.add("C:/Users/IBM_ADMIN/Desktop/000018.txt");
        orgs.add("C:/Users/IBM_ADMIN/Desktop/000019.txt");
        
        String targetS = "C:/Users/IBM_ADMIN/Desktop/000017_sql.txt";
        w.read(orgs, targetS, "task");
        
        System.out.println("DONE, on " +(System.currentTimeMillis() - sd)/1000+" s");
    }
}

  

獲得了彙總的sql文件後,就導入到數據庫中。
最後,出一個運行圖:
 
終於鬆了一口氣。(雖然此次導入花了5分鐘。。)
 
最後提醒你們,必定要常備份,謹慎操做啊!
相關文章
相關標籤/搜索