Go to the first, previous, next, last section, table of contents.


問題とよくあるエラー

MySQL 使用時のよくあるいくつかのエラー

MySQL server has gone away エラー

MySQL server has gone away エラーのもっとも一般的な理由は、サーバ がタイムアウトで接続をクローズしたことです。デフォルトでは、何も起きない 場合、サーバは 8 時間後に接続をクローズします。

スクリプトの場合は、自動的に再接続するためにクライアントからクエリを再発 行する必要があります。

この場合、通常これらのエラーコードを得ます: (OS 依存です)

CR_SERVER_GONE_ERROR クライアントがサーバに質問を送信できなかった。
CR_SERVER_LOST クライアントがサーバに書き込む時にはエラーは発生しなかったが、質問に対する完全な答え(または何らかの答え)が得られなかった。
間違っているか大きすぎるクエリをサーバに送った場合にもこのエラーが発生し ます。mysqld が間違ったブロックを得た場合、クライアントの何かが間違った と見なし、接続をクローズします。大きなクエリが必要な場合、例えば大きな blob で働かせる場合は、mysqld をオプション -O max_query_size=# (デフォルト 65536) で起動することでクエリ制限を増加できます。拡張メモリ は要求によって割り当てられます。そのため、mysqld は大きなクエリを発行し た時や大きな結果行を返す必要のある時だけ、多くのメモリを使用します!

Can't connect to local MySQL server エラー

