mysql ibdata 1を誤って削除した後のリカバリ方法

4257 ワード

mysql ibdata 1を誤って削除した後、どのように回復しますか?
オンラインサーバからmysql innodb関連のデータファイルibdata 1およびログファイルib_を誤って削除した場合logfile*、どうやって復元すればいいですか?
この时は冷や汗をかいたでしょう?まずタバコを吸って、落ち着いてください.サイトをもう一度観察すると、すべてが正常で、データの読み取りと書き込み操作が完全に正常であることがわかりました.これはどういう状況ですか.
実際、mysqldは実行状態では、これらのファイルを開いた状態に維持され、削除してもファイルシステムに存在し、mysqldは読み書きすることができます.
 
  
root@localhost:/var/lib/mysql# ls -la /proc/14101/fd/ | grep -e ibdata -e ib_
lrwx------ 1 root  root  64 Aug  7 23:29 3 -> /var/lib/mysql/ibdata1 (deleted)
lrwx------ 1 root  root  64 Aug  7 23:29 8 -> /var/lib/mysql/ib_logfile0 (deleted)
lrwx------ 1 root  root  64 Aug  7 23:29 9 -> /var/lib/mysql/ib_logfile1 (deleted)

14101はmysqldのpid(プロセスID)
mysqldが終了しない限り、procファイルシステムを介して削除されたファイル(Markがdeleted状態)を見つけることができます.
この時はほっとしただろう.これらのファイルを/var/lib/mysqlにコピーすればいいですか?
事は決してそんなに簡単ではない.
なぜなら、innodbのbuffer poolにはdirty page(メモリ内のデータは変更されているが、ファイルに書き込まれていない)が多く、直接ファイルをコピーすると、軽くなるとデータが失われ、重くなるとibdata 1ファイルが破損するからです.
mysqlデータをバックアップするときも、これらのファイルを直接バックアップすることはできません.同じ理屈です.
すべてのbuffer poolのデータ変更がハードディスクファイルに保存されていることを保証する必要があります.そのため、まずより多くの書き込み/更新/削除操作を停止し、innodb flush pages to diskを待つ必要があります.書き込みを停止すると、Webサイトのアプリケーションを閉じるか、lock tables:
 
  
mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 ROWS affected (0.37 sec)

この时flushが终わるのを待って、どのように终わりがあるかどうかを知っていますか?checkpoint ageを観察すればいいです.
 
  
mysql> SHOW engine innodb STATUS  
---
LOG
---
Log SEQUENCE NUMBER 363096003
Log flushed up TO 363096003
LAST checkpoint at 363096003

checkpoint ageはLog sequence numberの値からLast checkpoint atの値を減算し、0の場合、すべてのpageがハードディスクファイルにflushされていることを示します.
この时flushが终わるのを待って、どのように终わりがあるかどうかを知っていますか?checkpoint ageを観察すればいいです.
 
  
mysql> SHOW engine innodb STATUS  
---
LOG
---
Log SEQUENCE NUMBER 363096003
Log flushed up TO 363096003
LAST checkpoint at 363096003

checkpoint ageはLog sequence numberの値からLast checkpoint atの値を減算し、0の場合、すべてのpageがハードディスクファイルにflushされていることを示します.
このflushのプロセスを加速させるには、次のように設定します.
 
  
mysql> SET global innodb_max_dirty_pages_pct=0;
Query OK, 0 ROWS affected (0.01 sec)

さらに、insert buffer threadのようなバックグラウンドのスレッドが作業を完了することを保証する必要があります.ibufのサイズは=1
 
  
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: SIZE 1, free list len 398, seg SIZE 400,

purge threadもあります.purgeはすべてのtransactionsをpurgeしているはずです.
 
  
------------
TRANSACTIONS
------------
Trx id counter 0 16644
Purge done FOR trx's n:o < 0 16644 undo n:o < 0 0

また、innodbが書き込みを行わないことを確認します.
 
  
FILE I/O
--------
I/O thread 0 state: waiting FOR i/o request (INSERT buffer thread)
I/O thread 1 state: waiting FOR i/o request (log thread)
I/O thread 2 state: waiting FOR i/o request (READ thread)
 I/O thread 3 state: waiting FOR i/o request (WRITE thread)
Pending normal aio reads: 0, aio writes: 0,
ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
Pending flushes (fsync) log: 0; buffer pool: 0
332 OS file reads, 47 OS file writes, 32 OS fsyncs
0.00 reads/s, 0 avg bytes/READ, 0.00 writes/s, 0.00 fsyncs/s

ファイルをコピーします.
 
  
root@localhost:/var/lib/mysql# cp /proc/14101/fd/3 /var/lib/mysql/ibdata1
root@localhost:/var/lib/mysql# cp /proc/14101/fd/8 /var/lib/mysql/ib_logfile0
root@localhost:/var/lib/mysql# cp /proc/14101/fd/9 /var/lib/mysql/ib_logfile1

root@localhost:/var/lib/mysql# chown -R mysql ib* mysqld
root@localhost:/var/lib/mysql# /etc/init.d/mysql restart
~~~

結論:1)事故が起きた場合、決して慌ててはいけない.タバコを吸って落ち着いてください.2)ソリューションが不明な場合は、mysqldを再起動したり、サーバを再起動したりしないでください.3)mysqlのibdataなどのファイルが存在するかどうかを監視する必要がある.