XAMPPのMySQLが起動しなくなったので、.ibdをrenameしてみた。


# 現象
しばらくXAMPPを起動しなかったら、MySQLが起動しなくなった。
(rails/sqlite3とか、djangoとかごちゃごちゃ別の環境を使ったりしていたので、へそを曲げたのか・・・理由がわかれば苦労しないんだけど、ポートがぶつかったりもしていたのかな？）

XAMPPのManage Serverで、MySQL Databaseを選んで"Start"を押しても、数十秒悩んだ後Stoppedになってしまって、Runningにならない。

うっかりポートが被っているDBを走らせていて、そこにXAMPPを起動した後などは、全部を「停止」してもXAMPPのMySQLが起動してくれない場合もあったけれど、Macを再起動すればだいたい機嫌を直してくれていた。（ここで、再起動が必要な場合と、再起動しなくても動く場合の違いが、実はよくわかっていない。）

いずれにせよ、前回と違ったやり方で対応してみたのでメモ。（二通りのやり方をメモっておきます。）

# 環境
Mac OS X El Capitan (10.11.5)
XAMPP 5.6.11-0
 (mysql  Ver 14.14 Distrib 5.6.25, for osx)
(WindowsのXAMPPでも、基本的に同じアプローチになると思う。）
  
# エラーログ

XAMPPの[Configure]ボタンから、[Open Log]をクリックして表示。
または、
/Application/XAMPP/xamppfiles/var/(マシン名).local.err

```エラーログ
2016-07-XX XX:XX:XX 7fff7519c000  InnoDB: Operating system error number 2 in a file operation.
InnoDB: The error means the system cannot find the path specified.
InnoDB: If you are installing InnoDB, remember that you must create
InnoDB: directories yourself, InnoDB does not create them.
InnoDB: Error: could not open single-table tablespace file ./foobardb/zot.ibd
InnoDB: We do not continue the crash recovery, because the table may become
InnoDB: corrupt if we cannot apply the log records in the InnoDB log to it.
InnoDB: To fix the problem and start mysqld:
InnoDB: 1) If there is a permission problem in the file and mysqld cannot
InnoDB: open the file, you should modify the permissions.
InnoDB: 2) If the table is not needed, or you can restore it from a backup,
InnoDB: then you can remove the .ibd file, and InnoDB will do a normal
InnoDB: crash recovery and ignore that table.
InnoDB: 3) If the file system or the disk is broken, and you cannot remove
InnoDB: the .ibd file, you can set innodb_force_recovery > 0 in my.cnf
InnoDB: and force InnoDB to continue crash recovery here.
```

# 解決策その１
実は、今回が最初じゃない。前回はエラーログにある(3)のやり方：
you can set innodb_force_recovery > 0 in my.cnf
and force InnoDB to continue crash recovery here
の部分を試して、だいたいうまくいっていた。

/Application/XAMPP/etc/my.cnf

に、

``` my.cnf
...
# Comment the following if you are using InnoDB tables
#skip-innodb
innodb_data_home_dir=/Applications/XAMPP/xamppfiles/var/mysql/
innodb_data_file_path=ibdata1:10M:autoextend
innodb_log_group_home_dir=/Applications/XAMPP/xamppfiles/var/mysql/
innodb_force_recovery=1
...
```

という感じで、1行追記して、無事解決。

# 解決策その２

妙に、拡張子がibdのファイルが気になったので、検索してみたら、以下の記述を見つけた。（他のバージョンの記述は、なぜか出てこない。）
MySQL.com(https://dev.mysql.com/doc/mysql-enterprise-backup/3.11/ja/partial.restoring.single.html "MySQL Enterprise Backup ユーザーズガイド (バージョン 3.11)  /  ...  /  単一の .ibd ファイルのバックアップとリストア")

ibdファイルをとりあえずrenameしてみたらどうだろうか、と思って試してみる。
データファイルのパスは、上記のmy.cnfにある通り

**/Applications/XAMPP/xamppfiles/var/mysql**

この下にある、./foobardb/zot.ibd が問題のファイルということになる。suで強引にスーパーユーザになり、cd foobardbでカレントディレクトリを移動。

**mv cache_menu.ibd cache_menu.ibdremoved**

で、renameする。最初は、cache_menu.ibdが開けない、とか言っていたのが、いざrenameしてみると今度はcache_update.ibdが開けない、といってくる。もともと設計していたテーブルではない、おそらくInnoDB自体が管理しているテーブルのibdがことごとく引っ掛かっている感じだったので、試しに、全部ibdをrenameしたらどうなるか、試した。

## システム管理？のibdファイル
このバージョンでは、ibdは以下のように大量に作られている。
access.ibd actions.ibd actions_aid.ibd authmap.ibd batch.ibd blocks.ibd blocks_roles.ibd boxes.ibd cache.ibd cache_block.ibd cache_filter.ibd cache_form.ibd cache_page.ibd comments.ibd files.ibd filter_formats.ibd filters.ibd flood.ibd history.ibd languages.ibd locales_source.ibd locales_target.ibd menu_custom.ibd menu_links.ibd menu_router.ibd node.ibd node_access.ibd node_comment_statistics.ibd node_counter.ibd node_revisions.ibd node_type.ibd permission.ibd role.ibd semaphore.ibd sessions.ibd studylogs.ibd system.ibd term_data.ibd term_hierarchy.ibd term_node.ibd term_relation.ibd term_synonym.ibd url_alias.ibd users_roles.ibd variable.ibd vocabulary.ibd vocabulary_node_types.ibd watchdog.ibd

いいのかなぁ、やっちゃえ、ってな訳で、以下のようなスクリプトを書いた。

```rename_ibds.sh
#!/bin/bash

arr=( `ls *.ibd` )
for n in ${arr[@]}; do
  # echo $n
  new_name=$n"removed"
  mv $n $new_name
done
```

上記の全ての拡張子 .ibd が .ibdremovedに・・・

大丈夫かなぁ、と思いつつ、MySQLを起動したら無事Runningになりました。
めでたしめでたし。
で、ごちゃごちゃして気持ち悪いので、suになった勢いで

**rm \*.ibdremoved**

で、renameしたファイルを消したことは言うまでもありません。

ということは、(2)にあった
2) If the table is not needed, or you can restore it from a backup, then you can remove the .ibd file, and InnoDB will do a normal crash recovery and ignore that table.
の通り、最初からrenameせずにrmする、つまり

```remove_ibds.sh
#!/bin/bash

arr=( `ls *.ibd` )
for n in ${arr[@]}; do
  # echo $n
  rm $n
done
```

でもよかったのかなぁ、って、結局全部削除するなら、スクリプトなんか書かずに

**rm \*.ibd**

でいいじゃん。なんて回りくどいことをしたんだ　orz。
でも、削除一瞬怪我一生ですから・・・つい慎重になっただけです・・・

# 結果について
もっと丁寧に、InnoDBの挙動を確認してから、とは思ったのですが、そして、「解決策１」が一番「間違いのない」やり方かもしれないとは思いましたが、ibdの存在が妙に気になったので、force_recoveryではないやり方を試してみた次第です。

何かのご参考になれば・・・