以下の既知の問題は、優先して修正されます。
FLUSH TABLES WITH READ LOCK
によって CREATE TABLE
または
COMMIT
がブロックされず、テーブルおよびバイナリログの完全バックアップを実行すると、バイナリログの位置に関する問題が発生する。
BDB テーブルでの ANALYZE TABLE
によって、mysqld
を再実行するまでテーブルが使用できなくなることがある。この問題が発生した場合は、MySQL
エラーファイルに次のようなエラーが生成される。
001207 22:07:56 bdb: log_flush: LSN past current end-of-log
MySQL では FROM
部でかっこを使用することができるが、自動的に無視される。エラーを生成しない理由は、クエリを自動的に生成する多くのクライアントで、不要な場合でも
FROM
部にかっこが付け加えられるためである。
同じクエリ内で多数の RIGHT
JOINS
を連結した場合や
LEFT
および RIGHT
結合を組み合わせた場合、LEFT
結合の前のテーブルまたは
RIGHT
結合の前のテーブルについて
NULL
行のみが生成されるので、正しい結果が得られないことがある。これは、FROM
部におけるかっこのサポートの追加と同時に、5.0
で修正する予定である。
マルチステートメントトランザクションを実行している
BDB
テーブルでは、それらのトランザクションすべてが完了するまで
ALTER TABLE
を実行しない(ほとんどの場合、トランザクションは無視される)。
ANALYZE TABLE
、OPTIMIZE
TABLE
、および REPAIR
TABLE
によって、INSERT
DELAYED
を使用しているテーブルで問題が発生することがある。
LOCK TABLE ...
および FLUSH
TABLES ...
を実行しても、処理が進行中の未完了のトランザクションがテーブルにないとは限らない。
BDB
テーブルを開くのに多少時間がかかる。データベースに多数の
BDB テーブルがあるときに、-A
オプションを使用していない場合や
rehash
を使用している場合、データベース上で
mysql
クライアントを使用するのに時間がかかる。これは、大きなテーブルキャッシュがある場合に特に顕著である。
レプリケーションではクエリレベルのログが使用される。つまり、マスタによって、実行されたクエリがバイナリログに書き込まれる。これは非常に速く、コンパクトで効率的なログ方法であり、ほとんどの場合に問題なく機能する。実際に発生した例を聞いたことはないが、データの変更が非決定論的、つまりクエリオプティマイザの判断で行われるようにクエリが設計されている場合(レプリケーションの外部でも、通常は適切な方法でない)、マスタおよびスレーブのデータが理論的に異なる可能性がある。たとえば、次のような場合である。
AUTO_INCREMENT
カラムにゼロまたは NULL
値を挿入する CREATE ...
SELECT
または INSERT ...
SELECT
ステートメント。
ON DELETE CASCADE
プロパティが設定された外部キーがあるテーブルからレコードを削除する場合の
DELETE
。
挿入されるデータに重複するキー値がある場合の
REPLACE ...
SELECT
、INSERT IGNORE ...
SELECT
。
これらのクエリすべてに決定論的順序を保証する
ORDER BY
節がない場合のみである。
実際、たとえば、ORDER BY
がない INSERT ... SELECT
の場合、SELECT
は、マスタおよびスレーブでオプティマイザによって行われる選択によっては、異なる順序でレコードを返すことがある(その結果、レコードに異なるランクが設定され、auto_increment
カラムで異なる数を取得することになる)。マスタとスレーブでクエリが異なって最適化されるのは、以下の場合のみである。
2
つのクエリによって使用されるファイルが、正確には同じでない。たとえば、OPTIMIZE
TABLE
がマスタテーブルでは実行されたが、スレーブテーブルでは実行されなかった場合などである(これを修正するために、MySQL
4.1.1
以降では、OPTIMIZE
、ANALYZE
、および
REPAIR
がバイナリログに書き込まれる)。
マスタとスレーブで異なるストレージエンジンにテーブルが格納されている(スレーブとマスタで異なるストレージエンジンを使用することができる。たとえば、スレーブの方が使用可能なディスク領域が少ない場合、マスタでは InnoDB を使用し、スレーブでは MyISAM を使用することができる)。
MySQL
バッファのサイズ(key_buffer_size
など)が、マスタとスレーブで異なる。
マスタとスレーブで異なる MySQL バージョンが実行されており、オプティマイザのコードがこれらのバージョン間で異なる。
また、この問題は、mysqlbinlog|mysql
によるデータベースのリストアにも影響を及ぼすことがある。
あらゆるケースでこの問題を回避する最も簡単な方法は、このような非決定論的なクエリに
ORDER BY
節を追加して、レコードが常に同じ順序で格納/変更されるようにすることである。今後の
MySQL
バージョンでは、必要に応じて自動的に
ORDER BY
節が追加されるようにする予定である。
以下の既知の問題は、近いうちに修正されます。
テンポラリテーブルを使用して解決する必要があるクエリで
RPAD
関数、または最終的に右側に空白を追加する他の文字列関数を使用した場合、すべての結果文字列で右側の空白が削除される。次に、このクエリの例を示す。
SELECT RPAD(t1.field1, 50, ' ') AS f2,
RPAD(t2.field2, 50, ' ') AS f1 FROM table1 as t1 LEFT JOIN
table2 AS t2 ON t1.record=t2.joinID ORDER BY
t2.record;
このバグの最終的な結果は、生成されるフィールドの右側の空白を取得できなくなることである。
この動作は、すべてのバージョンの MySQL に見られる。
この原因は、テンポラリテーブルとして最初に使用される HEAP テーブルで VARCHAR 型のカラムを処理できないことである。
この動作は、4.1 シリーズのいずれかのリリースで修正される予定である。
テーブル定義ファイルの格納方法のために、テーブル名、カラム名、または列挙に文字
255(CHAR(255)
)を使用することができない。これは、新しいテーブル定義ファイル形式が導入されるバージョン
5.1 で修正される予定である。
SET CHARACTER SET
を使用した場合、データベース名、テーブル名、およびカラム名で変換された文字を使用することができない。
LIKE ... ESCAPE
で
ESCAPE
とともに
_
または %
を使用することができない。
DECIMAL
型のカラムにさまざまな形式(+01.00、1.00、01.00)で数字が格納されている場合、GROUP
BY
によって各値が異なる値として見なされることがある。
WHERE
なしで DELETE FROM
merge_table
を使用すると、テーブルに対するマッピングのみが消去され、マップされたテーブルの内容は一切削除されない。
MIT-pthreads を使用した場合、別のディレクトリにサーバを構築することができない。これには MIT-pthreads の変更が必要なので、これを修正する予定はない。 See 項2.3.6. 「MIT-pthreads に関する注意事項」。
GROUP BY
、ORDER
BY
、または DISTINCT
で
BLOB
値を ``確実に''
使用することができない。これらの場合に
BLOB
値を比較した場合、最初の
max_sort_length
バイト(デフォルトは
1024)のみが使用される。これは、mysqld
の -O max_sort_length
オプションを使用して変更することができる。ほとんどの場合の回避策は、SELECT
DISTINCT LEFT(blob,2048) FROM tbl_name
のように部分文字列を使用することである。
BIGINT
または
DOUBLE
で計算が実行される(通常はどちらの長さも
64
ビット)。取得する精度は関数によって異なる。一般的なルールとして、ビット関数は
BIGINT
精度、IF
および ELT()
は
BIGINT
または
DOUBLE
精度、残りは
DOUBLE
精度で実行される。ビットフィールド以外については、符号なしの長い値が
63
ビット(9223372036854775807)より大きい値に解決される場合、そのような値を使用しないようにする必要がある。MySQL
サーバ 4.0 では、3.23 に比べて
BIGINT
の処理が向上している。
BLOB
型および
TEXT
型のカラムを除くすべての文字列カラムで、取得時に後続のスペースすべてが自動的に削除される。CHAR
型の場合、これには問題はなく、SQL-92
に準拠した機能と見なすことができる。バグは、MySQL
サーバで VARCHAR
型のカラムが同様に処理される点である。
1 つのテーブルに ENUM
型および SET
型のカラムを 255
個までしか作成することができない。
MySQL
では現在、MIN()
、MAX()
、およびその他の集約関数において、ENUM
型と SET
型のカラムがセット内の文字列の相対的な位置ではなく、文字列値によって比較される。
mysqld_safe
によって、mysqld
から
mysqld
ログにすべてのメッセージがリダイレクトされる。これに関する
1 つの問題として、mysqladmin
refresh
を実行してログを閉じた後、もう一度開いた場合、stdout
および stderr
が引き続き元のログにリダイレクトされる点がある。--log
を広範に使用する場合、'hostname'.log
ではなく 'hostname'.err
にログが記録されるように
mysqld_safe
を編集して、元のログを削除し、mysqladmin
refresh
を実行することで、元のログのスペースを簡単に解放できるようにする必要がある。
UPDATE
ステートメントで、カラムが左から右に更新される。更新されたカラムを参照した場合、元の値ではなく更新された値を取得する。たとえば、次のようなコマンドがあるとする。
mysql> UPDATE tbl_name SET KEY=KEY+1,KEY=KEY+1;
この場合、KEY
は
1
ではなく、2
によって更新される。
1 つのクエリで複数のテンポラリテーブルを参照することができるが、特定のテンポラリテーブルを複数回参照することはできない。たとえば、次のクエリは動作しない。
mysql> SELECT * FROM temporary_table, temporary_table AS t2;
RENAME
が、TEMPORARY
テーブル、または MERGE
テーブル内で使用されているテーブルで動作しない。
結合で '非表示の'
カラムを使用している場合と使用していない場合とで、オプティマイザによって
DISTINCT
が異なって処理されることがある。結合では、非表示のカラムは結果の一部としてカウントされるが(表示されていない場合も同様)、通常のクエリでは、非表示のカラムは
DISTINCT
比較に関連しない。DISTINCT
を実行した場合も非表示のカラムが比較されないように、今後これを変更する予定である。
この例は以下のとおりである。
SELECT DISTINCT mp3id FROM band_downloads WHERE userid = 9 ORDER BY id DESC;
および
SELECT DISTINCT band_downloads.mp3id FROM band_downloads,band_mp3 WHERE band_downloads.userid = 9 AND band_mp3.id = band_downloads.mp3id ORDER BY band_downloads.id DESC;
2 番目の例の場合、MySQL サーバ 3.23.x
では、結果セットで 2
つの同じレコードを取得することがある(非表示の
id
カラムが異なる場合があるため)。
この問題は、結果に ORDER BY カラムがないクエリのみで発生する。これは、SQL-92 では許可されていない。
MySQL
サーバではトランザクションをサポートしないためにデータをロールバック
することができないテーブル型を使用することができるので、MySQL
サーバと他の SQL
サーバでは動作が多少異なる。これは単に、MySQL
サーバでは SQL
コマンドに対してロールバックが実行されないようにするためである。これは、アプリケーションでカラム値をチェックする必要があるときには多少不便な場合があるが、他の方法では非常に困難な最適化を
MySQL
サーバで実行することができるので、実質的には速度が大幅に向上する。
カラムを正しくない値に設定した場合、ロールバックが行われる代わりに、カラムに取りうる値のうち最適な値
が格納される。
数値カラムに範囲外の値を格納しようとした場合、使用可能な最小値または最大値が代わりに格納される。
数値カラムに数字以外で始まる文字列を格納しようとした場合、0 が格納される。
NULL
値を使用することができないカラムに
NULL
を格納しようとした場合、0 または
''
(空白文字列)が代わりに格納される(ただし、この動作は、-DDONT_USE_DEFAULT_FIELDS
コンパイルオプションを使用して変更することができる)。
MySQL では、DATE
型および
DATETIME
型のカラムに正しくない日付値(2000-02-31
や 2000-02-00
など)を格納することができる。その考えは、日付を検証するのは
SQL
サーバの役目ではないというものである。MySQL
で日付を格納し、同じ日付を正確に取得できる場合、その日付は格納される。日付がまったく正しくない(サーバで日付を格納することができない)場合は、特殊な日付値
0000-00-00 がカラムに格納される。
ENUM
型のカラムをサポートされていない値に設定した場合、エラー値である空白文字列
に設定される。数値の場合は、0
に設定される。
SET
型のカラムをサポートされていない値に設定した場合、その値は無視される。
空のセットを返すクエリで
PROCEDURE
を実行した場合、PROCEDURE
によってカラムが変換されないことがある。
MERGE
型のテーブルを作成する際に、基になるテーブルの型に互換性があるかどうかがチェックされない。
MySQL
サーバではまだ、NaN
、-Inf
、および
Inf
値を倍精度で処理することができない。これらを使用した場合、データをエクスポートおよびインポートしようとすると問題が発生する。中間的な解決策として、NaN
を
NULL
(可能な場合)、-Inf
および Inf
をそれぞれ使用可能な最小および最大倍精度
値に変更する必要がある。
ALTER TABLE
を使用して
MERGE
テーブルで使用されているテーブルに
UNIQUE
インデックスを追加した後、ALTER
TABLE
を使用して MERGE
テーブルに通常のインデックスを追加すると、一意でない古いキーがテーブルに存在していた場合、テーブルでキーの順序が変わる。これは、重複キーをできるだけ早く検出できるように、ALTER
TABLE
が UNIQUE
キーを通常のキーの前に配置するためである。
以下は、MySQL の初期のバージョンにおける既知のバグです。
LOCK TABLES
を使用してロックされている多数のテーブルのうちの
1 つのテーブルで DROP TABLE
を実行した場合、ハングスレッドを取得することがある。
以下の場合、コアダンプを取得することがある。
遅延挿入ハンドラがテーブルへの挿入を保留している場合。
WRITE
を含む LOCK
table
。
FLUSH TABLES
。
MySQL サーババージョン 3.23.2
より前は、同じキーで WHERE
を使用してキーを更新した
UPDATE
でエラーが発生することがあった。これは、そのキーがレコードの検索に使用され、同じレコードが複数回検出されることがあったためである。次に例を示す。
UPDATE tbl_name SET KEY=KEY+1 WHERE KEY > 100;
回避策は次のとおりである。
mysql> UPDATE tbl_name SET KEY=KEY+1 WHERE KEY+0 > 100;
これが機能するのは、MySQL サーバでは
WHERE
節内の式にインデックスが使用されないためである。
MySQL サーババージョン 3.23 より前は、すべての数値型が固定小数点型フィールドとして扱われていた。そのため、固定小数点型フィールドの小数部桁数を指定しなければならなかった。すべての結果が、正確な小数部桁数で返されていた。
プラットフォーム固有のバグについては、コンパイルおよび移植に関するセクションを参照してください。 See 項2.3. 「MySQL ソースディストリビューションのインストール」。 See 付録 E. 他システムへの移植。
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.