ローカルのMySQLが壊れた時にやったこと

ほぼ、参考にしたサイトの内容をなぞる形になってしまったが、プロセス残存とかよくあるMySQL起動問題とは違っていたので書く。

ローカルでMySQLが絡むテスト中にMacが落ちてMySQLが起動出来なくなった。

$ mysql.server start
Starting MySQL
. ERROR! The server quit without updating PID file (/usr/local/var/mysql/eiryu-MBP.local.pid).

/usr/local/var/mysql/eiryu-MBP.local.errの中を見てみる。

2017-11-27 03:25:06 19627 [Note] InnoDB: Database was not shutdown normally!
2017-11-27 03:25:06 19627 [Note] InnoDB: Starting crash recovery.
2017-11-27 03:25:06 19627 [Note] InnoDB: Reading tablespace information from the .ibd files...
2017-11-27 03:25:16 19627 [Note] InnoDB: Restoring possible half-written data pages
2017-11-27 03:25:16 19627 [Note] InnoDB: from the doublewrite buffer...
InnoDB: Doing recovery: scanned up to log sequence number 24054316032
InnoDB: Doing recovery: scanned up to log sequence number 24056388854
2017-11-27 03:25:17 19627 [Note] InnoDB: Starting an apply batch of log records to the database...
InnoDB: Progress in percent: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 InnoDB: Error: trying to access page number 0 in space 1027648,
InnoDB: space name circle_test/login_user,
InnoDB: which is outside the tablespace bounds.
InnoDB: Byte offset 0, len 16384, i/o type 10.

どうも起動時に前回正しく終了されなかったところをリストアしようとして失敗しているらしい。circle_test/login_user
このDBはテスト時だけ使うもので普段はテーブル等が存在していないDBなので、リストアは不要。(ちなみにCircleCIが標準で用意しているDBと同じ名前。ローカルでも同じ名前にしておいて同じ設定でテストが動くようにしている)
とりあえず起動して、念のため必要なDBのバックアップ&このテスト用DBを削除することにする。

innodb_force_recoveryを1から試していって6で起動した。

バックアップ後、テスト用DBを消そうとしたら消えない。

mysql> drop database circle_test;
ERROR 1051 (42S02): Unknown table 

のでデータディレクトリを物理的に削除。

rm -rf /usr/local/var/mysql/circle_test

そして、innodb_force_recoveryをコメントアウトして起動。
しかし、この状態でテスト用DBを作ってテーブルを作ろうとしても論理的な整合性がおかしいらしく、作ることが出来なかった。

mysql> use circle_test
Database changed
mysql> show tables;
Empty set (0.00 sec)
mysql> create table databasechangeloglock(id int);
ERROR 1813 (HY000): Tablespace for table '`circle_test`.`databasechangeloglock`' exists. Please DISCARD the tablespace before IMPORT.

仕方ないので、 /usr/local/var/mysqlからmysql以外のディレクトリを他の場所へ移動。サイトによってはDBごとのibdataファイルを消したりしているものも見たが、1つのものしかないっぽかったので諦めて全部移動した。

その後は、起動して必要なDBをリストアして、さっきのテスト用DBでもテーブルが作れるようになっていることを確認。

参考