MySQL クライアントは mysqld サーバに2つの異なる方法で接続できま す: Unix ソケット, これはファイルシステム上のファイル(デフォルト `/tmp/mysql.sock')を通して接続します。または TCP/IP, これはポート番 号を通して接続します。Unix ソケットは TCP/IP よりも速いですが、サーバと 同じコンピュータから接続する時しか使えません。Unix ソケットは、ホスト名 を指定しない場合か、特別なホスト名 'localhost' を指定した場合に使用され ます。

次にエラーのいくつかの理由を挙げます Can't connect to local MySQL server

Out of memory エラー

クエリを行って、次のエラーのようなものを得た場合:

mysql: Out of memory at line 42, 'malloc.c'
mysql: neaded 8136 byte (8k), memory in use: 12481367 bytes (12189k))
ERROR 2008: MySQL client got out of memory                

エラーは MySQL クライアントに関係することに注意してください。エ ラーの理由は単純で、クライアントが結果全体を格納するのに十分なメモリを持っ ていないことです。

Packet too large

クライアントが net_buffer_length よりも大きなブロックを得た時、 Packet too large エラーを発します。

mysql クライアントを使用する場合、mysql --set-variable=net_buffer_length=1m でクライアントを開始することで、バッ ファを大きく設定できます。

The table is full

このエラーはメモリ内一時テーブルが tmp_table_size よりも大きくなっ た時に発生します。この問題を回避するために、mysqld のオプション -O tmp_table_size=# で増加、または、SQL オプション SQL_BIG_TABLES を問題のクエリの前に使用できます。 「SET OPTION 構文」節参照 。

One can also start mysqld with the option: --big-tables. This is exactly the same as using SQL_BIG_TABLES for all queries.

Commands out of sync in client

Commands out of sync; You can't run this command now をクライアン トコード中で得た場合、クライアント関数を間違った順番で呼び出しました!

これは例えば、'mysql_use_result()' を使用していて、'mysql_free_result()' を行う前に新しいクエリの実行を試みた場合に発生します。これはまた、データ を返す2つのクエリの実行を、間に mysql_use_result() や mysql_store_result() 無しで試みた場合にも発生します。

MySQL はフルディスクをどのように扱うか?

ディスクフル条件では MySQL は次のことを行います:

MySQL が一時ファイルを格納する場所

MySQL は一時ファイルを格納する場所として TMPDIR 環境変数の値を 使用します。TMPDIR を設定していなければ、MySQL はシステムのデフォ ルトを使用します。通常は /tmp または /usr/tmp です。TMPDIR が小さ すぎる場合、safe_mysqld を編集して、十分な領域がある他のディレクトリを指 すように TMPDIR を設定すべきです!

MySQL は全ての一時ファイルを '隠しファイル' として生成します。 これは mysqld が終了した場合に、一時ファイルが削除されないことを確実にし ます。隠しファイルを使用する '悪い' 側面は、小さすぎる一時ディスクを一杯 にする大きな一時ファイルを見つけられないことです。

ソート時 (ORDER BY または GROUP BY)、MySQL は通常一つまたは二つ の一時ファイルを使用します。必要な最大のディスク容量は (length_of_what_is_sorted + sizeof(database_pointer)) * number_of_matched_rows * 2 です。 sizeof(database_pointer) は通常4ですが、将来本当に大きなテーブル のために大きくなることもあります。

いくつかの SELECT クエリは一時的な SQL テーブルも生成します。これらは隠 しファイルではなく、SQL_ で始まる名前です。

ALTER TABLE は一時テーブルをオリジナルテーブルと同じディレクトリ 内に生成します。

Access denied? エラー

特権システムがどのように働くか?」節参照 。そして特に 「何故 Access denied エラーになるのか?」節参照 。

一般ユーザで MySQL を動かす方法

mysqld (MySQL サーバ) は誰でも開始し実行することができます。 mysqld をユーザ USER で実行するように変更するためには、次を行なう必要が あります:

root で safe_mysqld を実行させないようにするために行なうことは何もありま せん。

この時点で、あなたの mysqld プロセスはユーザ 'USER' で正常に動作します。 一つのことは変わりません。それはアクセスパーミッションです。デフォルト (パーミッションテーブルインストールスクリプト実行後の権限) では、データベース のアクセスパーミッションはユーザ 'root' だけです。これを変更しないと、そ れはそのままです。root 以外のユーザでログインしている時でも、あなたは MySQL のアクセスは可能です - ただプログラムに -u root を記述す るだけです。コマンドラインで -u root を使用することによって、root で MySQL にアクセスしても、root として、ユーザとしてまたは他の誰化 として起動している MySQL で行なうことは何もないということに注意 してください。MySQL のアクセスパーミッションとユーザベースは、 UNIX ユーザとは完全に別のものです。UNIX ユーザに関係するのは、クライアン トに -u オプションを使用しない場合だけです。この場合、クライアントは MySQL へのログインを、あなたの UNIX ログイン名で試みます。あな たの UNIX マシンそれ自身が安全でない場合は、少なくとも MySQL ア クセステーブルの root ユーザにはパスワードを設定すべきです。どこかの誰かが 'mysql -u root dbname' を行ない、彼が望むことの全てを実行できてしまうからです。

ファイルパーミッションの問題

ファイルパーミッションの問題がある場合、例えば、テーブルの生成時に mysql が次 を出力する場合: "ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13)", 環境変数 UMASK が間違った値を持っています。 デフォルト umask は 0664 です。次のように修正してください:

UMASK=432
export UMASK
./bin/safe_mysqld

File not found

ERROR '...' not found (Errcode: 23) またはなんらかの他の errcode 23 のエラーを MySQL から得た場合、これは MySQL に十分なファイル記述子が割り当てられなかったことを意味し ます。perror # はさらに読みやすい形式のエラーメッセージを与えます。

`safe_mysqld' 内にコメントされた行 ulimit -n 256 があります。 もちろん、このコメントは削除でき、望むなら値を増加または減少させることが できます。テーブルキャッシュをより小さくすることもできます: safe_mysqld -O table_cache=32 (デフォルトは 64)。

DATE 項目の使用の問題

日付の形式は 'YYYY-MM-DD' です。ANSI SQL に従って実際には他のは許されま せん。更新または WHERE 節内ではこの形式を使用すべきです。すなわち: select * from table_1 where date >= '1997-05-05';

利便のため、MySQL は数値の文脈で使用されると、日付を自動的に数 値に変換します。これは更新と TIMESTAMP, DATE または DATETIME 項目での WHERE 時に、'ゆるやかな' 文字列の形式を許 すために十分スマートです。

特別な日付 '0000-00-00' は 0000-00-00 として格納され取り出されます。 MyODBC を通して '0000-00-00' 日付を使用する時、MyODBC 2.50.12 以上では自 動的に NULL に変換されます。ODBC はこの日付の種類を扱えないためです。

これは次が働くことを意味します:

insert into table_1 (idate) values (19970505) ;
insert into table_1 (idate) values ('19970505') ;
insert into table_1 (idate) values ('97-05-05');
insert into table_1 (idate) values ('1997.05.05');
insert into table_1 (idate) values ('1997 05 05');
insert into table_1 (idate) values ('0000-00-00');

select idate from table_1 where idate >= '1997-05-05';
select idate from table_1 where idate >= 19970505;
select mod(idate,100)1 from table_1 where idate >= 19970505;
select idate from table_1 where idate >= '19970505';

次は働きません:

select idate from table_1 where strcmp(idate,'19970505')=0;
'19970505' は文字列として '1997-05-05' と比較されるからです。

MySQL は日付が正しいかどうかをチェックしないことに注意してくだ さい。間違った日付(例えば 1998-2-31)を格納すると、その間違った日付が格納 されます。日付が全体的に不可能な場合、0 が日付項目に格納されます。これは 主に速度の問題で、日付のチェックはサーバではなくアプリケーションでと我々 は考えています。

検索時のケース依存

デフォルトでは MySQL 項目はケース非依存です (しかし、ケース非依 存にならないいくつかの文字セットはあります)。これは、column like 'a%'; で検索した場合、A または a で始まる全ての項目を得ることを 意味します。検索をケース依存にしたいのなら、始まりをチェックするには INDEX(column, "A")=0 のようなことを、また、文字列全体が同じかどう かには STRCMP(column, "A") = 0 を使用してください。

単純な比較操作 >=, >, =, <, <=、ソートそしてグループ化は、文字 'sort value' 上で行われます。同じソート値の文字 (like E, e and -A�) $)Bは同じ文字と して扱われます!

