久々にMySQL関係でハマりました。原因は mysqldump です。実は数ヶ月前にも同じ現象で悩み、その時は深い調査しないまま対処療法をしてしまいました。今回、やはり技術者たるもの、しっかりと根本原因を追及しなければならないなと反省した次第です。
MySQL 5.0 以降の mysqldump では --opt オプションがデフォルトで有効となっています。これは以下の8つのオプションを一括して指定するオプションです。
--add-drop-table --add-locks --create-options --disable-keys --extended-insert --lock-tables --quick --set-charset
この中で --extended-insert オプションがあることにより、レコードをコンマ区切りにして、できるかぎり一括してひとつのINSERT文記述するやりかたで出力してくれるのですが、ダンプしたファイルを grep してみたい時や、diffを取ってみたいときに、非常に不便なので、私は --skip-opt をした上で、--add-drop-table など、自分の使いたいオプションだけ追加していました。
さて、--skip-opt によって無効化される上記8つのオプションの中に、非常にキケンなものがひとつあります。どれでしょう。
--quick や --lock-tables, --disable-keys, --add-locks などは主に速度に関するものですし、--add-drop-table は予めテーブルをDROPしておけば困ることはありません。--set-charset も、私の場合はすべての環境が utf8 になっているのでたぶん問題ないでしょう。
そう。--create-options。こんなキケンなオプションが --skip-opt で外されてしまうのです。
これは何かというと、CREATE TABLE 文の中で「MySQL独自のもの」を含めないようにするオプションです。 NOT NULL や DEFAULT などは標準SQLなので出力されますが、そう! このオプションをつけないと、AUTO_INCREMENT がなくなるのです!
大事なことなので繰り返します。
「--skip-opt を指定すると、--create-options も外れちゃうよ!そうしたら、CREATE TABLE 文から AUTO_INCREMENT が消えちゃうよ!」
対応法は2つあり、個人的には2番目のほうがいいかなぁと思っています。
(1)「--skip-opt --create-options --add-droptable」のように、--skip-opt で8つのオプションを引いたあと、使用したいオプションを明示する
(2)--skip-opt を指定せずに、引きたいオプションだけを「--skip-extended-insert」のように指定する。先頭に skip- をつけるだけなので、「--skip-add-drop-table」みたいなちょっと面白い名前になったりもします。
処理速度や処理方法(DROPするかしないか等)に関するものだけでなく、テーブルレイアウトそのものが再現できなくなってしまうものが一緒に含まれているなんて、怖いなぁと思いました。
そして、前回「あれー?いつのまにか AUTO_INCREMENT がなくなってるー。なんでだろー?」などと呑気に対応してしっかり調査しなかったことで、今日またハマってしまったということで、技術者としてもっとコダワリを持たなきゃいけないな、と猛省した次第なのであります。
.