LoginSignup
4
3

More than 5 years have passed since last update.

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

Posted at

現象

しばらく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.

解決策その1

実は、今回が最初じゃない。前回はエラーログにある(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行追記して、無事解決。

解決策その2

妙に、拡張子が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の挙動を確認してから、とは思ったのですが、そして、「解決策1」が一番「間違いのない」やり方かもしれないとは思いましたが、ibdの存在が妙に気になったので、force_recoveryではないやり方を試してみた次第です。

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

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3