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

21 問題とよくあるエラー

This chapter lists some common problems and error messages that users have run into. You will learn how to figure out what the problem is, and what to do to solve it. You will also find proper solutions to some common problems.

21.1 How to Determine What Is Causing Problems

When you run into problems, the first thing you should do is to find out which program / piece of equipment is causing problems:

If after you have examined all other possibilities and you have concluded that it's the MySQL server or a MySQL client that is causing the problem, it's time to do a bug report for our mailing list or our support team. In the bug report, try to give a very detailed description of how the system is behaving and what you think is happening. You should also state why you think it's MySQL that is causing the problems. Take into consideration all the situations in this chapter. State any problems exactly how they appear when you examine your system. Use the 'cut and paste' method for any output and/or error messages from programs and/or log files!

Try to describe in detail which program is not working and all symptoms you see! We have in the past received many bug reports that just state "the system doesn't work". This doesn't provide us with any information about what could be the problem.

If a program fails, it's always useful to know:

When sending a bug report, you should of follow the outlines described in this manual. 「2.2 質問またはバグ報告」節参照.

21.1.1 MySQL がクラッシュする場合に行うこと

全ての MySQL バージョンはリリースの前に多くのプラットフォームで テストされます。 これは MySQL にいかなるバグもないということを 意味しますが、発見するのが困難で、わずかなバグがあるかもしれません。 もし問題があった場合、何がシステムをクラッシュしているかを見つけようとする事は、 問題を早く修正するためのより良い機会でもあります。

まず最初に, その問題で mysqld デーモンが死ななければならないかどうかか, また はその問題がクライアントで処理しなければならないかどうかを調べるべきです。 mysqladmin version を実行することにより、 mysqld サーバーが どれぐらい稼働していたかわかります。 もし mysqld が死んでいたなら、 を実行することによってあるのかをチェックすることができます. mysqldが死んだなら、 その原因を `mysql-data-directory/`hostname`.err' で見つけれるかもしれません。 「23.1 The Error Log」節参照.

Many crashes of MySQL are caused by corrupted index / data files. MySQL will update the data on disk, with the write() system call, after every SQL statement and before the client is notified about the result. (This is not true if you are running with delayed_key_writes, in which case only the data is written.) This means that the data is safe even if mysqld crashes, as the OS will ensure that the not flushed data is written to disk. You can force MySQL to sync everything to disk after every SQL command by starting mysqld with --flush.

The above means that normally you shouldn't get corrupted tables unless:

何かがクラッシュする理由を知るのは非常に難しいので、まず、他の人で動くも のがあなたでクラッシュするのかどうかをチェックしてください。次のことを行っ てください。

21.2 Problems When Linking with the MySQL Client Library

If you are linking your program and you get errors for unreferenced symbols that start with mysql_, like the following:

/tmp/ccFKsdPa.o: In function `main':
/tmp/ccFKsdPa.o(.text+0xb): undefined reference to `mysql_init'
/tmp/ccFKsdPa.o(.text+0x31): undefined reference to `mysql_real_connect'
/tmp/ccFKsdPa.o(.text+0x57): undefined reference to `mysql_real_connect'
/tmp/ccFKsdPa.o(.text+0x69): undefined reference to `mysql_error'
/tmp/ccFKsdPa.o(.text+0x9a): undefined reference to `mysql_close'

you should be able to solve this by adding -Lpath-to-the-mysql-library -lmysqlclient LAST on your link line.

If you get undefined reference errors for the uncompress or compress function, add -lgz LAST on your link line and try again!

If you get undefined reference errors for functions that should exist on your system, like connect, check the man page for the function in question, for which libraries you should add to the link line!

If you get undefined reference errors for functions that don't exist on your system, like the following:

mf_format.o(.text+0x201): undefined reference to `__lxstat'

