今天在羣裏看到有人說不熟悉innodb把ibdata(數據文件)和ib_logfile(事務日誌)文件誤刪除了。不知道怎麼解決。當時我也不知道怎麼辦。後來查閱相關資料。終找到解決方法。其實恢復也挺簡單的。咱們不知道的時候就以爲難了。誰說不是這樣呢?python
下面咱們就來模擬生產環境下,人爲刪除數據文件和重作日誌文件。而後詳細說明恢復步驟。mysql
一、用sysbench模擬數據的寫入,以下所示:sql
[root@yayun-mysql-server ~]# sysbench --test=oltp --oltp-table-size=1000000 --oltp-read-only=off --init-rng=on --num-threads=16 --max-requests=0 --oltp-dist-type=uniform --max-time=1800 --mysql-user=root --mysql-socket=/tmp/mysqld.sock --mysql-password=123456 --db-driver=mysql --mysql-table-engine=innodb --oltp-test-mode=complex prepare sysbench 0.4.10: multi-threaded system evaluation benchmark Creating table 'sbtest'... Creating 1000000 records in table 'sbtest'...
二、使用命令rm -f ib*刪除數據文件和事務日誌文件:數據庫
[root@yayun-mysql-server mysql]# ls employees ib_logfile1 mysql-bin.000003 mysql-bin.000008 performance_schema world_innodb yayun-mysql-server.pid general.log menagerie mysql-bin.000004 mysql-bin.000009 sakila world_myisam host mysql mysql-bin.000005 mysql-bin.000010 sbtest xtrabackup_binlog_pos_innodb ibdata1 mysql-bin.000001 mysql-bin.000006 mysql-bin.index slow-query.log yayun ib_logfile0 mysql-bin.000002 mysql-bin.000007 percona test yayun-mysql-server.err [root@yayun-mysql-server mysql]# rm -f ib* [root@yayun-mysql-server mysql]#
下面咱們來看看如何恢復:緩存
若此時發現數據庫還能正常工做,數據依然可讀可寫,切記:這個時候千萬不要把mysqld進程殺死,不然真無法挽救了,你就等着哭吧。socket
(root@yayun 20:42:25pm> ) [yayun]>select * from t1; +----+-------+ | id | name | +----+-------+ | 1 | yayun | | 2 | atlas | | 3 | mysql | +----+-------+ 3 rows in set (0.00 sec) (root@yayun 20:42:28pm> ) [yayun]>insert into t1 select 4,'python'; Query OK, 1 row affected (0.01 sec) Records: 1 Duplicates: 0 Warnings: 0 (root@yayun 20:42:48pm> ) [yayun]>select * from t1; +----+--------+ | id | name | +----+--------+ | 1 | yayun | | 2 | atlas | | 3 | mysql | | 4 | python | +----+--------+ 4 rows in set (0.00 sec) (root@yayun 20:42:50pm> ) [yayun]>
我這裏讀寫都正常。因此咱們可以恢復成功的。
(1)首先,先找到mysqld進程的pid,以下所示:tcp
[root@yayun-mysql-server ~]# netstat -nltp | grep mysqld tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 5725/mysqld [root@yayun-mysql-server ~]#
可見mysqld的pid是5725,這一步是關鍵的一步。ide
(2)使用以下命令查看結果(很是重要)lua
[root@yayun-mysql-server ~]# ll /proc/5725/fd | egrep 'ib_|ibdata' lrwx------. 1 root root 64 Apr 30 20:44 10 -> /data/mysql/ib_logfile1 (deleted) lrwx------. 1 root root 64 Apr 30 20:44 4 -> /data/mysql/ibdata1 (deleted) lrwx------. 1 root root 64 Apr 30 20:44 9 -> /data/mysql/ib_logfile0 (deleted) [root@yayun-mysql-server ~]#
這裏有相關很重要的知識,童鞋們自行查閱,刪除一個文件時,並非真正刪除,而是打一個標記,一樣在咱們mysql數據庫中,delete一條記錄實際的刪除操做也沒有發生。
上面顯示的結果中,其中10,4,9就是咱們須要恢復的文件。spa
(3)在恢復文件前,須要執行flush tables with read lock,確保數據庫沒有寫入操做,以便咱們完成恢復
(root@yayun 20:55:26pm> ) [(none)]>flush tables with read lock; Query OK, 0 rows affected (0.00 sec) (root@yayun 20:55:31pm> ) [(none)]>
那麼咱們如何肯定沒有數據寫入呢?分幾個步驟查看
(1)設置髒頁刷新比例(讓髒頁儘快刷新到磁盤)
(root@yayun 20:55:31pm> ) [(none)]>set global innodb_max_dirty_pages_pct=0; Query OK, 0 rows affected (0.00 sec) (root@yayun 20:57:42pm> ) [(none)]>
(2)查看binlog日誌寫入狀況,確保File和Position的值沒有發生變化
(root@yayun 20:57:42pm> ) [(none)]>show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000010 | 61704130 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) (root@yayun 20:59:11pm> ) [(none)]>
(3)查看innodb狀態信息,確保髒頁已經刷新到磁盤
(root@yayun 20:59:11pm> ) [(none)]>show engine innodb status\G ------------ TRANSACTIONS ------------ Trx id counter B9E0F Purge done for trx's n:o < B9E0C undo n:o < 0 #確保後臺線程purge把undo log所有清刷掉 ------------------------------------- INSERT BUFFER AND ADAPTIVE HASH INDEX ------------------------------------- Ibuf: size 1, free list len 2543, seg size 2545, 0 merges #確保合併插入緩存等於1 --- LOG --- Log sequence number 6173930288 Log flushed up to 6173930288 #確保這裏三個值保持一致,而且再也不變化 Last checkpoint at 6173930288 Buffer pool size 65534 Free buffers 50513 Database pages 15020 Old database pages 5506 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. 5725, id 140014471358208, state: waiting for server activity Number of rows inserted 1000004, updated 1995, deleted 0, read 2008 0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s #確保插入,更新,刪除爲0
上面咱們都確認後,就能夠進行恢復操做了。記得前面咱們查看要恢復的文件的命令吧,咱們的mysqld進程的pid是5725,咱們再次看看須要恢復的文件
[root@yayun-mysql-server ~]# ll /proc/5725/fd | egrep 'ib_|ibdata' lrwx------. 1 root root 64 Apr 30 20:44 10 -> /data/mysql/ib_logfile1 (deleted) lrwx------. 1 root root 64 Apr 30 20:44 4 -> /data/mysql/ibdata1 (deleted) lrwx------. 1 root root 64 Apr 30 20:44 9 -> /data/mysql/ib_logfile0 (deleted) [root@yayun-mysql-server ~]#
把10,4,9文件cp到原來mysql的數據目錄下:
[root@yayun-mysql-server ~]# cd /proc/5725/fd [root@yayun-mysql-server fd]# cp 10 /data/mysql/ib_logfile1 [root@yayun-mysql-server fd]# cp 4 /data/mysql/ibdata1 [root@yayun-mysql-server fd]# cp 9 /data/mysql/ib_logfile0 [root@yayun-mysql-server fd]#
修改文件權限
[root@yayun-mysql-server ~]# cd /data/mysql [root@yayun-mysql-server mysql]# chown -R mysql.mysql ib* [root@yayun-mysql-server mysql]# ll | egrep 'ib_|ibdata1' -rw-r--r-- 1 mysql mysql 866123776 Apr 30 21:13 ibdata1 -rw-r--r-- 1 mysql mysql 67108864 Apr 30 21:13 ib_logfile0 -rw-r--r-- 1 mysql mysql 67108864 Apr 30 21:11 ib_logfile1 [root@yayun-mysql-server mysql]#
重啓mysql,修復完成
[root@yayun-mysql-server mysql]# /etc/init.d/mysqld restart Shutting down MySQL... [ OK ] Starting MySQL.... [ OK ] [root@yayun-mysql-server mysql]#