LIKE 比較は各文字の大文字で行われます (E == e but E <> -A�)$)B

column をいつでもケース依存で扱いたい場合は、それを BINARY として宣言してください。 「CREATE TABLE 構文」節参照 。

big5 エンコーディングと呼ばれる中国語データを使用している場合は、全ての 文字項目を BINARY にしてください。これは、big5 エンコーディング文 字のソート順が ascii コードが基になっているため、機能します。

NULL での問題

SQL の初心者のありがちな混乱は、NULL が空文字列 '' と同じ物だと考えるこ とです。これは正しくありません! 例えば、次のステートメントは全く別のも のです:

INSERT INTO my_table (name,phone) values ("my",NULL);
INSERT INTO my_table (name,phone) values ("my","");

初めのは NULL 値をアドレスに挿入し、二番目のは空文字列をアドレスに挿入し ます。初めのは '電話番号を知らない' と見なされ、二番目のは '彼女は電話を 持っていない' と見なされます。

SQL では、 NULL は他の全ての値(たとえ NULL でも)と比較した時に、常に偽に なる値です。NULL を含む式は、特に断りがなければ、常に NULL 値を生成しま す。次の項目は全て NULL を返します:

SELECT NULL,1+NULL,CONCAT('Invisible',NULL);

NULL を持つ項目を検索したい場合は、IS NULL テストを使用しなくてはいけま せん。次は NULL 電話番号と空の電話番号を見つける方法を示しています:

SELECT * from my_table where phone IS NULL;
SELECT * from my_table where phone = "";

MySQL では、他の多くの SQL サーバのように、NULL 値を持つ インデックス項目を持てません。これらの項目は NOT NULL と宣言しな くてはいけません。

LOAD DATA INFILE でデータを読み込むときは、空の項目は '' で更新さ れます。項目を NULL 値にしたい場合は、テキストファイル中に NULL または \N を使用すべきです。

ORDER BY 使用時、NULL 値は最初に提示されます(DESC 未使用時)。 GROUP BY 使用時、全ての NULL 値は等しいと見なされます。

NULL 処理を手助けするため、次の関数を使用できます: IS NULL, IS NOT NULL, IFNULL()


Go to the first, previous, next, last section, table of contents.