it usually means that your library is compiled on a system that is not 100 % compatible with yours. In this case you should download the latest MySQL source distribution and compile this yourself. 「4.7 MySQL ソースディストリビューションのインストール」節参照.

If you are trying to run a program and you then get errors for unreferenced symbols that start with mysql_ or that the mysqlclient library can't be found, this means that your system can't find the share libmysqlclient.so library.

The fix for this is to tell your system to search after shared libraries where the library is located by one of the following methods:

Another way to solve this problem is to link your program statically, with -static, or by removing the dynamic MySQL libraries before linking your code. In the second case you should be sure that no other programs are using the dynamic libraries!

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

This section lists some errors that users frequently get. You will find descriptions of the errors, and how to solve the problem here.

21.3.1 Access denied Error

6.8 特権システムはどのように動くか?」節参照, and especially. 「6.15 何故 Access denied エラーになるのか」節参照.

21.3.2 MySQL server has gone away エラー

このセクションは Lost connection to server during query エラーに関することもカバーします。

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

Another common reason to receive the MySQL server has gone away error is because you have issued a ``close'' on your MySQL connection and then tried to run a query on the closed connection.

mysqladmin version を実行することで MySQL が死んでいるかどうか、 また uptime はどれぐらいか、チェックできます。

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

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

CR_SERVER_GONE_ERROR クライアントがサーバーに問い合わせを送ることができなかった
CR_SERVER_LOST クライアントがサーバーに書き込みを行ったときにはエラーは無かったけれども、問い合わせに対して完全に回答が返ってこない

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

21.3.3 Can't connect to [local] MySQL server エラー

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

On Windows you can connect only with TCP/IP if the mysqld server is running on Win95/Win98. If it's running on NT, you can also connect with named pipes. The name of the named pipe is MySQL. If you don't give a hostname when connecting to mysqld, a MySQL client will first try to connect to the named pipe, and if this doesn't work it will connect to the TCP/IP port. You can force the use of named pipes on Windows by using . as the hostname.

(2002) Can't connect to ... エラーは、通常、MySQL サーバーが システム上に走っていないか、あなたが、間違ったソケットファイルや TCP/IP ポートを使用して mysqld に接続しようとする場合におきます。

Start by check サーバー上に mysqld というプロセスが走っているか ( ps を使用して。 Windows の場合はタスクマネージャでみて) 確認することから開始してください! 「4.16.2 MySQL サーバー起動時の問題」節参照.

mysqld プロセスが走っているなら、違う接続を試すことでサーバーを 確認することができます(もちろん、ポート番号とソケットのパスはあなたが セットアップしたものとは違うでしょう):

shell> mysqladmin version
shell> mysqladmin variables
shell> mysqladmin -h `hostname` version variables
shell> mysqladmin -h `hostname` --port=3306 version
shell> mysqladmin -h 'ip for your host' version
shell> mysqladmin --socket=/tmp/mysql.sock version

hostname コマンドはフォワードクオートでなくバッククオテーションで 囲んでいることに注意してください; これは ホスト名 (カレントのホスト名) を mysqladmin コマンドに与えます。

Can't connect to local MySQL server エラーが起こりうる理由として:

もし Can't connect to MySQL server on some_hostname エラーの場合, 何が問題なのかを見つけるために、以下の手順を踏みます:

21.3.4 Host '...' is blocked エラー


Host 'hostname' is blocked because of many connection errors.
Unblock with 'mysqladmin flush-hosts'

これは mysqld が多くの 'hostname' ホストからの接続エラー(max_connect_errors) を受けた場合に発生します。 この max_connect_errors 大量発生後、mysqld は何か(クラッカーによるサーバーへのアタックなど)が起こったと判断し、このホストからの接続をいっさい拒否するようにします。 これを解除するには、mysqladmin flush-hosts コマンドを実行します。

デフォルトでは、10回の接続エラーが発生した場合に、mysqld はそのホストを拒否します。 この値は以下のようにして簡単に変更できます:

