在日常工作中,因不熟悉InnoDB引擎,在群裡看到有很多人誤刪除了InnoDB ibdata資料檔案)和ib_logfileredo log重做交易記錄檔),結果導致了杯具的發生。如果你有做主從複製同步,那還好,如果是單機呢?如何恢複?
下面,請看恢複示範:
一、你可以用sysbench類比資料的寫入,如:
- sysbench --test=oltp --mysql-table-engine=innodb --oltp-table-size=10000000 --max-requests=10000
- --num-threads=90 --mysql-host=192.168.110.140 --mysql-port=3306 --mysql-user=admin --mysql-password=123456
- --mysql-db=test --oltp-table-name=uncompressed --mysql-socket=/tmp/mysql.sock run
二、rm -f ib*
三、此時我估計你被嚇得夠嗆,臉白手哆嗦,如果你看到這篇文章,心可以穩穩了,沒事,可以恢複的。
四、此時,你會探索資料庫還可以正常工作,資料照樣可以寫入,切記,這時千萬別把mysqld進程殺死,否則你只有跳樓了,神仙都沒法救你。
五、先找到mysqld的進程pid
- # netstat -ntlp | grep mysqld
- tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 30426/mysqld
我這裡是30426
六、執行關鍵的一步
- # ll /proc/30426/fd | egrep 'ib_|ibdata'
- lrwx------ 1 root root 64 9月 24 16:51 10 -> /u2/mysql/data/ib_logfile1
- lrwx------ 1 root root 64 9月 24 16:51 11 -> /u2/mysql/data/ib_logfile2
- lrwx------ 1 root root 64 9月 24 16:51 4 -> /u2/mysql/data/ibdata1
- lrwx------ 1 root root 64 9月 24 16:51 9 -> /u2/mysql/data/ib_logfile0
10,11,4,9就是我們要恢複的檔案。
七、你可以把前端業務關閉,或者執行FLUSH TABLES WITH READ LOCK;這一步的作用是讓資料庫沒有寫入操作,以便後面的恢複工作。
八、如何驗證沒有寫入操作呢?分以下幾步,記住要結合在一起觀察。
- set global innodb_max_dirty_pages_pct=0;
- # 讓髒頁儘快刷入到磁碟裡。
- mysql> show master status;
- +------------------+----------+--------------+------------------+
- | File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
- +------------------+----------+--------------+------------------+
- | mysql-bin.000002 | 107 | | |
- +------------------+----------+--------------+------------------+
- 1 row in set (0.00 sec)
確保File和Position值不在變化
- show engine innodb status\G;
-
- ------------
- TRANSACTIONS
- ------------
- Trx id counter A21837
- Purge done for trx's n:o < A21837 undo n:o < 0
- ## 確保後台Purge進程把undo log全部清除掉,事務ID要一致。
-
- -------------------------------------
- INSERT BUFFER AND ADAPTIVE HASH INDEX
- -------------------------------------
- Ibuf: size 1, free list len 65, seg size 67, 0 merges
- ## insert buffer合并插入緩衝等於1
-
- ---
- LOG
- ---
- Log sequence number 18158813743
- Log flushed up to 18158813743
- Last checkpoint at 18158813743
- ## 確保這3個值不在變化
-
- ----------------------
- BUFFER POOL AND MEMORY
- ----------------------
- Total memory allocated 643891200; in additional pool allocated 0
- Dictionary memory allocated 39812
- Buffer pool size 38400
- Free buffers 37304
- Database pages 1095
- Old database pages 424
- Modified db pages 0
- ## 確保髒頁數量為0
-
- --------------
- ROW OPERATIONS
- --------------
- 0 queries inside InnoDB, 0 queries in queue
- 1 read views open inside InnoDB
- Main thread process no. 30426, id 140111500936976, state: waiting for server activity Number of rows inserted 0, updated 0, deleted 0, read 0
- 0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s
- ## 確保插入、更新、刪除為0
九、上面一系列確認工作完成之後,我們就可以恢複了。還記得剛才我們記錄的刪除檔案嗎?
- # ll /proc/30426/fd | egrep 'ib_|ibdata'
- lrwx------ 1 root root 64 9月 24 16:51 10 -> /u2/mysql/data/ib_logfile1
- lrwx------ 1 root root 64 9月 24 16:51 11 -> /u2/mysql/data/ib_logfile2
- lrwx------ 1 root root 64 9月 24 16:51 4 -> /u2/mysql/data/ibdata1
- lrwx------ 1 root root 64 9月 24 16:51 9 -> /u2/mysql/data/ib_logfile0
把這些檔案拷貝到原來的目錄下並修改使用者屬性即可。
- #cd /proc/10755/fd
- #cp 10 /u2/mysql/data/ib_logfile1
- #cp 11 /u2/mysql/data/ib_logfile2
- #cp 4 /u2/mysql/data/ibdata1
- #cp 9 /u2/mysql/data/ib_logfile0
並修改使用者屬性
- #cd /u2/mysql/data/
- #chown mysql:mysql ib*
十、大功告成,只需要重啟MySQL即可。
- /etc/init.d/mysql restart
怎樣?就這麼簡單,你也動手試試吧。
本文出自 “賀春暘的技術專欄” 部落格,請務必保留此出處http://hcymysql.blog.51cto.com/5223301/1004810