誤刪除InnoDB ibdata資料檔案(無備份)

許願流星1號發表於2015-12-02


     

    在日常工作中,因不熟悉InnoDB引擎,在群裡看到有很多人誤刪除了InnoDB ibdata(資料檔案)和ib_logfile(redo log重做事務日誌檔案),結果導致了杯具的發生。如果你有做主從複製同步,那還好,如果是單機呢?如何恢復?

    下面,請看恢復演示:

    一、你可以用sysbench模擬資料的寫入,如:

     

  1. sysbench --test=oltp --mysql-table-engine=innodb --oltp-table-size=10000000 --max-requests=10000 
  1. --num-threads=90 --mysql-host=192.168.110.140 --mysql-port=3306 --mysql-user=admin --mysql-password=123456 
  1. --mysql-db=test --oltp-table-name=uncompressed  --mysql-socket=/tmp/mysql.sock run 

二、rm -f ib*

三、此時我估計你被嚇得夠嗆,臉白手哆嗦,如果你看到這篇文章,心可以穩穩了,沒事,可以恢復的。

四、此時,你會發現資料庫還可以正常工作,資料照樣可以寫入,切記,這時千萬別把mysqld程式殺死,否則你只有跳樓了,神仙都沒法救你。

五、先找到mysqld的程式pid

 

  1. # netstat -ntlp | grep mysqld 
  1. tcp        0      0 0.0.0.0:3306                0.0.0.0:*                   LISTEN      2463/mysqld  

我這裡是30426

六、執行關鍵的一步

[root@wg1 data]# ll /proc/2463/fd | egrep 'ib_|ibdata'

lrwx------ 1 root root 64 08-19 09:51 3 -> /mydata/mysql-5.6.25/data/ibdata1 (deleted)

lrwx------ 1 root root 64 08-19 09:51 8 -> /mydata/mysql-5.6.25/data/ib_logfile0 (deleted)

lrwx------ 1 root root 64 08-19 09:51 9 -> /mydata/mysql-5.6.25/data/ib_logfile1 (deleted)

 

3,8,9就是我們要恢復的檔案。

七、你可以把前端業務關閉,或者執行FLUSH TABLES WITH READ LOCK;這一步的作用是讓資料庫沒有寫入操作,以便後面的恢復工作。

八、如何驗證沒有寫入操作呢?分以下幾步,記住要結合在一起觀察。

 

mysql> set global innodb_max_dirty_pages_pct=0;

Query OK, 0 rows affected (0.00 sec)

 

  1. # 讓髒頁儘快刷入到磁碟裡。

 

  1. mysql> show master status; 
  2. +------------------+----------+--------------+------------------+ 
  1. | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | 
  2. +------------------+----------+--------------+------------------+ 
  1. | mysql-bin.000002 |      107 |              |                  | 
  1. +------------------+----------+--------------+------------------+ 
  2. 1 row in set (0.00 sec) 

確保File和Position值不在變化

 

  1. show engine innodb status\G;  
  2.   
  3. ------------  
  4. TRANSACTIONS  
  5. ------------  
  6. Trx id counter A21837  
  7. Purge done for trx's n:o < A21837 undo n:o < 0  
  1. ## 確保後臺Purge程式把undo log全部清除掉,事務ID要一致。  
  1.   
  2. -------------------------------------  
  3. INSERT BUFFER AND ADAPTIVE HASH INDEX  
  4. -------------------------------------  
  1. Ibuf: size 1, free list len 65, seg size 67, 0 merges  
  2. ## insert buffer合併插入快取等於1  
  1.  
  1. --- 
  1. LOG 
  1. --- 
  1. Log sequence number 18158813743 ---- 當前的LSN
  1. Log flushed up to 18158813743         ----重新整理到redo log的LSN
  1. Pages flushed up to 18158813743     ---重新整理到磁碟的LSN
  1. Last checkpoint at 18158813743 
  1. ## 確保這3個值不在變化   
  1.  
  1. ---------------------- 
  1. BUFFER POOL AND MEMORY 
  1. ----------------------  
  1. Total memory allocated 643891200; in additional pool allocated 0 
  1. Dictionary memory allocated 39812 
  1. Buffer pool size   38400 
  1. Free buffers   37304 
  2. Database pages 1095 
  3. Old database pages 424 
  1. Modified db pages  0 
  2. ## 確保髒頁數量為0  
  1.  
  2. -------------- 
  3. ROW OPERATIONS 
  4. -------------- 
  1. 0 queries inside InnoDB, 0 queries in queue 
  1. 1 read views open inside InnoDB 
  2. Main thread process no. 30426, id 140111500936976, state: waiting for server activity Number of rows inserted 0, updated 0, deleted 0, read 0 
  1. 0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s 
  2. ## 確保插入、更新、刪除為0 

九、上面一系列確認工作完成之後,我們就可以恢復了。還記得剛才我們記錄的刪除檔案嗎?

 

[root@wg1 data]# ll /proc/2463/fd | egrep 'ib_|ibdata'

lrwx------ 1 root root 64 08-19 09:51 3 -> /mydata/mysql-5.6.25/data/ibdata1 (deleted)

lrwx------ 1 root root 64 08-19 09:51 8 -> /mydata/mysql-5.6.25/data/ib_logfile0 (deleted)

lrwx------ 1 root root 64 08-19 09:51 9 -> /mydata/mysql-5.6.25/data/ib_logfile1 (deleted)

 

把這些檔案複製到原來的目錄下並修改使用者屬性即可。

 

[root@wg1 data]# cd /proc/2463/fd

 

[root@wg1 fd]# cp 3 /mydata/mysql-5.6.25/data/ibdata1

[root@wg1 fd]# cp 8 /mydata/mysql-5.6.25/data/ib_logfile0

[root@wg1 fd]# cp 9 /mydata/mysql-5.6.25/data/ib_logfile1

 

並修改使用者屬性

 

[root@wg1 fd]# cd /mydata/mysql-5.6.25/data/

[root@wg1 data]# chown mysql:mysql ib*

十、大功告成,只需要重啟MySQL即可。

 

  1. /etc/init.d/mysql restart 

 

源文件 <> 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29893219/viewspace-1851577/,如需轉載,請註明出處,否則將追究法律責任。

相關文章