shell> safe_mysqld -O max_connect_errors=10000 &

もしこのエラーがあるホストに対して発生するならば、まず最初にそのホストからの TCP/IP 接続に不具合がないかチェックしてください。 もし TCP/IP 接続が動作していないようなら、 max_connect_errors 値を増やすことはよくないことです!

21.3.5 Too many connections エラー

もし MySQL に接続しようとして Too many connections となった場合、 これは既に max_connections 分、クライアントから mysqld サーバーへの 接続が行われています。

もしデフォルトの100よりも多い接続を必要とするならば、 max_connections 変数に多くの値を与えて、mysqld を リスタートしなくてはなりません。

実際は、mysqld は (max_connections+1) 個のクライアントからの接続を許しています。 最後の1個は、 process 権限をもつユーザーのために取ってあります。 By not giving this privilege to normal users (they shouldn't need this), an administrator with this privilege can log in and use SHOW PROCESSLIST to find out what could be wrong. 「7.28 SHOW 構文」節参照.

The maximum number of connects MySQL is depending on how good the thread library is on a given platform. Linux or Solaris should be able to support 500-1000 simultaneous connections, depending on how much RAM you have and what your clients are doing.

21.3.6 Some non-transactional changed tables couldn't be rolled back Error

If you get the error/warning: Warning: Some non-transactional changed tables couldn't be rolled back when trying to do a ROLLBACK, this means that some of the tables you used in the transaction didn't support transactions. These non-transactional tables will not be affected by the ROLLBACK statement.

The most typical case when this happens is when you have tried to create a table of a type that is not supported by your mysqld binary. If mysqld doesn't support a table type (or if the table type is disabled by a startup option) , it will instead create the table type with the table type that is most resembles to the one you requested, probably MyISAM.

You can check the table type for a table by doing:


You can check the extensions your mysqld binary supports by doing:

show variables like 'have_%'. 「7.28.4 SHOW VARIABLES」節参照.

21.3.7 Out of memory エラー


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

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

この問題を解決するにあたり、まず最初にクエリーが正しいか確認してください。 そのクエリーは大量の結果を返すものでしょうか? もしそうなら、mysql --quick を使用してください。 これは結果を取り出すために mysql_use_result() を使用します。 これはクライアントのロード不足を補います(サーバーより多い領域は取れません)。

21.3.8 Packet too large エラー

MySQL クライアントが max_allowed_packet よりも大きなブロックを mysqld サーバーから得た時、Packet too large エラーを発します。

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

もし(DBI のように)最大パケットサイズを指定できないクライアントを使用している場合、 パケットサイズを指定してサーバーを立ち上げ直します。 これは mysqld のオプションの max_allowed_packet に大きな値を設定することで行います。 例えば、 BLOB 型の許容範囲いっぱいのデータをテーブルに入れる場合、 --set-variable=max_allowed_packet=16M オプションを指定してサーバーを起動する必要があります。

21.3.9 Communication Errors / Aborted Connection

If you find errors like the following in your error log.

010301 14:38:23  Aborted connection 854 to db: 'users' user: 'josh'

23.1 The Error Log」節参照.

This means that something of the following has happened:

When the above happens, the server variable Aborted_clients is incremented.

The server variable Aborted_connects is incremented when:

Note that the above could indicate that someone is trying to break into your database!

7.28.4 SHOW VARIABLES」節参照.

Other reasons for problems with Aborted clients / Aborted connections.

21.3.10 The table is full エラー

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

mysqld--big-tables オプション指定して起動します。 これは全てのクエリーに対して SQL_BIG_TABLES を使用するのと同じです。

In MySQL Version 3.23, in-memory temporary tables will automatically be converted to a disk-based MyISAM table after the table size gets bigger than tmp_table_size.

21.3.11 Can't create/write to file Error

If you get an error for some queries of type:

Can't create/write to file '\\sqla3fe_0.ism'.

this means that MySQL can't create a temporary file for the result set in the given temporary directory. (The above error is a typical error message on Windows, and the Unix error message is similar.) The fix is to start mysqld with --tmpdir=path or to add to your option file:


assuming that the `c:\\temp' directory exists. 「4.16.5 オプションファイル ( my.cnf )」節参照.

Check also the error code that you get with perror. One reason may also be a disk full error;

shell> perror 28
Error code  28:  No space left on device

21.3.12 Commands out of sync Error 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() 無しで試みた場合にも発生します。

21.3.13 Ignoring user エラー


Found wrong password for user: 'some_user@some_host'; Ignoring user

これは mysqld の開始または 'reload' 時に user テーブル内に正しいパスワー ドを持たないエントリを見つけたことを意味します。 これは単にエントリが許可システムに拒否されているだけです。


21.3.14 Table 'xxx' doesn't exist Error

もし Table 'xxx' doesn't existCan't find file: 'xxx' (errno: 2) エラーが出た場合、使用しているデータベースに xxx という名前のテーブルが 見付からなかったことを示します

データベースとテーブルの保存に、MySQL はディレクトリとファイルを使用し、 データベースとテーブルの名前はケース依存です! (Windows ではデータベースとテーブル名はケース非依存です。 クエリ中のテーブルに対する問い合わせは全て、同じケースで書かなくてはなりません!)

SHOW TABLES を使用してデータベースのテーブルを確認できます. 「7.28 SHOW 構文」節参照.

21.3.15 Can't initialize character set xxx error.

If you get an error like:

MySQL Connection Failed: Can't initialize character set xxx

This means one of the following things:

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

ディスクフルが起きた場合 MySQL は次のことを行います:


Exceptions to the above behaveour is when you use REPAIR or OPTIMIZE or when the indexes are created in a batch after an LOAD DATA INFILE or after an ALTER TABLE statement.

All of the above commands may use big temporary files that left to themself would cause big problems for the rest of the system. If MySQL gets disk full while doing any of the above operations, it will remove the big temporary files and mark the table as crashed (except for ALTER TABLE, in which the old table will be left unchanged).

21.5 テキストファイルから SQL コマンドを実行

mysql クライアントは以下のようにして対話的に使用します:

shell> mysql database

しかし SQL コマンドをファイルに書いておき、それを mysql に読み込ませることができます。 テキストファイル `text_file' に実行したいコマンドを書いておき、 以下のようにして mysql を起動します:

shell> mysql database < text_file

テキストファイルの先頭に USE db_name 構文を書くこともできます。 この場合、データベース名をコマンドラインに与える必要は無く、以下のようにできます:

shell> mysql < text_file

15.1 様々な MySQL プログラムの概要」節参照.

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

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

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 は一時テーブルをオリジナルテーブルと同じディレクトリ 内に生成します。

21.7 `/tmp/mysql.sock' を削除から守る方法

もし誰かに MySQL のソケットファイル `/tmp/mysql.sock' が消されるなら、 ほとんどの UNIX がそうであるように、 `/tmp'sticky ビットをたてて保護します。 root でログインして、以下のようにします:

shell> chmod +t /tmp

これはファイルのオーナーとスーパーユーザー(root) のみが、 `/tmp' のファイルを消すことができます。

sticky ビットが立っているか確認するには、 ls -ld /tmp を行います。 パーミッションの最後のビットが t ならば、セットされています。

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

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

  1. サーバーを止めます (use mysqladmin shutdown).
  2. user_name が読み書きできるように、データベースディレクトリとその中のファイルのパーミッションを変更します。(これは UNIX root ユーザーで実行する必要があるでしょう):
    shell> chown -R user_name /path/to/mysql/datadir
    MySQL データベースディレクトリのディレクトリーやファイルがシンボリックリンクの場合、 これらリンクの先のディレクトリとファイルも変更します。chown -R はシンボリックリンク先を変更してくれません。
  3. ユーザ user_name でサーバを起動します。または MySQL 3.22 以降を使用する 場合は、mysqld を UNIX root で起動し --user=user_name スイッチを使用します。 mysqld は、接続を許可する前に、与えられた UNIX user user_name で実行するように切り替えます。
  4. システム再起動時、 mysql.server を使用して mysqld を起動する場合、ユーザ user_name への su を行なうようにまたは --user スイッチを使用して mysqld を起動するように mysql.server を 変更すべきです。 (No changes to safe_mysqld are necessary.)

この時点で、あなたの mysqld プロセスは UNIX user user_name で正常に動作します。

一つのことは変わりません。それは権限許可テーブルです。デフォルト (パーミッションテーブルインストールスクリプトmysql_install_db実行後の権限) では、mysqlデータベースへのアクセスやデータベースの作成、破棄はユーザ MySQL user root だけです。 これを変更しないと、それはそのままです。 root 以外の UNIX userでログインしている時でも、あなたは MySQL root user としてアクセスは可能です - ただプログラムに -u root をクライアントプログラムにオプション指定するだけです。

MySQLroot としてアクセスするには、 コマンドラインで -u root を使用するだけでいいことに注意してください。 UNIX root user や MySQL を走らせている UNIX ユーザーである必要はないことに注意してください。 MySQL のアクセスパーミッションとMySQL のユーザは、 UNIX ユーザとは完全に別のものです。UNIX ユーザに関係するのは、クライアン トに -u オプションを使用しない場合だけです。この場合、クライアントは MySQL へのログインを、あなたの UNIX ログイン名で試みます。

あなたの UNIX マシンそれ自身が安全でない場合は、少なくとも MySQL ア クセステーブルの MySQL root ユーザにはパスワードを設定すべきです。 どこかの誰かが mysql -u root db_name を行ない、彼が望むことの全てを実行できてしまうからです。

21.9 忘れたパスワードをリセットする

もし MySQLroot ユーザーのパスワードを忘れた場合、 これを以下のようにして入れ直すことが可能です。

  1. mysqld サーバーを kill で落とす。 (kill -9 ではありません!) PID 番号は通常 MySQL データディレクトリに .pid ファイルとして 書かれています:
    kill `cat /mysql-data-directory/hostname.pid`
    これを、 UNIX root ユーザーか、MySQL サーバーを実行した ユーザーで行います。
  2. mysqld--skip-grant-tables オプションで起動。
  3. mysql -h hostname mysqlmysqld サーバーに接続し、 GRANT コマンドでパスワードを変更します。 「7.35 GRANTREVOKE 構文」節参照. mysqladmin -h hostname -u user password 'new password' でも変更可能です。
  4. 許可テーブルを読み込みます: mysqladmin -h hostname flush-privileges か、SQL 文の FLUSH PRIVILEGES を実行します。

Note that after you started mysqld with --skip-grant-tables, any usage of GRANT commands will give you an Unknown command error until you have executed FLUSH PRIVILEGES.

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

ファイルパーミッションの問題がある場合、 例えば、テーブルの生成時に mysql が次を出力する場合:

ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13)

これは UMASK 環境変数が mysqld 起動時に間違ってセットされていると考えられます。 デフォルトの umask は 0660 です. これは以下のようにして safe_mysqld 立ち上げ時に変更できます:

shell> UMASK=384  # = 600 in octal
shell> export UMASK
shell> /path/to/safe_mysqld &

By default MySQL will create database and RAID directories with permission type 0700. You can modify this behavior by setting the UMASK_DIR variable. If you set this, new directories are created with the combined UMASK and UMASK_DIR. For example, if you want to give group access to all new directories, you can do:

shell> UMASK_DIR=504  # = 770 in octal
shell> export UMASK_DIR
shell> /path/to/safe_mysqld &

In MySQL Version 3.23.25 and above, MySQL assumes that the value for UMASK and UMASK_DIR is in octal if it starts with a zero.

A Environment Variables」節参照.

21.11 File not found

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

shell> perror 23
File table overflow
shell> perror 24
Too many open files

これは mysqld が多くのファイルを開こうとしたことに起因します。 mysqld に一度に開くファイル数を多く開かないようしたり、あるいは、 mysqld が扱えるファイル記述子の数を与えたりできます。

mysqld が一度に開くファイルの数を少なくするには、-O table_cache=32 オプション(デフォルトは64)を safe_mysqld に与えることで可能です。 また、max_connections の値(デフォルトは90)を少なくするならば、開くファイル数も少なくできます。

To change the number of file descriptors available to mysqld, you can use the option --open-files-limit=# to safe_mysqld or -O open-files-limit=# to mysqld. 「7.28.4 SHOW VARIABLES」節参照. The easiest way to do that is to add the option to your option file. 「4.16.5 オプションファイル ( my.cnf )」節参照. If you have an old mysqld version that doesn't support this, you can edit the safe_mysqld script. There is a commented-out line ulimit -n 256 in the script. You can remove the '#' character to uncomment this line, and change the number 256 to affect the number of file descriptors available to mysqld.

ulimitopen-files-limit はオペレーティングシステムの 制限内でしかファイル記述子の数を指定できません。 There is also a 'hard' limit that can only be overrided if you start safe_mysqld or mysqld as root (Just remember that you need to also use the --user=.. option in this case). もし OS の制限以上にファイル記述子のオープン数を増やしたい場合、 お使いのオペレーティングシステムのドキュメントを見て対処してください。

tcsh を使用している場合は ulimit は動かないことに注意してください! tcsh は現在の制限をあなたが問い合わせても、違った値を報告するでしょう。 この場合、safe_mysqldsh で起動すべきです!

21.12 DATE フィールド使用時の問題

日付 DATE の形式は 'YYYY-MM-DD' です。ANSI SQL に従って実際には他のは許されま せん。更新または SELECT 文中の WHERE 節内ではこの形式を使用すべきです。すなわち:

mysql> SELECT * FROM tbl_name WHERE date >= '1997-05-05';

利便のため MySQL は、日付が数値の文脈で使用されると、日付を自動的に数 値に変換します。これにより、更新と TIMESTAMP, DATE または DATETIME フィールドでの WHERE 時に、わりと自由に日付を指定することができます。 (この記述を許すため、句読記号を日付のセパレーターとして使用します。 例えば、'1998-08-15''1998#08#15' は同一です.) もしろんセパレーターのない記述(例:'19980815')も日付として変換してくれます。

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


mysql> INSERT INTO tbl_name (idate) VALUES (19970505);
mysql> INSERT INTO tbl_name (idate) VALUES ('19970505');
mysql> INSERT INTO tbl_name (idate) VALUES ('97-05-05');
mysql> INSERT INTO tbl_name (idate) VALUES ('1997.05.05');
mysql> INSERT INTO tbl_name (idate) VALUES ('1997 05 05');
mysql> INSERT INTO tbl_name (idate) VALUES ('0000-00-00');

mysql> SELECT idate FROM tbl_name WHERE idate >= '1997-05-05';
mysql> SELECT idate FROM tbl_name WHERE idate >= 19970505;
mysql> SELECT mod(idate,100) FROM tbl_name WHERE idate >= 19970505;
mysql> SELECT idate FROM tbl_name WHERE idate >= '19970505';


mysql> SELECT idate FROM tbl_name WHERE STRCMP(idate,'19970505')=0;

STRCMP() は文字列関数で、idate を文字に変換して、文字比較を行います。 '19970505' は日付には変換してくれず、日付の比較も行いません。

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

21.13 Time Zone Problems

もし SELECT NOW() があなたのローカル時間ではなく GMT を返すなら、 TZ 環境変数をローカルのTimezone に設定しなくてはなりません。 環境変数の設定は、サーバーを実行する前に行われなくてはなりません。 たとえば、safe_mysqldmysql.server スクリプトで 行います。

21.14 検索時のケース依存

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

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

LIKE 比較は各文字の大文字で行われます (E == e but E <> 'e)

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

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

21.15 NULL 値での問題

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

mysql> INSERT INTO my_table (phone) VALUES (NULL);
mysql> INSERT INTO my_table (phone) VALUES ("");

両方の文とも phone フィールドに値を挿入していますが、 初めのは NULL 値を挿入し、二番目のは空文字列を挿入しています。 初めのは ``電話番号を知らない'' と見なされ、二番目のは ``彼女は電話を 持っていない'' と見なされます。

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

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

NULL 値がセットされている項目を検索する場合、 =NULL テストを行わないでください。 これは expr = NULL が FALSE なので、なんの行も返しません。 例えば以下の例:

mysql> SELECT * FROM my_table WHERE phone = NULL;

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

mysql> SELECT * FROM my_table WHERE phone IS NULL;
mysql> SELECT * FROM my_table WHERE phone = "";

MySQL では、他の多くの SQL サーバのように、NULL 値を持つ インデックスフィールドを持てません。これらのフィールドは NOT NULL と宣言しな くてはいけません。 インデックスフィールドには、NULL を設定することはできません。

LOAD DATA INFILE でデータを読み込むときは、空のフィールドは '' で更新されます。 項目を NULL 値にしたい場合は、テキストファイル中に \N を使用すべきです。 リテラルとしての 'NULL' 語が、ある状況下で使用されています。 「7.23 LOAD DATA INFILE構文」節参照.

ORDER BY 使用時, NULL 値は最初に提示されます. DESC を使用して降順にソートする時、NULL 値は最後になります。 GROUP BY 使用時, 全ての NULL 値は等しいと見なされます。

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

いくつかの項目型では、NULL 値はハンドルとして扱われます。 もしテーブル内の最初の TIMESTAMP 項に NULL を挿入するなら、 現在の日付と時刻が挿入されます。もし AUTO_INCREMENT 項にNULL 値を挿入するなら、 次のシーケンス番号が挿入されます。

21.16 alias の問題

GROUP BY, ORDER BY, HAVING 節において 項目を参照するに当たりエイリアスが使用できます。 エイリアスは項目としてより良い名称を与えるのに使用されます:

SELECT SQRT(a*b) as rt FROM table_name GROUP BY rt HAVING rt > 0;
SELECT id,COUNT(*) AS cnt FROM table_name GROUP BY id HAVING cnt > 0;
SELECT id AS "Customer identity" FROM table_name;

ANSI SQL が WHERE 節内でエイリアスを参照することを 許可していないことに注意してください。これは WHERE が実行される時点で 項目の値がまだ決定されていないからです。例えば、以下のクエリは あやまりです

SELECT id,COUNT(*) AS cnt FROM table_name WHERE cnt > 0 GROUP BY id;

どの行が GROUP BY に含まれるかを決めるために WHERE 構文が 実行される一方で、 得られた結果のどの行を使うか確定するために HAVING が使用されます。

21.17 Deleting Rows from Related Tables

MySQL は現在 sub-select は未サポートで、また DELETE 構文で複数のテーブルを扱う事もサポートしていません。 したがって、2つのテーブルに関連するレコードを消すには、以下のようにして行います:

  1. いくつかの WHERE 条件を使用して、基本となるテーブルから行を SELECT
  2. 同じ条件下で、基本となるテーブルに含まれる行を DELETE
  3. DELETE FROM related_table WHERE related_column IN (selected_rows).

related_column のクエリの合計文字数が、1,048,576 (デフォルトは max_allowed_packet の値) をこえる場合、 それをいくつかに分割して、複数の DELETE 構文にしなくてはなりません。

related_column がインデックスで、100-1000 のrelated_columnだけを消す場合、 よりはやく DELETE できます。 もし related_column がインデックスでない場合、その速度は IN 節の引数の数に無関係になります。

21.18 Solving problems with no matching rows

複雑なクエリーを行って、もしなんの結果も返さなければ、 そのクエリーの何が悪いかを見つけるため、以下の手続きを行います:

  1. EXPLAIN を使用してクエリーをテストし、明白な間違いを見つけます。 「7.29 EXPLAIN 構文 (SELECTについての情報を得る)」節参照.
  2. WHERE 節で使用されているフィールドだけを Select してみます
  3. 結果が返ってくるまで、一つ一つクエリーからテーブルを取り除いていきます。 テーブルが大きい場合、LIMIT 10 をクエリーで使用することは良くありません。
  4. 行にマッチすべきであろう項を SELECT してみます。 その場合、select するのは、上記で最後に取り除いたテーブルに対して行います。
  5. もし FLOATDOUBLE 型のものを数字と比較するなら、 = は使用しないでください!これはほとんどのコンピュータ言語において、 浮動小数点の値はぴったりの値にならないからです。
    mysql> SELECT * FROM table_name WHERE float_column=3.5;
    mysql> SELECT * FROM table_name WHERE float_column between 3.45 and 3.55;
    In most cases, changing the FLOAT to a DOUBLE will fix this!
  6. もしなにも悪いところを見つけることができなかった場合、 小さなテストをつくって mysql test < query.sql を行ってみてください。 mysqldump --quick database tables > query.sql でテストファイルを作成できます。 このファイルをエディターで編集し、いくつかのinsert行を(多すぎるなら)消します。 そしてファイルの最後にselect構文を付け足します。 テストを行うには:
    shell> mysqladmin create test2
    shell> mysql test2 < query.sql
    mysqlbug を使用して mysql@lists.mysql.com にテストを投稿してください。

21.19 Problems with ALTER TABLE.

もし ALTER TABLE が以下のようなエラーで死んだ場合:

Error on rename of './database/name.frm' to './database/B-a.frm' (Errcode: 17)

これは以前の ALTER TABLEMySQL がクラッシュしており、 `A-something'`B-something' という名前の、誤った情報を流している 古いテーブルが存在しています。 この場合、MySQL データディレクトリに入り、A-B- で始まる 名前を持つファイルを全て消します。 (消す代わりにどこかに移動しても構いません。)

ALTER TABLE は以下のように動作します:

もし名称変更の際に問題があると、MySQL は変更を取り消すように動きます。 致命的な問題が起きた場合(ありえませんが)、MySQL は元の古いテーブルを `B-xxx' という名前のままにしておきます。単に名称変更すればデータは戻ります。

21.20 How To Change the Order of Columns in a Table

The whole point of SQL is to abstract the application from the data storage format. You should always specify the order in which you wish to retrieve your data. For example:

SELECT col_name1, col_name2, col_name3 FROM tbl_name;

will return columns in the order col_name1, col_name2, col_name3, whereas:

SELECT col_name1, col_name3, col_name2 FROM tbl_name;

will return columns in the order col_name1, col_name3, col_name2.

You should NEVER, in an application, use SELECT * and retrieve the columns based on their position, because the order in which columns are returned CANNOT be guaranteed over time. A simple change to your database may cause your application to fail rather dramatically.

If you want to change the order of columns anyway, you can do it as follows:

  1. Create a new table with the columns in the right order.
  2. Execute INSERT INTO new_table SELECT fields-in-new_table-order FROM old_table.
  3. Drop or rename old_table.
  4. ALTER TABLE new_table RENAME old_table.

21.21 TEMPORARY TABLE problems

The following are a list of the limitations with TEMPORARY TABLES.

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