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.
When you run into problems, the first thing you should do is to find out which program / piece of equipment is causing problems:
kbd_mode -a
on it.
top
, ps
, taskmanager
, or some similar program,
to check which program is taking all CPU or is locking the machine.
top
, df
, or a similar program if you are out of
memory, disk space, open files, or some other critical resource.
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:
top
. Let the
program run for a while, it may be evaluating something heavy.
mysqld
server that is causing problems, can you
do mysqladmin -u root ping
or mysqladmin -u root processlist
?
mysql
, for example)
when you try to connect to the MySQL server?
Does the client jam? Do you get any output from the program?
When sending a bug report, you should of follow the outlines described in this manual. 「1.6.1.2 質問またはバグ報告」節参照.
This section lists some errors that users frequently get. You will find descriptions of the errors, and how to solve the problem here.
Access denied
エラー
「4.2.11 何故 Access denied
エラーになるのか」節参照.
「4.2.6 特権システムはどのように動くか?」節参照.
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 | クライアントがサーバーに問い合わせを送る ことができなかった server. |
CR_SERVER_LOST | クライアントがサーバーに書き込みを行ったときに はエラーは無かったけれども、問い合わせに対して完全に回答が返ってこない |
You will also get this error if someone has kills the running thread with
kill #threadid#
.
You can check that the MySQL hasn't died by executing mysqladmin
version
and examining the uptime. If the problem is that mysqld
crashed you should concentrate one finding the reason for the crash.
You should in this case start by checking if issuing the query again
will kill MySQL again. 「A.4.1 What To Do If MySQL Keeps Crashing」節参照.
間違っているか大きすぎるクエリをサーバに送った場合にもこのエラーが発生し
ます。mysqld
が間違ったブロックを得た場合、クライアントの何かが間違った
と見なし、接続をクローズします。大きなクエリが必要な場合、例えば大きな
BLOB
で働かせる場合は、mysqld
をオプション -O max_query_size=#
(デフォルト 1M) で起動することでクエリ制限を増加できます。拡張メモリ
はオンデマンドで割り当てられます。そのため、mysqld
は大きなクエリを発行し
た時や大きな結果行を返す必要のある時だけ、多くのメモリを割り当てます!
You will also get a lost connection if you are sending a packet >= 16M if your client is older than 4.0.8 and your server is 4.0.8 and above, or the other way around.
If you want to make a bug report regarding this problem, be sure that you include the following information:
hostname.err file
. 「A.4.1 What To Do If MySQL Keeps Crashing」節参照.
mysqld
and the involved tables where
checked with CHECK TABLE
before you did the query, can you do
a test case for this? 「E.1.6 Making a Test Case When You Experience Table Corruption」節参照.
wait_timeout
variable in the MySQL server ?
mysqladmin variables
gives you the value of this
mysqld
with --log
and check if the
issued query appears in the log ?
「1.6.1.2 質問またはバグ報告」節参照.
Can't connect to [local] MySQL server
エラー
UNIX 上の MySQL クライアントは mysqld
サーバに2つの異なる方法で
接続できます:
UNIX ソケット, これはファイルシステム上のファイル(デフォルト
`/tmp/mysql.sock')を通して接続します。または TCP/IP, これはポート番
号を通して接続します。Unix ソケットは TCP/IP よりも速いですが、サーバと
同じコンピュータから接続する時しか使えません。UNIX ソケットは、ホスト名
を指定しない場合か、特別なホスト名 localhost
を指定した場合に使用され
ます。
On Windows, if the mysqld
server is running on 9x/Me, you can
connect only via TCP/IP. If the server is running on NT/2000/XP and
mysqld is started with --enable-named-pipe
, 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
に接続しようとする場合におきます。
サーバー上に mysqld
というプロセスが走っているか ( ps
を使用して。
Windows の場合はタスクマネージャでみて)
確認することから開始してください!
「2.4.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
エラーが起こりうる理由として:
mysqld
is not running.
mysqld
は
MIT-pthreads パッケージを使用します。 「2.2.5 MySQL がサポートする OS」節参照.
MIT-pthreads スレッドは UNIX ソケットをサポートしません。
そのため、サーバに接続する時は常にホスト名を与える必要があります。
サーバーへの接続をチェックするために、以下を試してください:
shell> mysqladmin -h `hostname` version
mysqld
が使用する UNIX ソケット を削除した (default `/tmp/mys
qld.sock').
だれかが cron
で MySQL ソケットを削除しているかもしれません。(例
えば `/tmp' ディレクトリから古いファイルを削除するようなクローンで)。
いつでも mysqladmin version
を実行して
mysqladmin
が使用するソケットが本当に存在するかをチェックできます。
この場合の修正は、`mysqld.sock' を消さないように cron
を変更するか、
またはソケットをどこか他の場所に移すことです。
「A.4.5 MySQL ソケットファイル `/tmp/mysql.sock' を変更する方法、削除から守る方法」節参照.
--socket=/path/to/socket
オプションで mysqld
サーバーを起動できます。
もしサーバーのソケットのパスを変えた場合、MySQL クライアントに、新しい
パスを教えなければなりません。
「A.4.5 MySQL ソケットファイル `/tmp/mysql.sock' を変更する方法、削除から守る方法」節参照.
mysqld
スレッドをキルしなければなりません。
たとえば、mysql_zap
スクリプトを、新しく MySQL サーバーを
起動する前に実行します。 「A.4.1 What To Do If MySQL Keeps Crashing」節参照.
mysqld
so that it uses a directory that you can access.
もし Can't connect to MySQL server on some_hostname
エラーの場合,
何が問題なのかを見つけるために、以下の手順を踏みます:
telnet your-host-name tcp-ip-port-number
を実行すると
サーバーがアップするなら、 RETURN
を何回かたたいてください。
もしこのポートで MySQL サーバーが走っているなら、
走っている MySQL サーバーのバージョンナンバーを含んだ
レスポンスが得られるはずです。
もし telnet: Unable to connect to remote host: Connection refused
のような
エラーになったならば、このポートを使用しているサーバーはありません。
mysqld
デーモンに接続してみてください。
mysqldmin variables
で、mysqld
が使用するように指定された
TCP/IP ポート(変数 port
)をチェックしてください。
mysqld
サーバーが --skip-networking
オプションで起動されていないか
確認してください。
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
値を増やす
ことはよくないことです!
Too many connections
エラー
もし MySQL に接続しようとして Too many connections
となった場合、
これは既に max_connections
分、クライアントから mysqld
サーバーへの
接続が行われています。
もしデフォルトの100よりも多い接続を必要とするならば、
max_connections
変数に多くの値を与えて、mysqld
を
リスタートしなくてはなりません。
実際は、mysqld
は (max_connections
+1) 個のクライアントからの接続を
許しています。
最後の1個は、 SUPER
権限 (version4.0.2以上。未満は 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. 「4.5.6.6 SHOW PROCESSLIST
」節参照.
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.
Some non-transactional changed tables couldn't be rolled back
エラー
もし ROLLBACK
を試みたときに
Warning: Some non-transactional changed tables couldn't be rolled back
エラー/警告が出た場合、これは、あなたが使用しているテーブルがトランザクションを
サポートしていないということです。
これらの非トランザクションのテーブルは ROLLBACK
によって、何の影響も受けません。
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
.
以下の SQL 文でテーブルの型をチェックできます:
SHOW TABLE STATUS LIKE 'table_name'
. 「4.5.6.2 SHOW TABLE STATUS
」節参照.
You can check the extensions your mysqld
binary supports by doing:
show variables like 'have_%'
. 「4.5.6.4 SHOW VARIABLES
」節参照.
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()
を使用します。
これはクライアントのロード不足を補います(サーバーより多い領域は取れません)。
Packet too large
エラー
MySQL クライアントが max_allowed_packet
よりも大きなブロックを
mysqld
サーバーから得た時、Packet too large
エラーを発します。
In MySQL 3.23 the biggest possible packet is 16M (due to limits in the client/server protocol). In MySQL 4.0.1 and up, this is only limited by the amount on memory you have on your server (up to a theoretical maximum of 2G).
A communication packet is a single SQL statement sent to the MySQL server or a single row that is sent to the client.
MySQL クライアントや mysqld
サーバーが max_allowed_packet
バイトより
大きなパケットを受け取ったた場合、 Packet too large
エラーを発して
接続を閉じます。
いくつかのクライアントでは、
Lost connection to MySQL server during query
エラーも出すでしょう。
クライアントとサーバーは、自身の max_allowed_packet
変数を持っています。
もし大きなパケットを扱いたい場合には、クライアントとサーバーの両方の
max_allowed_packet
値を増やしてください。
It's safe to increase this variable as memory is only allocated when needed; this variable is more a precaution to catch wrong packets between the client/server and also to ensure that you don't accidentally use big packets so that you run out of memory.
If you are using the mysql
client, you may specify a bigger
buffer by starting the client with
mysql --set-variable=max_allowed_packet=8M
.
Other clients have different methods to set this variable.
Please note that --set-variable
is deprecated since
MySQL 4.0, just use --max-allowed-packet=8M
instead.
You can use the option file to set max_allowed_packet
to a larger
size in mysqld
. For example, if you are expecting to store the
full length of a MEDIUMBLOB
into a table, you'll need to start
the server with the set-variable=max_allowed_packet=16M
option.
MySQL 3.23.40
からは、mysqld
を --warnings
オプションで
たち上げた時にだけ、Aborted connection
エラーを出力することが可能です。
もし以下のようなエラーがエラーログファイルに記録されていたら、
010301 14:38:23 Aborted connection 854 to db: 'users' user: 'josh'
「4.9.1 The Error Log」節参照.
これは以下が起きたことを示します:
mysql_close()
を呼び出さなかった。
wait_timeout
か interactive_timeout
以上、いかなるリクエストもしない状態だった。
「4.5.6.4 SHOW VARIABLES
」節参照.
「4.5.6.4 SHOW VARIABLES
」節参照.
上記が起きたときには、サーバーは Aborted_clients
変数を増やします。
サーバー変数 Aborted_connects
は以下の時に増えます:
connect_timeout
秒以上
かかった時
「4.5.6.4 SHOW VARIABLES
」節参照.
Note that the above could indicate that someone is trying to break into your database!
「4.5.6.4 SHOW VARIABLES
」節参照.
Other reasons for problems with Aborted clients / Aborted connections.
max_allowed_packet
is too small or queries require more memory
than you have alloacated for mysqld
. 「A.2.8 Packet too large
エラー」節参照.
The table is full
エラーtmp_table_size
よりも大きくなっ
た時に発生します。この問題を回避するために、mysqld
のオプション
-O tmp_table_size=#
で増加、または、SQL オプション BIG_TABLES
(ver.4.0.3未満では SQL_BIG_TABLES
)
を問題のクエリの前に使用できます。
「5.5.6 SET
構文」節参照.
You can also start mysqld
with the --big-tables
option.
This is exactly the same as using BIG_TABLES
for all queries.
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
.
InnoDB
tables and run out of room in the
InnoDB
tablespace. In this case the solution is to extend the
InnoDB
tablespace.
ISAM
or MyISAM
tables on an OS that only
supports files of 2G in size and you have hit this limit for the data
or index file.
MyISAM
tables and the needed data or index size is
bigger than what MySQL has allocated pointers for. (If you don't specify
MAX_ROWS
to CREATE TABLE
MySQL will only allocate pointers
to hold 4G of data).
You can check the maximum data/index sizes by doing
SHOW TABLE STATUS FROM database LIKE 'table_name';or using
myisamchk -dv database/table_name
.
If this is the problem, you can fix it by doing something like:
ALTER TABLE table_name MAX_ROWS=1000000000 AVG_ROW_LENGTH=nnn;You only have to specify
AVG_ROW_LENGTH
for tables with BLOB/TEXT
fields as in this case MySQL can't optimise the space required based
only on the number of rows.
Can't create/write to file
エラー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:
[mysqld] tmpdir=C:/temp
assuming that the `c:\\temp' directory exists. 「4.1.2 `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
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()
無しで試みた場合にも発生します。
Ignoring user
エラー以下のエラーの場合:
Found wrong password for user: 'some_user@some_host'; ignoring user
これは mysqld
の開始または 'reload' 時に user
テーブル内に正しいパ
スワードを持たないエントリを見つけたことを意味します。
これは単にエントリが許可システムに拒否されているだけです。
起こり得ることとその解決:
mysqld
を、古いバージョン用の user
テーブルで走
らせているのかもしれません。
mysqlshow mysql user
を行うことによってこれを検証できます。
パスワードフィールドが 16 文字よりも短いかどうかをチェックしてください。
もしそうなら、これを修正するために、scripts/add_long_password
スクリプト
を実行してください。
mysqld
を --old
-protocol
オプションで起動していないのかもしれません。
新しいパスワードで user
テーブル内のユーザを更新するか、--old-protocol
付きで mysqld
を再起動してください。
user
テーブルのパスワードを、PASSWORD()
関数を使用しないで登録した
のかもしれません。
この場合、user
テーブルのパスワードを、mysql
を使用して更新します。
PASSWORD()
関数は以下のようにして使用します:
mysql> UPDATE user SET password=PASSWORD('your password') -> WHERE user='XXX';
Table 'xxx' doesn't exist
エラー
もし Table 'xxx' doesn't exist
か Can't find file: 'xxx' (errno: 2)
エラーが出た場合、使用しているデータベースに xxx
という名前のテーブルが
見付からなかったことを示します
データベースとテーブルの保存に、MySQL はディレクトリとファイルを使用し、 データベースとテーブルの名前はケース依存です! (Windows ではデータベースとテーブル名はケース非依存です。 クエリ中のテーブルに対する問い合わせは全て、同じケースで書かなくてはなりません!)
SHOW TABLES
を使用してデータベースのテーブルを確認できます.
「4.5.6 SHOW
構文」節参照.
Can't initialize character set xxx
エラーもし以下のようなエラーが出た場合:
MySQL Connection Failed: Can't initialize character set xxx
これは次を意味します:
--with-charset=xxx
か
--with-extra-charsets=xxx
コンフィギャ・オプションで再コンパイルする必要があります。
「2.3.3 典型的な configure
オプション」節参照.
All standard MySQL binaries are compiled with
--with-extra-character-sets=complex
which will enable support for
all multi-byte character sets. 「4.6.1 データとソートに使用されるキャラクター・セット」節参照.
mysqld
に
組み込まれておらず、さらに 定義ファイルも特定の場所に存在しなかった場合。
この場合は以下のようにします:
configure
オプション」節参照.
--character-sets-dir=path-to-charset-dir
オプションを
持っています。
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 shell> perror 11 Resource temporarily unavailable
これは 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
.
「4.5.6.4 SHOW VARIABLES
」節参照.
The easiest way to do that is to add the option to your option file.
「4.1.2 `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
.
ulimit
と open-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_mysqld
は sh
で起動すべきです!
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'
この場合には、-Lpath-to-the-mysql-library -lmysqlclient
を、
リンクの 最後に 加えれば解決します。
もし undefined reference
エラーで uncompress
や
compress
が定義されていないエラーを受けたならば、
-lz
をリンク ラインの 最後に 加えて再リンクしてください!
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. 「2.3 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:
LD_LIBRARY_PATH
環境変数に、`libmysqlclient.so' が存在する
ディレクトリを加える。
LD_LIBRARY
環境変数に、`libmysqlclient.so' が存在する
ディレクトリを加える。
ldconfig
.
他の解決方法は、あなたのプログラムを -static
フラグで static にリンクするか、
動的な MySQL ライブラリをリンク前に移動してから、リンクします。
二つ目の場合は、他のプログラムがそのダイナミックライブラリを使用していないか
注意してください!
mysqld
(MySQL サーバ) はいかなるユーザーでも開始し実行することが
できます。mysqld
をユーザ user_name
で実行するように変更するためには、
次を行なう必要があります:
mysqladmin shutdown
).
user_name
が読み書きできるように、データベースディレクトリとその中のファ
イルのパーミッションを変更します。(これは UNIX root
ユーザーで実行する必
要があるでしょう):
shell> chown -R user_name /path/to/mysql/datadirMySQL データベースディレクトリのディレクトリーやファイルがシンボリック リンクの場合、 これらリンクの先のディレクトリとファイルも変更します。
chown -R
はシンボリ
ックリンク先を変更してくれません。
user_name
でサーバを起動します。または MySQL 3.22 以降を
使用する場合は、mysqld
を UNIX root
で起動し
--user=user_name
スイッチを使用します。
mysqld
は、接続を許可する前に、与えられた UNIX user user_name
で実
行するように切り替えます。
user
line that specifies the user name to
the [mysqld]
group of the `/etc/my.cnf' option file or the
`my.cnf' option file in the server's data directory. For example:
[mysqld] user=user_name
この時点で、あなたの mysqld
プロセスは UNIX user user_name
で正常
に動作します。
一つのことは変わりません。それは権限許可テーブルです。デフォルト
(パーミッションテーブルインストールスクリプトmysql_install_db
実行後の権限)
では、mysql
データベースへのアクセスやデータベースの作成、破棄はユーザ
MySQL user root
だけです。
これを変更しないと、それはそのままです。
root
以外の UNIX userでログインしている時でも、あなたは
MySQL root
user としてアクセスは可能です - ただプログラムに
-u root
をクライアントプログラムにオプション指定するだけです。
MySQL に root
としてアクセスするには、
コマンドラインで -u root
を使用するだけでいいことに注意してください。
UNIX root
user や MySQL を走らせている UNIX ユーザーである必要は
ないことに注意してください。
MySQL のアクセスパーミッションとMySQL のユーザは、
UNIX ユーザとは完全に別のものです。UNIX ユーザに関係するのは、クライアン
トに -u
オプションを使用しない場合だけです。この場合、クライアントは
MySQL へのログインを、あなたの UNIX ログイン名で試みます。
あなたの UNIX マシンそれ自身が安全でない場合は、少なくとも MySQL ア
クセステーブルの MySQL root
ユーザにはパスワードを設定すべきです。
どこかの誰かが mysql -u root db_name
を行ない、彼が望むことの全てを実行で
きてしまうからです。
ファイルパーミッションの問題がある場合、
例えば、テーブルの生成時に 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 behaviour 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.
「F Environment Variables」節参照.
全ての MySQL バージョンはリリースの前に多くのプラットフォームで テストされます。 これは MySQL にいかなるバグもないということを 意味しますが、発見するのが困難で、わずかなバグがあるかもしれません。 もし問題があった場合、何がシステムをクラッシュしているかを見つけようとする事は、 問題を早く修正するためのより良い機会でもあります。
まず最初に, その問題で mysqld
デーモンが死ななければならないかどうかか,
また
はその問題がクライアントで処理しなければならないかどうかを調べるべきです。
mysqladmin version
を実行することにより、 mysqld
サーバーが
どれぐらい稼働していたかわかります。 もし mysqld
が死んでいたなら、
を実行することによってあるのかをチェックすることができます. mysqldが死んだなら、
その原因を `mysql-data-directory/`hostname`.err' で見つけれるかもしれません。
「4.9.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 delay_key_write
, 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:
mysqld
or the machine in the middle
of an update.
mysqld
that caused it to die in the
middle of an update.
mysqld
servers on the same data on a
system that doesn't support good filesystem locks (normally handled by
the lockd
daemon ) or if you are running
multiple servers with --skip-external-locking
mysqld
confused.
ALTER TABLE
on a
repaired copy of the table!
何かがクラッシュする理由を知るのは非常に難しいので、まず、他の人で動くも のがあなたでクラッシュするのかどうかをチェックしてください。次のことを行っ てください。
mysqld
デーモンを mysqladmin shutdown
で停止し, 全てのテーブルで
myisamchk --silent --force */*.MYI
を実行し、そして mysqld
デーモ
ンを再起動します. これはきれいな状態から開始することになります。
「4 Database Administration」節参照.
mysqld --log
を使用し、ログの情報から特定のクエリがサーバーをキルしている
かを見つけ出してください。 95% のバグは特定のクエリに関係があります!
通常これは、 MySQL が再起動される前の、ログファイルの最後のクエリの一つ
です。 「4.9.2 The General Query Log」節参照.
If you can repeatadly kill MySQL with one of the queries, even
when you have checked all tables just before doing the query, then you
have been able to locate the bug and should do a bug report for this!
「1.6.1.3 バグや問題を報告する方法」節参照.
fork_test.pl
と fork2_test.pl
を試します。
configure
に
--with-debug
オプションか --with-debug=full
オプションを
つけて MySQL を再コンフィグし、
再コンパイルしてください。 「E.1 MySQL server のデバッグ」節参照.
--skip-external-locking
(ver. 4.0.3未満では --skip-locking
)
オプションを mysqld
に使用してください。いくつかのシステム上では、
lockd
ロックマネージャは正しく動きません;
--skip-external-locking
(ver. 4.0.3未満では --skip-locking
)
オプションは mysqld
に外部ロッキングを使用
しないように伝えます。(これは同じデータ上で2つの mysqld
サーバを
動すことができず、myisamchk
の使用時に注意しなければいけないことを
意味します。しかし、テストとしてこのオプションを試すことは指示できます。)
mysqld
が動いているのに応答がないように見えた時
mysqladmin -u root processlist
を試しましたか? 時々
mysqld
はそう思えても死んでいません。問題は全ての接続が使用中であ
ることか、いくつかの内部ロック問題があることです。mysqladmin
processlist
は通常これらの場合でも接続を作ることができ、現在の接続数と
それらの状態についての有用な情報を提供できます。
mysqladmin -i 5 status
や mysqladmin -i 5 -r status
をクエリ中に行ってください。
gdb
(または他のデバッガ) から mysqld
を開始してください。
「E.1.3 Debugging mysqld under gdb」節参照.
mysqld
has crashed inside
gdb:
backtrace info local up info local up info localWith gdb you can also examine which threads exist with
info
threads
and switch to a specific thread with thread #
, where
#
is the thread id.
BLOB/TEXT
フィールドは使用しておらず、VARCHAR
フィールド
だけ使用しているなら、全ての VARCHAR
フィールドを
ALTER TABLE
で CHAR
に変更してみてください。
これは MySQL に固定長レコードを使用させるようにします。
固定長レコードは少し余分な領域をとりますが、よりエラーに対して
強くなります。
現在の可変長のレコードのコードは MySQL AB で少なくとも3年以上問題なく
使用されています。 しかし可変長のレコードはよりエラーの傾向があり、
上記の事柄を試すことは良いアイデアです!
If you never set a root
password for MySQL, then the server will
not require a password at all for connecting as root
. It is
recommended to always set a password for each user. 「4.2.2 MySQL をクラッカーに対して安全にする方法」節参照.
もし MySQL の root
ユーザーのパスワードを忘れた場合、
これを以下のようにして入れ直すことが可能です。
mysqld
サーバーを kill
で落とす。
(kill -9
ではありません!)
PID 番号は通常 MySQL データディレクトリに `.pid' ファイルに
書かれています:
shell> kill `cat /mysql-data-directory/hostname.pid`これを、 Unix
root
ユーザーか、MySQL サーバーを実行した
ユーザーで行います。
mysqld
を --skip-grant-tables
オプションで起動。
mysqladmin password
コマンドでパスワードを変更します。
shell> mysqladmin -u root password 'mynewpassword'
mysqld
and restart it normally,
or just load the privilege tables with:
shell> mysqladmin -h hostname flush-privileges
Alternatively, you can set the new password using the mysql
client:
mysqld
with the --skip-grant-tables
option as described above.
mysqld
server with:
shell> mysql -u root mysql
mysql
client:
mysql> UPDATE user SET Password=PASSWORD('mynewpassword') -> WHERE User='root'; mysql> FLUSH PRIVILEGES;
mysqld
and restart it normally.
ディスクフルが起きた場合 MySQL は次のことを行います:
この問題の場合、以下のようにします:
mysqladmin kill
をスレッドに送る
必要があります。スレッドは次に(1分)ディスクをチェックした時にアボートし
ます。
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).
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
は一時テーブルをオリジナルテーブルと同じディレクトリ
内に生成します。
If you use MySQL 4.1 or later you can spread load between
several physical disks by setting --tmpdir
to a list of paths
separated by colon :
(semicolon ;
on Windows). They
will be used in round-robin fashion.
Note: These paths should end up on different physical disks,
not different partitions of the same disk.
もし誰かに MySQL のソケットファイル `/tmp/mysql.sock' が消されるな
ら、ほとんどの UNIX がそうであるように、 `/tmp' に sticky
ビットをたてて
保護します。
root
でログインして、以下のようにします:
shell> chmod +t /tmp
これはファイルのオーナーとスーパーユーザー(root
) のみが、
`/tmp' のファイルを消すことができます。
sticky
ビットが立っているか確認するには、 ls -ld /tmp
を行います。
パーミッションの最後のビットが t
ならば、セットされています。
You can change the place where MySQL uses / puts the socket file the following ways:
/etc/my.cnf
:
[client] socket=path-for-socket-file [mysqld] socket=path-for-socket-file「4.1.2 `my.cnf' オプションファイル」節参照.
safe_mysqld
and most
clients with the --socket=path-for-socket-file
option.
MYSQL_UNIX_PORT
環境変数に設定することにより可能です。
configure
option
--with-unix-socket-path=path-for-socket-file
. 「2.3.3 典型的な configure
オプション」節参照.
ソケットのテストをする場合、以下のようにします:
shell> mysqladmin --socket=/path/to/socket version
もし SELECT NOW()
があなたのローカル時間ではなく GMT を返すなら、
TZ
環境変数をローカルのTimezone に設定しなくてはなりません。
環境変数の設定は、サーバーを実行する前に行われなくてはなりません。
たとえば、safe_mysqld
や mysql.server
スクリプトで
行います。
「F Environment Variables」節参照.
デフォルトでは MySQL フィールドはケース非依存です (しかし、ケース非依
存にならないいくつかの文字セットはありますsuch as czech
)。
これは、col_name LIKE 'a%'
で検索した場合、A
または a
で始まる全てのフィールドを得ることを
意味します。検索をケース依存にしたいのなら、始まりをチェックするには
INDEX(column, "A")=1
のようなことを、また、文字列全体が同じかどう
かには STRCMP(column, "A") = 0
を使用してください。
単純な比較操作 >=, >, =, <, <=
、ソートそしてグループ化は、文字 ``sort val
ue'' 上で行われます。同じソート値の文字 (like E, e and 'e)は同じ文字と
して扱われます!
In older MySQL versions LIKE
comparisons where done on
the uppercase value of each character (E == e but E <> 'e. In newer
MySQL versions LIKE
works just like the other comparison
operators.
あるフィールドをいつでもケース依存で扱いたい場合は、それを BINARY
として宣言してください。 「6.5.3 CREATE TABLE
構文」節参照.
big5 エンコーディングと呼ばれる中国語データを使用している場合は、全ての
文字項目を BINARY
にしてください。これは、big5 エンコーディング文
字のソート順が ascii コードが基になっているため、機能します。
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 はこの日付の種類を扱え
ないためです。
Because MySQL performs the conversions described above, the following statements work:
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'
)を格納すると、その間違った日付が格
納されます。
Because MySQL packs dates for storage, it can't store any given date as it would not fit onto the result buffer. The rules for accepting a date are:
DATE
and DATETIME
columns.
DATE
column and you only know part
of the date.
If the date cannot be converted to any reasonable value, a 0
is
stored in the DATE
field, which will be retrieved as
0000-00-00
. This is both a speed and convenience issue as we
believe that the database's responsiblity is to retrieve the same date
you stored (even if the data was not logically correct in all cases).
We think it is up to the application to check the dates, and not the server.
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 = "";
Note that you can only add an index on a column that can have NULL
values if you are using MySQL Version 3.23.2 or newer and are using the
MyISAM
or InnoDB
table type.
Version 3.23.2 以前の MySQL では、他の多くの SQL サーバのように、NULL
値を持つ
インデックスフィールドを持てません。これらのフィールドは NOT NULL
と宣言
しなくてはいけません。
LOAD DATA INFILE
でデータを読み込むときは、空のフィールドは ''
で
更新されます。
項目を NULL
値にしたい場合は、テキストファイル中に \N
を使用すべき
です。
リテラルとしての 'NULL'
語が、ある状況下で使用されています。
「6.4.9 LOAD DATA INFILE
構文」節参照.
When using ORDER BY
, NULL
values are presented first.
In versions prior to 4.0.2, if you sort in descending order using
DESC
, NULL
values are presented last.
When using GROUP BY
, all NULL
values are regarded as equal.
To help with NULL
handling, you can use the IS NULL
and
IS NOT NULL
operators and the IFNULL()
function.
ORDER BY
使用時, NULL
値は最初に提示されます.
DESC
を使用して降順にソートする時、NULL
値は最後になります。
GROUP BY
使用時, 全ての NULL
値は等しいと見なされます。
NULL
処理を手助けするため、次の関数を使用できます:
IS NULL
, IS NOT NULL
, IFNULL()
.
いくつかの項目型では、NULL
値はハンドルとして扱われます。
もしテーブル内の最初の TIMESTAMP
項に NULL
を挿入するなら、
現在の日付と時刻が挿入されます。もし AUTO_INCREMENT
項にNULL
値を
挿入するなら、
次のシーケンス番号が挿入されます。
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
が使用されます。
MySQL は現在 subselect は未サポートで、また Version 4.0 以前では
DELETE
構文で複数のテーブルを扱う事もサポートしていません。
したがって、2つのテーブルに関連するレコードを消すには、以下のようにして行います:
WHERE
条件を使用して、基本となるテーブルから行を SELECT
DELETE
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
節の引
数の数に無関係になります。
複雑なクエリーを行って、もしなんの結果も返さなければ、 そのクエリーの何が悪いかを見つけるため、以下の手続きを行います:
EXPLAIN
を使用してクエリーをテストし、明白な間違いを見つけます。
「5.2.1 EXPLAIN
構文 (SELECT
についての情報を得る)」節参照.
WHERE
節で使用されているフィールドだけを Select してみます
LIMIT 10
をクエリーで使用することは良くありません。
SELECT
してみます。
その場合、select するのは、上記で最後に取り除いたテーブルに対して行います。
FLOAT
or DOUBLE
columns with numbers that
have decimals, you can't use '='
. This problem is common in most
computer languages because floating-point values are not exact values.
In most cases, changing the FLOAT
to a DOUBLE
will fix this.
「A.5.7 Problems with Floating-Point Comparison」節参照.
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 にテストを投稿してくだ
さい。
floating-point numbers cause confusion sometimes, because these numbers are not stored as exact values inside computer architecture. What one can see on the screen usually is not the exact value of the number.
Field types FLOAT
, DOUBLE
and DECIMAL
are such.
CREATE TABLE t1 (i INT, d1 DECIMAL(9,2), d2 DECIMAL(9,2)); INSERT INTO t1 VALUES (1, 101.40, 21.40), (1, -80.00, 0.00), (2, 0.00, 0.00), (2, -13.20, 0.00), (2, 59.60, 46.40), (2, 30.40, 30.40), (3, 37.00, 7.40), (3, -29.60, 0.00), (4, 60.00, 15.40), (4, -10.60, 0.00), (4, -34.00, 0.00), (5, 33.00, 0.00), (5, -25.80, 0.00), (5, 0.00, 7.20), (6, 0.00, 0.00), (6, -51.40, 0.00); mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b -> FROM t1 GROUP BY i HAVING a <> b; +------+--------+-------+ | i | a | b | +------+--------+-------+ | 1 | 21.40 | 21.40 | | 2 | 76.80 | 76.80 | | 3 | 7.40 | 7.40 | | 4 | 15.40 | 15.40 | | 5 | 7.20 | 7.20 | | 6 | -51.40 | 0.00 | +------+--------+-------+
The result is correct. Although the first five records look like they shouldn't pass the comparison test, they may do so because the difference between the numbers show up around tenth decimal, or so depending on computer architecture.
The problem cannot be solved by using ROUND() (or similar function), because the result is still a floating-point number. Example:
mysql> SELECT i, ROUND(SUM(d1), 2) AS a, ROUND(SUM(d2), 2) AS b -> FROM t1 GROUP BY i HAVING a <> b; +------+--------+-------+ | i | a | b | +------+--------+-------+ | 1 | 21.40 | 21.40 | | 2 | 76.80 | 76.80 | | 3 | 7.40 | 7.40 | | 4 | 15.40 | 15.40 | | 5 | 7.20 | 7.20 | | 6 | -51.40 | 0.00 | +------+--------+-------+
This is what the numbers in column 'a' look like:
mysql> SELECT i, ROUND(SUM(d1), 2)*1.0000000000000000 AS a, -> ROUND(SUM(d2), 2) AS b FROM t1 GROUP BY i HAVING a <> b; +------+----------------------+-------+ | i | a | b | +------+----------------------+-------+ | 1 | 21.3999999999999986 | 21.40 | | 2 | 76.7999999999999972 | 76.80 | | 3 | 7.4000000000000004 | 7.40 | | 4 | 15.4000000000000004 | 15.40 | | 5 | 7.2000000000000002 | 7.20 | | 6 | -51.3999999999999986 | 0.00 | +------+----------------------+-------+
Depending on the computer architecture you may or may not see similar results. Each CPU may evaluate floating-point numbers differently. For example in some machines you may get 'right' results by multiplaying both arguments with 1, an example follows.
WARNING: NEVER TRUST THIS METHOD IN YOUR APPLICATION, THIS IS AN EXAMPLE OF A WRONG METHOD!!!
mysql> SELECT i, ROUND(SUM(d1), 2)*1 AS a, ROUND(SUM(d2), 2)*1 AS b -> FROM t1 GROUP BY i HAVING a <> b; +------+--------+------+ | i | a | b | +------+--------+------+ | 6 | -51.40 | 0.00 | +------+--------+------+
The reason why the above example seems to be working is that on the particular machine where the test was done, the CPU floating-point arithmetics happens to round the numbers to same, but there is no rule that any CPU should do so, so it cannot be trusted.
The correct way to do floating-point number comparison is to first decide on what is the wanted tolerance between the numbers and then do the comparsion against the tolerance number. For example, if we agree on that floating-point numbers should be regarded the same, if they are same with precision of one of ten thousand (0.0001), the comparsion should be done like this:
mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b FROM t1 -> GROUP BY i HAVING ABS(a - b) > 0.0001; +------+--------+------+ | i | a | b | +------+--------+------+ | 6 | -51.40 | 0.00 | +------+--------+------+ 1 row in set (0.00 sec)
And vice versa, if we wanted to get rows where the numbers are the same, the test would be:
mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b FROM t1 -> GROUP BY i HAVING ABS(a - b) < 0.0001; +------+-------+-------+ | i | a | b | +------+-------+-------+ | 1 | 21.40 | 21.40 | | 2 | 76.80 | 76.80 | | 3 | 7.40 | 7.40 | | 4 | 15.40 | 15.40 | | 5 | 7.20 | 7.20 | +------+-------+-------+
ALTER TABLE
.
ALTER TABLE
changes a table to the current character set.
If you during ALTER TABLE
get a duplicate key error, then the cause
is either that the new character sets maps to keys to the same value
or that the table is corrupted, in which case you should run
REPAIR TABLE
on the table.
もし ALTER TABLE
が以下のようなエラーで死んだ場合:
Error on rename of './database/name.frm' to './database/B-a.frm' (Errcode: 17)
これは以前の ALTER TABLE
で MySQL がクラッシュしており、
`A-something' か `B-something' という名前の、誤った情報を流している
古いテーブルが存在しています。
この場合、MySQL データディレクトリに入り、A-
や B-
で始まる
名前を持つファイルを全て消します。
(消す代わりにどこかに移動しても構いません。)
ALTER TABLE
は以下のように動作します:
もし名称変更の際に問題があると、MySQL は変更を取り消すように動きます。 致命的な問題が起きた場合(ありえませんが)、MySQL は元の古いテーブルを `B-xxx' という名前のままにしておきます。単にシステムレベルで名称変更すれば データは戻ります。
SQLの主な目的はデータフォーマットからアプリケーションを切り離してしまうことにあります。そのため、常に取り出したいデータの順序を常に指定する必要があります。例えば、次のような文:
SELECT col_name1, col_name2, col_name3 FROM tbl_name;
これは、col_name1
, col_name2
, col_name3
, の順序でデータを返します。ここで、
SELECT col_name1, col_name3, col_name2 FROM tbl_name;
こうすると、col_name1
, col_name3
, col_name2
, の順序でデータを返します。
SELECT *
やそのテーブル内での位置に依存してしまうような取り出し方はけっしてするべきではありません。というのは取り出されるデータの順序が常に保障されるものではないからです。単にフィールドの情報が変更されただけでアプリケーションがエラーが発生する可能性を有しているのです。
にもかかわらずフィールドの順序を変えたい場合には次のような方法があります。
INSERT INTO new_table SELECT fields-in-new_table-order FROM old_table
.
を実行します。
old_table
をドロップするかリネームして下さい。
ALTER TABLE new_table RENAME old_table
.
を実行します。
TEMPORARY TABLES
を用いる処理における制限を以下に示します。
HEAP
, ISAM
, MyISAM
, MERGE
, InnoDB
の
いづれかの型のみを持つことが可能です。
mysql> SELECT * FROM temporary_table, temporary_table AS t2;
ALTER TABLE org_name RENAME new_name
は動作します。しかし、
TEMPORARY
テーブルにRENAME
を使用することはできません。
Go to the first, previous, next, last section, table of contents.