InnoDBの破損とリカバリ方法

原因の確認

MySQLが起動しなくなった。"/var/log/mysql/error.log"を確認したら、DBが正常にシャットダウンしなかったために、InnoDBが壊れったっぽい。

141122 21:00:54  InnoDB: Database was not shut down normally!
InnoDB: Starting crash recovery.
InnoDB: Reading tablespace information from the .ibd files...
InnoDB: Restoring possible half-written data pages from the doublewrite
InnoDB: buffer...
InnoDB: Doing recovery: scanned up to log sequence number 105723690293
InnoDB: Error: trying to access page number 2916374426 in space 0,
InnoDB: space name ./ibdata1,
InnoDB: which is outside the tablespace bounds.
InnoDB: Byte offset 0, len 16384, i/o type 10.
InnoDB: If you get this error at mysqld startup, please check that
InnoDB: your my.cnf matches the ibdata files that you have in the MySQL server.

InnoDB強制リカバリモードでの起動

最初は値を1にして、MySQLの起動を行う。ダメだったら、この値を1ずつ足していき、6までMySQLが起動するまで試す。

sudo vim /etc/mysql/my.cnf

[mysqld]
innodb_force_recovery = 3

DBのバックアップ

MySQLが起動するので、即効でバックアップを取得する。終わったらMySQLを停止させる。

mysqldump -u root -p database_name > ~/database_name.sql
sudo service mysql stop

InnoDB出力先の変更

InnoDB出力先の確認

InnoDB出力先の確認を行う、ついでに、先ほど設定したInnoDB強制リカバリモードでの起動は無効にしておく。

sudo vim /etc/mysql/my.cnf

[mysqld]

# innodb_force_recovery = 3
# InnoDB強制リカバリモードでは起動しなくても良いので、コメントアウトする。
datadir         = /var/lib/mysql
# InnoDBの出力先を確認する。

InnoDB新しい出力先の作成

古いInnoDBファイルを念のため避けておき、新しいフォルダを作成する。

cd /var/lib
sudo mv mysql mysql.dist
sudo mkdir mysql
sudo chown mysql:mysql mysql
sudo chmod 700 mysql

これで全てOKなので、MySQLを再起動する。

sudo service mysql start

この時点では、MySQLは初期設定状態なので、必要に応じて設定を行う。

取得したバックアップを戻す

mysql -u root -p database_name < ~/database_name.sql