あらしおブログ

技術ネタ中心の粗削りブログ

Bitnami Redmine の MySQL がクラッシュしたときのデータ復旧方法

Bitnami RedmineMySQL でデータ破損などでクラッシュして、MySQL が起動できなった場合のデータ復旧手順です。

以下で /path/to/redmine は、Bitnami Redmine のインストール先に読み替えてください。

1. Bitnami Redmine を停止
sudo service bitnami-redmine stop
2. データをバックアップ

これは万が一のためです。データ復旧が成功すれば特に使いません。

cp -ra /path/to/redmine/mysql /tmp/mysql.backup
3. 強制リカバリオプションを指定

/path/to/redmine/mysql/my.cnf で innodb_force_recovery オプションを指定します。

[mysqld]
innodb_force_recovery=1

オプションの詳細はリファレンスマニュアルを参照してください。 基本的には innodb_force_recovery の値をまずは 1 に設定し、mysqld が起動するか確認します。 起動しない場合は徐々に数字を上げていきます。 最大は 6 で、4以上はデータ破損の可能性があり危険と言われています。必ずバックアップをとっておきましょう。 また強制リカバリモードで起動すると、データベースは読み取り専用になっています。

以下はリファレンスマニュアルからの抜粋です。

innodb_force_recovery は、デフォルトでは 0 です (リカバリが強制的に実行されない通常の起動)。innodb_force_recovery の許可される 0 以外の値は 1 から 6 までです。大きい方の値には、小さい方の値の機能が含まれています。たとえば、3 の値には、値 1 と 2 のすべての機能が含まれています。

3 以下の innodb_force_recovery 値を使用してテーブルをダンプできる場合は、破損した個々のページ上の一部のデータしか失われないため、比較的安全です。4 以上の値は、データファイルが永続的に破損する場合があるため、危険であるとみなされます。6 の値は、データベースページが廃止された状態のままになり、それによって B ツリーやその他のデータベース構造にさらに多くの破損が導入される可能性があるため、きわめて危険であるとみなされます。

安全策として、innodb_force_recovery が 0 より大きい場合、InnoDB は INSERT、UPDATE、または DELETE 操作を回避します。MySQL 5.6.15 の時点では、4 以上の innodb_force_recovery 設定は InnoDB を読み取り専用モードにします。

4. mysqld を起動
sudo service bitnami-redmine start mysql

ここで、もし起動に失敗する場合は、3 に戻り、innodb_force_recovery のレベルを上げて再度起動を試みます。

5. データベースをダンプする
/path/to/redmine/mysql/bin/mysqldump -uroot -p --quote-names --flush-logs --all-databases > /tmp/dump.sql
6. データベースファイルを削除する
sudo service bitnami-redmine stop mysql
sudo rm -rf /path/to/redmine/mysql/data/*

また /path/to/redmine/my.cnf でさきほど設定した innodb_force_recovery を削除します。

7. データベースを初期化
/path/to/redmine/mysql/scripts/myscript.sh /path/to/redmine/mysql
8. mysqld を起動
sudo service bitnami-redmine start mysql
9. データベースをリストア
/path/to/redmine/mysql/mysql -uroot < /tmp/dump.sql
sudo service bitnami-redmine restart mysql
10. Bitnami Redmine を起動
sudo service bitnami-redmine start
11. mysqld のログを確認

/path/to/redmine/mysql/data/mysqld.log を確認しエラーが発生していなければ成功です。