MERGEテーブルが抱えているMyISAMのリネームとテーブル破損

MERGEテーブルが抱えているMyISAMテーブルをリネームした場合、何かが原因でテーブルが壊れたと見なされる様子。

例えば、parentというMERGEテーブルがあり、childというMyISAMテーブルを抱えているとします。そして、child_tempというMyISAMテーブルを作成していくらかのINSERTを行った後、"RENAME TABLE child TO child_old, child_temp TO child;"としてリネームします。そうすると、childが壊れたと見なされる事があります。これは、必ずというわけでもないので、理由がよくわかりません。

アクティブな MERGE テーブルで使用されているテーブルに対して RENAME TABLE を実行すると、テーブルが破損するおそれがある。これは MySQL 4.1.x で修正される予定。
MySQL :: MySQL 4.1 リファレンスマニュアル :: 7.2.1 MERGE テーブルの問題

MySQLのドキュメントに、それらしい記述がありますが、利用しているバージョンは5.0系なので、ドキュメント通りに事が進んでいるとすれば、修正されて問題がなくなっているはずです(そうでもない?)。

開いているMERGE テーブルにマップされた全てのテーブルに対して、 WHERE 条項、 REPAIR TABLE、 TRUNCATE TABLE、 OPTIMIZE TABLE、また ANALYZE TABLEがない DROP TABLE、 ALTER TABLE、 DELETEを使う事はできません。それをすると MERGE テーブルは元のテーブルを参照する事があるので、好ましくない結果をもたらす可能性があります。このような事を防ぐのに一番簡単なのは、FLUSH TABLES ステートメントを事前に発行する事によって、全ての MERGE テーブルを閉じておくという方法です。
MySQL :: MySQL 5.1 リファレンスマニュアル :: 13.6.1 MERGE テーブルの問題点

また、上記のような記述もあります。微妙にRENAME TABLEは外れている気がしますが、それらしい記述です。

.MRG ファイルを変更し、MERGE テーブルとこれを構成するすべてのテーブルに対して FLUSH TABLE を発行することで、ストレージエンジンが新しい定義ファイルを読み取るようにする。
MySQL :: MySQL 4.1 リファレンスマニュアル :: 7.2 MERGE テーブル

ついでに、上記のような記述もありました。

さて、「壊れた」と書きましたが、症状としては、レコードサイズやデータファイルのサイズが一致しないというものでした。さらに、観察してみると、どうやら、RENAME TABLE前のテーブル情報をそのまま抱え続けている様です。

どうやら、テーブル情報を「何か」が抱え続けている事が原因で、テーブルが破損したと見なされる様です。(ソースを確認したわけではないので)確証はありませんが、"RENAME TABLE"後にMERGEテーブルとMyISAMテーブルの両方をFLUSH TABLEする様にしたところ、「今のところは」テーブル破損が確認されなくなりました。

プロフィール

このブログ記事について

このページは、koshigoeが2008年7月24日 21:35に書いたブログ記事です。

ひとつ前のブログ記事は「MySQLのレプリケーションでDBやテーブルを指定」です。

次のブログ記事は「autocomplete="off"とパスワードマネージャ」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。