Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
EPUB - 7.5Mb
HTML Download (TGZ) - 7.2Mb
HTML Download (Zip) - 7.2Mb


15.7.2 MERGE テーブルの問題点

MERGE テーブルの既知の問題点は次のとおりです。

  • 5.1.23 バージョンより前の MySQL Server では、MyISAM の非一時的な子供のテーブルを持つ一時的なマージテーブルを作成できました。

    バージョン 5.1.23 からは、MERGE の子供は親のテーブルを介してロックされました。親が一時的であった場合、親がロックされなかったため、子供もロックされませんでした。MyISAM テーブルを同時に使用すると、テーブルが破損しました。

  • ALTER TABLE を使用して MERGE テーブルを別のストレージエンジンに変えると、基礎テーブルへのマッピングが失われます。その代わり、変更されたテーブルに基礎 MyISAM テーブルの行がコピーされ、そのときに、指定されたストレージエンジンを使用します。

  • MERGE テーブルの INSERT_METHOD テーブルオプションは、MERGE テーブルへの挿入にどの基礎 MyISAM テーブルを使用するかを示します。ただし、その MyISAM テーブルに AUTO_INCREMENT テーブルオプションを使用しても、1 つ以上の行が MyISAM テーブルに直接挿入されるまで、MERGE テーブルへの挿入は有効になりません。

  • MERGE テーブルは、テーブル全体に一意制約を保持できません。INSERT を実行すると、データは最初または最後の MyISAM テーブル (INSERT_METHOD オプションで指定されます) に入ります。MySQL は一意のキー値が MyISAM テーブル内で一意のままであることを保証しますが、コレクション内のすべての基礎テーブルには保証しません。

  • MERGE エンジンは基本テーブルセットに一意性を適用できないため、REPLACE は期待どおりに機能しません。次の 2 つの重要な事実があります。

    • REPLACE は、書き込もうとする基礎テーブルでのみ一意キー違反を検出できます (INSERT_METHOD オプションで指定されます)。これは MERGE テーブル自体の違反とは異なります。

    • REPLACE が一意キー違反を検出した場合、書き込んでいる基礎テーブルの対応する行だけを変更します。すなわち、INSERT_METHOD オプションで指定される最初または最後のテーブルです。

    INSERT ... ON DUPLICATE KEY UPDATE についても同様な考慮が適用されます。

  • MERGE テーブルはパーティション化をサポートしていません。つまり、MERGE テーブルも、MERGE テーブルの基礎 MyISAM テーブルもパーティション化できません。

  • 開いた MERGE テーブルにマッピングされたどのテーブルにも、ANALYZE TABLEREPAIR TABLEOPTIMIZE TABLEALTER TABLEDROP TABLEDELETE (WHERE 句なし)、または TRUNCATE TABLE を使用すべきではありません。そうする場合、MERGE テーブルは引き続き元のテーブルを参照しているため、予期しない結果となる可能性があります。この問題に対処するには、名前付きの操作を行う前に FLUSH TABLES ステートメントを発行することで、確実に MERGE テーブルが開いたままにならないようにします。

    予期しない結果には、MERGE テーブルに対する操作によってテーブルの破損が報告される可能性が含まれます。基礎 MyISAM テーブルで名前付き操作のあとにこれが発生した場合、破損メッセージは偽りです。これに対処するには、MyISAM テーブルを変更したあとで FLUSH TABLES ステートメントを発行します。

  • MERGE ストレージエンジンのテーブルマッピングは MySQL の上位レイヤーから隠れているので、MERGE テーブルによって使用されているテーブルでの DROP TABLE は Windows では機能しません。Windows では開いているファイルの削除を許可しないため、最初にすべての MERGE テーブルをフラッシュするか (FLUSH TABLES を使用します)、テーブルを削除する前に MERGE テーブルを削除する必要があります。

  • MyISAM テーブルと MERGE テーブルの定義は、テーブルにアクセスするときにチェックされます (たとえば、SELECT または INSERT ステートメントの一部として)。このチェックは、テーブルの定義と親の MERGE テーブルの定義が、カラムの順番、タイプ、サイズ、および関連するインデックスを比較することで一致することを保証します。テーブル間で違いがある場合、エラーが戻され、ステートメントは失敗します。テーブルが開いたときにこれらのチェックが行われるため、1 つのテーブルの定義に変更を加えると (カラムの変更、カラムの順序付け、エンジンの変更など)、ステートメントが失敗する原因になります。

  • MERGE テーブルと、その基礎テーブルのインデックスの順番は同一でなければいけません。ALTER TABLE を使用して、MERGE テーブル内で使用されるテーブルに UNIQUE インデックスを追加し、次に ALTER TABLE を使用して MERGE テーブル上に一意でないインデックスを追加した場合、基礎テーブル内に一意でないインデックスがすでに存在していると、それらのテーブルのインデックス順序は異なります。(これが発生するのは、重複キーをすばやく検出できるように ALTER TABLE が一意でないインデックスの前に UNIQUE インデックスを配置するためです。)その結果、このようなインデックスを持つテーブルに対するクエリーは予想外の結果をもたらす可能性があります。

  • ERROR 1017 (HY000): Can't find file: 'tbl_name.MRG' (errno: 2)エラーメッセージが表示された場合、一般的に、いくつかの基礎テーブルが MyISAM ストレージエンジンを使用していないことを表しています。これらのテーブルがすべて MyISAM であることを確認してください。

  • MERGE テーブルの行の最大値は 264 です (~1.844E+19 で、MyISAM テーブルの場合と同じ)。複数の MyISAM テーブルを、この数よりも多くの行を含む単一の MERGE テーブルにマージできません。

  • MERGE ストレージエンジンは、INSERT DELAYED ステートメントをサポートしていません。

  • 親の MERGE テーブルを持つ、異なる行フォーマットの基礎 MyISAM テーブルを使用すると、現在失敗することが知られています。バグ #32364 を参照してください。

  • LOCK TABLES が実施されているときは、非一時的な MERGE テーブルの結合リストを変更できません。次は動作しません

    CREATE TABLE m1 ... ENGINE=MRG_MYISAM ...;
    LOCK TABLES t1 WRITE, t2 WRITE, m1 WRITE;
    ALTER TABLE m1 ... UNION=(t1,t2) ...;
    

    ただし、一時的な MERGE テーブルではこれを行うことができます。

  • 一時的な MERGE としても、非一時的な MERGE テーブルとしても、CREATE ... SELECTMERGE テーブルを作成できません。例:

    CREATE TABLE m1 ... ENGINE=MRG_MYISAM ... SELECT ...;

    これを試みると、tbl_nameBASE TABLE ではないというエラーとなります。

  • あるケースでは、MERGE と基礎テーブル間で PACK_KEYS テーブルオプション値が異なると、基礎テーブルに CHAR または BINARY カラムが含まれている場合、予期しない結果になります。回避策として、ALTER TABLE を使用して、関係するすべてのテーブルの PACK_KEYS 値が同じであることを保証します。(Bug #50646)


User Comments
  Posted by Johannes Ullrich on October 31, 2006
If a MyISAM table is part of a MERGE table, you can not just copy the table files as you upgrade from MySQL 4.1 to 5.0. Instead, you HAVE TO dump the table and read it back in.

If you don't: you will get errors indicating that the tables are not defined identically.

  Posted by on January 4, 2007
Actually, you don't have to drop and repopulate your MyISAM tables; running an ALTER TABLE statement (for instance, using CHANGE COLUMN to transform the primary key into its current definition) will upgrade the MyISAM table to the current version and the MERGE table will continue to function.

You can see the MyISAM version in SHOW TABLE STATUS; notice that MyISAM tables created by MySQL 4.1 are version 9 and MyISAM tables created by MySQL 5.0 are version 10.
  Posted by Simon Mudd on June 25, 2009
ALTER TABLE can be used (at least in 5.0.68) on the underlying tables to change index definitions. mysqld appears happy to allow you to do this. However, ensure you use FLUSH TABLE after doing this as access to the merge table appears to continue accessing the old underlying table prior to the ALTER TABLE and not the new table. If the underlying tables in you merge table are getting updated it may look as if these INSERTS/UPDATES or DELETES are not working when they are, but you are simply looking at the state of the old table.

This behaviour also means that the disk space of the old tables is not freed as mysqld still has the file handles open and thus altering many underlying tables may apparently fill up the disk for no apparent reason.

Again FLUSH TABLES will solve this, though the problem should be dealt with by mysqld itself.
Sign Up Login You must be logged in to post a comment.