This appendix lists some common problems and error messages that MySQL users have encountered. It describes how to figure out what the causes of problem are, and what to do to solve them.
When you run into a problem, the first thing you should do is to find out which program or piece of equipment is causing it:
glibc) are up to date. It's always good to use a machine with ECC memory to discover memory problems early.
taskmanager, or some similar program, to check which program is taking all CPU or is locking the machine.
df, or a similar program to check whether you are out of memory, disk space, file descriptors, or some other critical resource.
If after you have examined all other possibilities and you have concluded that the MySQL server or a MySQL client is causing the problem, it's time to create 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 that MySQL is causing the problem. Take into consideration all the situations in this chapter. State any problems exactly how they appear when you examine your system. Use the ``copy and paste'' method for any output and error messages from programs and 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 state only ``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 the following information:
top. Let the program run for a while, it may simply be evaluating something computationally intensive.
mysqldserver is causing problems, can you get any response from it with
mysqladmin -u root pingor
mysqladmin -u root processlist?
mysql, for example.) Does the client jam? Do you get any output from the program?
When sending a bug report, you should follow the outline described in section 126.96.36.199 Asking Questions or Reporting Bugs.
This section lists some errors that users frequently encounter. You will find descriptions of the errors, and how to solve the problem here.
See section 5.4.8 Causes of
Access denied Errors.
See section 5.4.2 How the Privilege System Works.
MySQL server has gone away
This section also covers the related
Lost connection to server
during query error.
The most common reason for the
MySQL server has gone away error
is that the server timed out and closed the connection. By default, the
server closes the connection after eight hours if nothing has happened. You
can change the time limit by setting the
wait_timeout variable when
See section 5.2.3 Server System Variables.
If you have a script, you just have to issue the query again for the client to do an automatic reconnection.
You normally get one of the the following error codes in this case (which one you get is operating system-dependent):
|The client couldn't send a question to the server.|
|The client didn't get an error when writing to the server, but it didn't get a full answer (or any answer) to the question.|
You will also get an error if someone has killed the running thread with a
KILL statement or a
mysqladmin kill command.
Another common reason the
MySQL server has gone away error occurs
within an application program is that you tried to run a query after
closing the connection to the server. This indicates a logic error in the
application that should be corrected.
You can check whether the MySQL server died and restarted by executing
mysqladmin version and examining the uptime. If the problem is that
mysqld crashed, you should concentrate on finding the reason for the
crash. Start by checking whether issuing the query again kills the server
again. See section A.4.1 What to Do if MySQL Keeps Crashing.
You can also get these errors if you send a query to the server that is
incorrect or too large. If
mysqld receives a packet that is too large
or out of order, it assumes that something has gone wrong with the client and
closes the connection. If you need big queries (for example, if you are
working with big
BLOB columns), you can increase the query limit by
setting the server's
max_allowed_packet variable, which has a default
value of 1MB. You may also need to increase the maximum packet size on the
client end. More information on setting the packet size is given in
Packet too large.
You will also get a lost connection if you are sending a packet 16MB or larger 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 create a bug report regarding this problem, be sure that you include the following information:
mysqldand the tables involved were checked with
CHECK TABLEbefore you ran the query, can you provide a reproducible test case? See section D.1.6 Making a Test Case If You Experience Table Corruption.
wait_timeoutsystem variable in the MySQL server? (
mysqladmin variablesgives you the value of this variable.)
--logoption to determine whether the problem query appears in the log?
See section 188.8.131.52 Asking Questions or Reporting Bugs.
Can't connect to [local] MySQL server
A MySQL client on Unix can connect to the
mysqld server in two
different ways: By using a Unix socket file to connect through a file in the
filesystem (default `/tmp/mysql.sock') or by using TCP/IP, which
connects through a port number. A Unix socket file connection is faster
than TCP/IP but can be used only when connecting to a server on the same
computer. A Unix socket file is used if you don't specify a hostname or if
you specify the special hostname
mysqld server is running on Windows 9x or Me, you can
connect only via TCP/IP. If the server is running on Windows NT, 2000, or XP and
mysqld is started with the
--enable-named-pipe option, you
can also connect with named pipes if you run the client on the same host where
the server is running. The name of the named pipe is
MySQL by default.
If you don't give a hostname when connecting to
mysqld, a MySQL
client first will try to connect to the named pipe. If that 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.
The error (2002)
Can't connect to ... normally means that there is no
MySQL server running on the system or that you are using an incorrect Unix
socket filename or TCP/IP port number when trying to connect to the
Start by checking whether there is a process named
mysqld running on
your server host. (Use
ps on Unix or the Task Manager on Windows.) If
there is no
mysqld process, you should start one.
See section 184.108.40.206 Starting and Troubleshooting the MySQL Server.
mysqld process is running, you can check the server by
trying the following commands. The port number or Unix socket filename
might be different in your setup.
host_ip represents the IP number of
the machine where the server is running.
shell> mysqladmin version shell> mysqladmin variables shell> mysqladmin -h `hostname` version variables shell> mysqladmin -h `hostname` --port=3306 version shell> mysqladmin -h 'host_ip' version shell> mysqladmin --protocol=socket --socket=/tmp/mysql.sock version
Note the use of backquotes rather than forward quotes with the
command; these cause the output of
hostname (that is, the current
hostname) to be substituted into the
If you have no
hostname command or are running on Windows, you can
manually type the hostname of your machine (without backquotes) following the
You can also try
-h 127.0.0.1 to connect with TCP/IP to the local host.
Here are some reasons the
Can't connect to local MySQL server
error might occur:
mysqldis not running.
mysqlduses the MIT-pthreads package. See section 2.1.1 Operating Systems Supported by MySQL. However, not all MIT-pthreads versions support Unix socket files. On a system without socket file support, you must always specify the hostname explicitly when connecting to the server. Try using this command to check the connection to the server:
shell> mysqladmin -h `hostname` version
mysqlduses (default `/tmp/mysql.sock'). For example, you might have a
cronjob that removes old files from the `/tmp' directory. You can always run
mysqladmin versionto check whether the Unix socket file that
mysqladminis trying to use really exists. The fix in this case is to change the
cronjob to not remove `mysql.sock' or to place the socket file somewhere else. See section A.4.5 How to Protect or Change the MySQL Socket File `/tmp/mysql.sock'.
mysqldserver with the
--socket=/path/to/socketoption but forgotten to tell client programs the new name of the socket file. If you change the socket pathname for the server, you must also notify the MySQL clients. You can do this by providing the same
--socketoption when you run client programs. See section A.4.5 How to Protect or Change the MySQL Socket File `/tmp/mysql.sock'.
mysqldthreads (for example, with the
mysql_zapscript) before you can restart the MySQL server. See section A.4.1 What to Do if MySQL Keeps Crashing.
--socketoption that specifies a socket filename in a directory where the server can create it and where client programs can access it.
If you get the error message
Can't connect to MySQL server on
some_host, you can try the following things to find out what the
telnet some_host 3306and pressing Enter a couple of times. (3306 is the default MySQL port number. Change the value if your server is listening to a different port.) If there is a MySQL server running and listening to the port, you should get a response that includes the server's version number. If you get an error such as
telnet: Unable to connect to remote host: Connection refused, then there is no server running on the given port.
mysqladmin -h localhost variablesto connect using the Unix socket file. Verify the TCP/IP port number that the server is configured to listen to (it is the value of the
mysqldserver was not started with the
--skip-networkingoption. If it was, you will not be able to connect to it using TCP/IP.
Client does not support authentication protocol
MySQL 4.1 and up uses an authentication protocal based on a password hashing algorithm that is incompatible with that used by older clients. If you upgrade the server to 4.1, attempts to connect to it with an older client may fail with the following message:
shell> mysql Client does not support authentication protocol requested by server; consider upgrading MySQL client
To solve this problem, you should use one of the following approaches:
mysql> SET PASSWORD FOR -> 'some_user'@'some_host' = OLD_PASSWORD('mypass');Alternatively, use
mysql> UPDATE mysql.user SET Password = OLD_PASSWORD('mypass') -> WHERE Host = 'some_host' AND User = 'some_user'; mysql> FLUSH PRIVILEGES;Substitute the password you want to use for ``mypass'' in the preceding example. MySQL cannot tell you what the original password was, so you'll need to pick a new one.
mysql> SELECT Host, User, Password FROM mysql.user -> WHERE LENGTH(Password) > 16;For each such account, use the
Uservalues and assign a password using the
OLD_PASSWORD()function and either
UPDATE, as described earlier.
For additional background on password hashing and authentication, see section 5.4.9 Password Hashing in MySQL 4.1.
MySQL client programs prompt for a password when invoked with a
-p option that has no following password value:
shell> mysql -u user_name -p Enter password:
On some systems, you may find that your password works when specified in an
option file or on the command line, but not when you enter it interactively
Enter password: prompt. This occurs when the library provided
by the system to read passwords limits password values to a small number of
characters (typically eight). To work around this, change your password to
a value that is eight or fewer characters long.
Host '...' is blocked
If you get the following error, it means that
mysqld has received many
connect requests from the host
'host_name' that have been
interrupted in the middle:
Host 'host_name' is blocked because of many connection errors. Unblock with 'mysqladmin flush-hosts'
The number of interrupted connect requests allowed is determined by the
value of the
max_connect_errors system variable. After
max_connect_errors failed requests,
mysqld assumes that
something is wrong (for example, that someone is trying to break in), and
blocks the host from further connections until you execute a
mysqladmin flush-hosts command or issue a
See section 5.2.3 Server System Variables.
mysqld blocks a host after 10 connection errors.
You can adjust the value by starting the server like this:
shell> mysqld_safe --max_connect_errors=10000 &
Note that if you get this error message for a given host, you should first
verify that there isn't anything wrong with TCP/IP connections from that
host. If you are having network problems, it won't do you any good to
increase the value of the
Too many connections
If you get a
Too many connections error when you try to connect to
mysqld server, this means that there are already
max_connections clients connected to it.
If you need to support more than the default maximum number of connections
(100), you should restart
mysqld with a bigger value for the
mysqld actually allows
max_connections+1 clients to
connect. The extra connection is reserved for use by accounts that have the
SUPER privilege. By granting the
SUPER privilege to
administrators and not to normal users (who should not need it), an
administrator can connect to the server and use
SHOW PROCESSLIST to
diagnose problems even if the maximum number of clients already are
See section 220.127.116.11
SHOW PROCESSLIST Syntax.
The maximum number of connections MySQL can support depends on the quality of the thread library 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
If you receive the following message when trying to perform a
ROLLBACK, it means that one or more of the tables you used in the
transaction do not support transactions:
Warning: Some non-transactional changed tables couldn't be rolled back
These non-transactional tables will not be affected by the
If you were not deliberately mixing transactional and non-transactional
tables within the transaction, the most likely cause for this message is
that a table you thought was transactional actually is not. This can happen
if you try to create a table using a transactional storage engine that is
not supported by your
mysqld server (or that was disabled with a
startup option). If
mysqld doesn't support a storage engine, it will
instead create the table as a
MyISAM table, which is
You can check the table type for a table by using either of these statements:
SHOW TABLE STATUS LIKE 'tbl_name'; SHOW CREATE TABLE tbl_name;
See section 18.104.22.168
SHOW TABLE STATUS Syntax and
SHOW CREATE TABLE Syntax.
You can check the storage engines that your
mysqld server supports by
using this statement:
Before MySQL 4.1.2, use the following statement instead and check the value of the variable that is associated with the storage engine in which you are interested:
SHOW VARIABLES LIKE 'have_%';
For example, to determine whether the
InnoDB storage engine is
available, check the value of the
See section 22.214.171.124
SHOW ENGINES Syntax and
SHOW VARIABLES Syntax.
Out of memory
If you issue a query using the
mysql client program and receive an
error like the following one, it means that
mysql does not
have enough memory to store the entire query result:
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
To remedy the problem, first check whether your query is correct. Is it
reasonable that it should return so many rows? If not, correct the query and
try again. Otherwise, you can invoke
mysql with the
option. This causes it to use the
mysql_use_result() to retrieve the
result set, which places less of a load on the client (but more on the
Packet too large
A communication packet is a single SQL statement sent to the MySQL server or a single row that is sent to the client.
In MySQL 3.23, the largest possible packet is 16MB, due to limits in the client/server protocol. In MySQL 4.0.1 and up, the limit is 1GB.
When a MySQL client or the
mysqld server receives a packet bigger
max_allowed_packet bytes, it issues a
large error and closes the connection. With some clients, you may also
Lost connection to MySQL server during query error if the
communication packet is too large.
Note that the client and the server each has its own
max_allowed_packet variable. If you want to handle big packets,
you have to increase this variable both in the client and in the server.
If you are using the
mysql client program, its default
max_allowed_packet variable is 16MB. That is also the maximum value
before MySQL 4.0. To set a larger value from 4.0 on, start
mysql> mysql --max_allowed_packet=32M
That sets the packet size to 32MB.
The sever's default
max_allowed_packet value is 1MB. You can increase
this if the server needs to handle big queries (for example, if you are
working with big
BLOB columns). For example, to set the variable to
16MB, start the server like this:
mysql> mysqld --max_allowed_packet=16M
Before MySQL 4.0, use this syntax instead:
mysql> mysqld --set-variable=max_allowed_packet=16M
You can also use an option file to set
example, to set the size for the server to 16MB, add the following lines in
an option file:
Before MySQL 4.0, use this syntax instead:
[mysqld] set-variable = max_allowed_packet=16M
It's safe to increase the value of this variable because the extra memory is
allocated only when needed. For example,
mysqld allocates more
memory only when you issue a long query or when
mysqld must return a
large result row. The small default value of the variable is more a
precaution to catch incorrect packets between the client and server and also
to ensure that you don't run out of memory by using large packets
You can also get strange problems with large packets if you are using large
BLOB values but have not given
mysqld access to enough memory
to handle the query. If you suspect this is the case, try adding
ulimit -d 256000 to the beginning of the
The server error log can be a useful source of information about connection
See section 5.8.1 The Error Log.
Starting with MySQL 3.23.40, if you start the server with the
--warnings option (or
--log-warnings from MySQL 4.0.3 on), you
might find messages like this in your error log:
010301 14:38:23 Aborted connection 854 to db: 'users' user: 'josh'
Aborted connections messages appear in the error log, the cause
can be any of the following:
interactive_timeoutseconds without issing any requests to the server. See section 5.2.3 Server System Variables.
When any of these things happen, the server increments the
Aborted_clients status variable.
The server increments the
Aborted_connects status variable when the
following things happen:
connect_timeoutseconds to get a connect packet. See section 5.2.3 Server System Variables.
Note that if these kinds of things happen, it might indicate that someone is trying to break into your database!
Other reasons for problems with aborted clients or aborted connections:
max_allowed_packetvariable value is too small or queries require more memory than you have allocated for
mysqld. See section A.2.10
Packet too large.
The table is full
There are several ways a full-table error can occur:
tmp_table_sizebytes. To avoid this problem, you can use the
-O tmp_table_size=#option to make
mysqldincrease the temporary table size or use the SQL option
SQL_BIG_TABLESbefore you issue the problematic query. See section 126.96.36.199
SETSyntax. You can also start
--big-tablesoption. This is exactly the same as using
SQL_BIG_TABLESfor all queries. As of MySQL 3.23, this problem should not occur. If an in-memory temporary table becomes larger than
tmp_table_size, the server automatically converts it to a disk-based
InnoDBtables and run out of room in the
InnoDBtablespace. In this case, the solution is to extend the
InnoDBtablespace. See section 16.8 Adding and Removing
InnoDBData and Log Files.
MyISAMtables on an operating system that supports files only up to 2GB in size and you have hit this limit for the data file or index file.
MyISAMtable and the space required for the table exceeds what is allowed by the internal pointer size. (If you don't specify the
MAX_ROWStable option when you create a table, MySQL allocates pointers to hold only 4GB of data). You can check the maximum data/index sizes by using this statement:
SHOW TABLE STATUS FROM database LIKE 'tbl_name';You also can use
myisamchk -dv /path/to/table-index-file. If the pointer size is too small, you can fix the problem by using
ALTER TABLE tbl_name MAX_ROWS=1000000000 AVG_ROW_LENGTH=nnn;You have to specify
AVG_ROW_LENGTHonly for tables with
TEXTcolumns; in this case, MySQL can't optimize 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 the following type, it means that MySQL can't create a temporary file for the result set in the temporary directory:
Can't create/write to file '\\sqla3fe_0.ism'.
The preceding error is a
typical error message for Windows; the Unix error message is similar.
The fix is to start
mysqld with the
--tmpdir option or to
add the option to the
[mysqld] section of your option file.
For example, to specify a directory of `C:\temp', use these lines:
The `C:\temp' directory must already exist. See section 4.3.2 Using Option Files.
Check also the error code that you get with
perror. One reason
the server cannot write to a table is that the filesystem is full:
shell> perror 28 Error code 28: No space left on device
Commands out of sync
If you get
Commands out of sync; you can't run this command now
in your client code, you are calling client functions in the wrong order.
This can happen, for example, if you are using
try to execute a new query before you have called
It can also happen if you try to execute two queries that return data without
mysql_store_result() in between.
If you get the following error, it means that when
mysqld was started
or when it reloaded the grant tables, it found an account in the
table that had an invalid password.
Found wrong password for user: 'some_user'@'some_host'; ignoring user
As a result, the account is simply ignored by the permission system.
The following list indicates possible causes of and fixes for this problem:
mysqldwith an old
usertable. You can check this by executing
mysqlshow mysql userto see whether the
Passwordcolumn is shorter than 16 characters. If so, you can correct this condition by running the
--old-protocoloption. Update the account in the
usertable to have a new password or restart
usertable without using the
mysqlto update the account in the
usertable with a new password, making sure to use the
mysql> UPDATE user SET Password=PASSWORD('your password') -> WHERE User='some_user' AND Host='some_host';
Table 'xxx' doesn't exist
If you get either of the following errors, it usually means that no table
exists in the current database with the name
Table 'xxx' doesn't exist Can't find file: 'xxx' (errno: 2)
In some cases, it may be that the table does exist but that you are not referring to it correctly:
You can check which tables you have in the current database with
SHOW TABLES. See section 14.5.3
Can't initialize character set xxx
You might see an error like this if you have character set problems:
MySQL Connection Failed: Can't initialize character set xxx
This error can have any of the following causes:
--with-extra-charsets=xxxoption. See section 2.3.2 Typical
configureOptions. All standard MySQL binaries are compiled with
--with-extra-character-sets=complex, which enables support for all multi-byte character sets. See section 5.7.1 The Character Set Used for Data and Sorting.
mysqld, and the character set definition files are not in the place where the client expects to find them. In this case, you need to use one of the following methods to solve the problem:
If you get
ERROR '...' not found (errno: 23),
Can't open file:
... (errno: 24), or any other error with
errno 23 or
from MySQL, it means that you haven't allocated enough file descriptors for
the MySQL server. You can use the
perror utility to get a
description of what the error number means:
shell> perror 23 File table overflow shell> perror 24 Too many open files shell> perror 11 Resource temporarily unavailable
The problem here is that
mysqld is trying to keep open too many
files simultaneously. You can either tell
mysqld not to open so
many files at once or increase the number of file descriptors
mysqld to keep open fewer files at a time, you can make the
table cache smaller by reducing the value of the
variable (the default value is 64). Reducing the value of
max_connections also will reduce the number of open files (the
default value is 100).
To change the number of file descriptors available to
mysqld, you can
--open-files-limit option to
mysqld_safe or (as of
MySQL 3.23.30) set the the
open_files_limit system variable.
See section 5.2.3 Server System Variables.
The easiest way to set these values is to add an option to your option file.
See section 4.3.2 Using Option Files. If you have an old version of
doesn't support setting the open files limit, you can edit the
mysqld_safe script. There is a commented-out line
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
ulimit can increase the number of file
descriptors, but only up to the limit imposed by the operating system. There
is also a ``hard'' limit that can only be overridden if you start
root (just remember that you
also need to start the server with the
--user option in this case).
If you need to increase the operating system limit on the number of file
descriptors available to each process, consult the documentation for your
Note: If you run the
ulimit will not work!
tcsh will also report incorrect values when you ask for the current
limits. In this case, you should start
When you are linking an application program to use the MySQL client library,
you might get undefined reference errors for symbols that start with
such as those shown here:
/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 problem by adding
-lmysqlclient at the end of your link command, where
represents the pathname of the directory where the client library is
located. To find the correct directory, try this command:
shell> mysql_config --libs
The command output might indicate other libraries that should be specified on the link command as well.
If you get
undefined reference errors for the
compress functions, add
-lz to the end of your
link command and try again.
If you get
undefined reference errors for functions that should
exist on your system, such as
connect, check the manual page for the
function in question to determine which libraries you should add to the link
You might get
undefined reference errors such as the following for
functions that don't exist on your system:
mf_format.o(.text+0x201): undefined reference to `__lxstat'
This usually means that your MySQL client library was compiled on a system that is not 100% compatible with yours. In this case, you should download the latest MySQL source distribution and compile MySQL yourself. See section 2.3 MySQL Installation Using a Source Distribution.
You might get undefined reference errors at runtime when you try to execute
a MySQL program. If these errors indicate symbols that start with
mysql_ or that the
mysqlclient library can't be found, it
means that your system can't find the shared `libmysqlclient.so' library.
The fix for this is to tell your system to search for shared
libraries where the library is located. Use whichever of the following methods
is appropriate for your system:
Another way to solve this problem is by linking your program statically with
-static option, or by removing the dynamic MySQL libraries
before linking your code. Before trying the second method, you should be
sure that no other programs are using the dynamic libraries.
On Windows, you can run the server as a Windows service using normal user accounts beginning with MySQL 4.0.17 and 4.1.2. (Older MySQL versions required you to have administrator rights. This was a bug introduced in MySQL 3.23.54).
On Unix, the MySQL server
mysqld can be started and run by any user.
However, you should avoid running the server as the Unix
for security reasons. To change
mysqld to run as a normal
unprivileged Unix user
user_name, you must do the following:
user_namehas privileges to read and write files in them (you might need to do this as the Unix
shell> chown -R user_name /path/to/mysql/datadirIf directories or files within the MySQL data directory are symbolic links, you'll also need to follow those links and change the directories and files they point to.
chown -Rmight not follow symbolic links for you.
user_name. If you are using MySQL 3.22 or later, another alternative is to start
mysqldas the Unix
rootuser and use the
mysqldwill switch to run as the Unix user
user_namebefore accepting any connections.
useroption 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:
At this point, your
mysqld process should be running as
the Unix user
user_name. One thing hasn't changed, though: the
contents of the grant table in the
mysql database. By default, the
grant tables are initialized such that only the MySQL
root accounts have permission to access the
database or to create or drop databases. Unless you have changed those
permissions, they still hold. This does not stop you from accessing
MySQL as the MySQL
root user when you're logged in
as a Unix user other than
root; just start your
client programs with the
Note that accessing the MySQL server as the MySQL
root user from
a client program by supplying
--user=root on the command line has
nothing to do with MySQL running as the Unix
root user, or,
indeed, as any other Unix user. The access permissions and usernames of MySQL
accounts are completely separate from those of Unix login accounts. The only
connection with Unix usernames is that if you don't provide a
option when you invoke a client program, the client will try to connect
using your Unix login name as your MySQL username.
If your Unix machine itself isn't secured, you should assign passwords
to the MySQL
root accounts in the grant tables. Otherwise, any
user with a login account on that machine can run
mysql with a
--user=root option and perform any operation. (It is a good idea to
assign passwords to MySQL accounts in any case, but especially so when
other login accounts exist on the server host.
See section 2.4 Post-installation Setup and Testing.
If you have problems with file permissions, the
variable might be set incorrectly when
mysqld starts. For example,
MySQL might issue the following error message when you create a table:
ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13)
The default umask value is
0660. You can change this behavior by
mysqld_safe as follows:
shell> UMASK=384 # = 600 in octal shell> export UMASK shell> /path/to/mysqld_safe &
By default, MySQL creates database and
with an access permission value of
0700. You can modify this
behavior by setting the
UMASK_DIR variable. If you set its value, new
directories are created with the combined
values. For example, if you want to give group access to all new
directories, you can do this:
shell> UMASK_DIR=504 # = 770 in octal shell> export UMASK_DIR shell> /path/to/mysqld_safe &
In MySQL 3.23.25 and above, MySQL assumes that the
UMASK_DIR is in octal if it starts
with a zero.
See section E Environment Variables.
All MySQL versions are tested on many platforms before they are released. This doesn't mean that there are no bugs in MySQL, but if there are bugs, they should be very few and can be hard to find. If you have a problem, it will always help if you try to find out exactly what crashes your system, as you will have a much better chance of getting the problem fixed quickly.
First, you should try to find out whether the problem is that the
mysqld server dies or whether your problem has to do with your
client. You can check how long your
mysqld server has been up by
mysqladmin version. If
mysqld has died and
restarted, you may find the reason by looking in the server's error log.
See section 5.8.1 The Error Log.
On some systems you can find in the error log a stack trace of where
mysqld died that you can resolve with the
program. See section D.1.4 Using a Stack Trace. Note that the variable values written in
the error log may not always be 100% correct.
Many server crashes are caused by corrupted data files or index files. MySQL
will update the files 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 the
data is written but not the indexes.) This means that the data is safe even
mysqld crashes, because the operating system will ensure that the
unflushed data is written to disk. You can force MySQL to flush everything
to disk after every SQL statement by starting
mysqld with the
The preceding means that normally you should not get corrupted tables unless one of the following happens:
mysqldthat caused it to die in the middle of an update.
mysqldwithout locking the table properly.
mysqldservers using the same data directory on a system that doesn't support good filesystem locks (normally handled by the
lockdlock manager), or you are running multiple servers with the
ALTER TABLEon a repaired copy of the table.
Because it is very difficult to know why something is crashing, first try to check whether things that work for others crash for you. Please try the following things:
mysqladmin shutdown, run
myisamchk --silent --force */*.MYIfrom the data directory to check all
MyISAMtables, and restart
mysqld. This will ensure that you are running from a clean state. See section 5 Database Administration.
--logoption and try to determine from the information written to the log whether some specific query kills the server. About 95% of all bugs are related to a particular query. Normally, this will be one of the last queries in the log file just before the server restarts. See section 5.8.2 The General Query Log. If you can repeatedly kill MySQL with a specific query, even when you have checked all tables just before issuing it, then you have been able to locate the bug and should submit a bug report for it. See section 188.8.131.52 How to Report Bugs or Problems.
fork_big.plscript. (It is located in the `tests' directory of source distributions.)
configureand then recompile. See section D.1 Debugging a MySQL server.
mysqld. On some systems, the
lockdlock manager does not work properly; the
mysqldnot to use external locking. (This means that you cannot run two
mysqldservers on the same data directory and that you must be careful if you use
myisamchk. Nevertheless, it may be instructive to try the option as a test.)
mysqladmin -u root processlistwhen
mysqldappears to be running but not responding? Sometimes
mysqldis not comatose even though you might think so. The problem may be that all connections are in use, or there may be some internal lock problem.
mysqladmin -u root processlistusually will be able to make a connection even in these cases, and can provide useful information about the current number of connections and their status.
mysqladmin -i 5 statusor
mysqladmin -i 5 -r statusin a separate window to produce statistics while you run your other queries.
gdb(or another debugger). See section D.1.3 Debugging
gdbyou can do this with the following commands when
mysqldhas crashed inside
backtrace info local up info local up info localWith
gdb, you can also examine which threads exist with
info threadsand switch to a specific thread with
thread #, where
#is the thread ID.
TEXTcolumns), you can try to change all
ALTER TABLE. This will force MySQL to use fixed-size rows. Fixed-size rows take a little extra space, but are much more tolerant to corruption. The current dynamic row code has been in use at MySQL AB for several years with very few problems, but by nature dynamic-length rows are more prone to errors, so it may be a good idea to try this strategy to see whether it helps.
If you have never set a
root password for MySQL, the server will
not require a password at all for connecting as
root. However, it is
recommended to set a password for each account. See section 5.3.1 General Security Guidelines.
If you set a
root password previously, but have forgotten what it
was, you can set a new password. The following procedure is for Windows
systems. The procedure for Unix systems is given later in this section.
The procedure under Windows:
Start Menu -> Control Panel -> Administrative Tools -> ServicesThen find the MySQL service in the list, and stop it. If your server is not running as a service, you may need to use the Task Manager to force it to stop.
Start Menu -> Run -> cmd
C:\> C:\mysql\bin\mysqld-nt --skip-grant-tablesThis starts the server in a special mode that does not check the grant tables to control access.
C:\> C:\mysql\bin\mysqladmin -u root flush-privileges password "newpwd" C:\> C:\mysql\bin\mysqladmin -u root -p shutdownReplace ``newpwd'' with the actual
rootpassword that you want to use. The second command will prompt you to enter the new password for access. Enter the password that you assigned in the first command.
In a Unix environment, the procedure is as follows:
rootuser or as the same user that the
mysqldserver runs as.
kill -9) to the
mysqldprocess, using the name of the `.pid' file in the following command:
shell> kill `cat /mysql-data-directory/hostname.pid`Note the use of backquotes rather than forward quotes with the
catcommand; these cause the output of
catto be substituted into the
shell> mysqld_safe --skip-grant-tables &
shell> mysqladmin -u root flush-privileges password "newpwd"Replace ``newpwd'' with the actual
rootpassword that you want to use.
Alternatively, you can set the new password using the
mysqldand restart it with the
--skip-grant-tablesoption as described earlier.
mysqldserver with this command:
shell> mysql -u root
mysql> UPDATE mysql.user SET Password=PASSWORD('newpwd') -> WHERE User='root'; mysql> FLUSH PRIVILEGES;Replace ``newpwd'' with the actual
rootpassword that you want to use.
When a disk-full condition occurs, MySQL does the following:
To alleviate the problem, you can take the following actions:
mysqladmin killto the thread. The thread will be aborted the next time it checks the disk (in one minute).
Exceptions to the preceding behavior are when you use
REPAIR TABLE or
OPTIMIZE TABLE or when the indexes are created in a batch after
LOAD DATA INFILE or after an
ALTER TABLE statement.
All of these statements may create large temporary files that left to
themselves would cause big problems for the rest of the system. If the disk
becomes full while MySQL is doing any of these operations,
it will remove the big temporary files and mark the table as crashed.
The exception is that for
ALTER TABLE, the old table will be left
MySQL uses the value of the
TMPDIR environment variable as the
pathname of the directory in which to store temporary files. If you don't
TMPDIR set, MySQL uses the system default, which is normally
`/tmp', `/var/tmp', or `/usr/tmp'. If the filesystem
containing your temporary file directory is too small, you can use the
--tmpdir option to
mysqld to specify a directory in a
filesystem where you have enough space.
Starting from MySQL 4.1, the
--tmpdir option can be set to a list
of several paths that are used in round-robin fashion. Paths should be
separated by colon characters (`:') on Unix and semicolon characters
(`;') on Windows, NetWare, and OS/2. Note: To spread load
between several physical disks, these paths should end up on different
physical disks, not different partitions of the same disk.
If the MySQL server is acting as a replication slave, you should not set
--tmpdir to point to a directory on a memory-based filesystem or to a
directory that is cleared when the server host restarts. A replication
slave needs some of its temporary files to survive a machine restart so that
it can replicate temporary tables or
LOAD DATA INFILE operations. If
files in the temporary file directory are lost when the server restarts,
replication will fail.
MySQL creates all temporary files as hidden files. This ensures
that the temporary files will be removed if
mysqld is terminated. The
disadvantage of using hidden files is that you will not see a big temporary
file that fills up the filesystem in which the temporary file directory is
When sorting (
ORDER BY or
GROUP BY), MySQL normally
uses one or two temporary files. The maximum disk space required is determined
by the following expression:
(length of what is sorted + sizeof(row pointer)) * number of matched rows * 2
The row pointer size is usually four bytes, but may grow in the future for really big tables.
SELECT queries, MySQL also creates temporary SQL
tables. These are not hidden and have names of the form `SQL_*'.
ALTER TABLE creates a temporary table in the same directory as
the original table.
The default location for the Unix socket file that the server uses for communication with local clients is `/tmp/mysql.sock'. This might cause problems, because on some versions of Unix, anyone can delete files in the `/tmp' directory.
On most versions of Unix, you can protect your `/tmp' directory so that
files can be deleted only by their owners or the superuser (
To do this, set the
sticky bit on the `/tmp' directory by
logging in as
root and using the following command:
shell> chmod +t /tmp
You can check whether the
sticky bit is set by executing
/tmp. If the last permission character is
t, the bit is set.
Another approach is to change the place where the server creates the Unix socket file. If you do this, you should also let client programs know the new location of the file. You can specify the file location in several ways:
[mysqld] socket=/path/to/socket [client] socket=/path/to/socketSee section 4.3.2 Using Option Files.
--socketoption on the command line to
mysqld_safeand when you run client programs.
MYSQL_UNIX_PORTenvironment variable to the path of the Unix socket file.
--with-unix-socket-pathoption when you run
configure. See section 2.3.2 Typical
You can test whether the new socket location works by attempting to connect to the server with this command:
shell> mysqladmin --socket=/path/to/socket version
If you have a problem with
SELECT NOW() returning values in GMT and
not your local time, you have to tell the server your current time zone.
The same applies if
UNIX_TIMESTAMP() returns the wrong value.
This should be done for the environment in which the server runs, for
See section E Environment Variables.
You can set the time zone for the server with the
--timezone=timezone_name option to
mysqld_safe. You can
also set it by setting the
TZ environment variable before you
The allowable values for
system-dependent. Consult your operating system documentation to see
what values are acceptable.
By default, MySQL searches are not case sensitive (although there are
some character sets that are never case-insensitive, such as
This means that if you search with
col_name LIKE 'a%', you will get all
column values that start with
a. If you want to make this
search case sensitive, make sure that one of the operands is a binary string.
You can do this with the
BINARY operator. Write the condition as either
BINARY col_name LIKE 'a%' or
col_name LIKE BINARY 'a%'.
If you want a column always to be treated in case-sensitive fashion,
declare it as
BINARY. See section 14.2.5
CREATE TABLE Syntax.
Simple comparison operations (
>=, >, = , < , <=, sorting and grouping)
are based on each character's ``sort value.'' Characters with the same
sort value (such as `E', `e' and `é') are treated as the
If you are using Chinese data in the so-called
big5 encoding, you
want to make all character columns
BINARY. This works because the
sorting order of
big5 encoding characters is based on the order of
ASCII codes. As of MySQL 4.1, you can explicitly declare that a column should
big5 character set:
CREATE TABLE t (name CHAR(40) CHARACTER SET big5);
The format of a
DATE value is
'YYYY-MM-DD'. According to
standard SQL, no other format is allowed. You should use this format in
UPDATE expressions and in the
WHERE clause of
statements. For example:
mysql> SELECT * FROM tbl_name WHERE date >= '2003-05-05';
As a convenience, MySQL automatically converts a date to a number if
the date is used in a numeric context (and vice versa). It is also smart
enough to allow a ``relaxed'' string form when updating and in a
clause that compares a date to a
DATE, or a
DATETIME column. (Relaxed form means that any punctuation character
may be used as the separator between parts. For example,
'2004#08#15' are equivalent.) MySQL can also convert a
string containing no separators (such as
'20040815'), provided it
makes sense as a date.
The special date
'0000-00-00' can be stored and retrieved as
'0000-00-00'. When using a
'0000-00-00' date through
Connector/ODBC, it is automatically converted to
Connector/ODBC 2.50.12 and above, because ODBC can't handle this kind of
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';
However, the following will not work:
mysql> SELECT idate FROM tbl_name WHERE STRCMP(idate,'20030505')=0;
STRCMP() is a string function, so it converts
idate to a
'YYYY-MM-DD' format and performs a string comparison.
It does not convert
'20030505' to the date
and perform a date comparison.
The MySQL server packs dates for storage, so it can't store a given date
if it would not fit onto the result buffer. Note that MySQL does very
limited checking whether the date is correct. If you store an incorrect
date, such as
'2004-2-31', MySQL stores it as given. The rules
for accepting a date are:
DATETIMEcolumns even if it is not strictly legal.
DATEcolumn and you only know part of the date.
If the date cannot be converted to any reasonable value, a
stored in the
DATE column, which will be retrieved as
'0000-00-00'. This is both a speed and convenience issue. We believe
that the database server's responsibility 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 and not the server to check the dates.
The concept of the
NULL value is a common source of confusion for
newcomers to SQL, who often think that
NULL is the same thing as an
''. This is not the case. For example, the following
statements are completely different:
mysql> INSERT INTO my_table (phone) VALUES (NULL); mysql> INSERT INTO my_table (phone) VALUES ('');
Both statements insert a value into the
phone column, but the first
NULL value and the second inserts an empty string. The
meaning of the first can be regarded as ``phone number is not known'' and the
meaning of the second can be regarded as ``the person is known to have no
phone, and thus no phone number.''
To help with
NULL handling, you can use the
IS NULL and
IS NOT NULL operators and the
In SQL, the
NULL value is never true in comparison to any
other value, even
NULL. An expression that contains
always produces a
NULL value unless otherwise indicated in
the documentation for the operators and functions involved in the
expression. All columns in the following example return
mysql> SELECT NULL, 1+NULL, CONCAT('Invisible',NULL);
If you want to search for column values that are
cannot use the
=NULL test. The following statement returns no
expr = NULL is never true for any expression:
mysql> SELECT * FROM my_table WHERE phone = NULL;
To look for
NULL values, you must use the
IS NULL test.
The following statements showhow to find the
NULL phone number and the
empty phone number:
mysql> SELECT * FROM my_table WHERE phone IS NULL; mysql> SELECT * FROM my_table WHERE phone = '';
You can add an index on a column that can have
values only if you are using MySQL 3.23.2 or newer and are using the
BDB storage engine.
In earlier versions and with other storage engines, you must declare indexed
NOT NULL. This also means you cannot then insert
NULL into an indexed column.
When reading data with
LOAD DATA INFILE, empty or missing columns
are updated with
''. If you want a
NULL value in a column,
you should use
\N in the data file. The literal word
may also be used under some circumstances.
See section 14.1.5
LOAD DATA INFILE Syntax.
GROUP BY, or
ORDER BY, all
NULL values are regarded as equal.
NULL values are presented first, or
last if you specify
DESC to sort in descending order. Exception:
In MySQL 4.0.2 through 4.0.10,
NULL values sort first
regardless of sort order.
Aggregate (summary) functions such as
NULL values. The exception to this is
COUNT(*), which counts rows and not individual column values.
For example, the following statement produces two counts.
The first is a count of the number of rows in the table, and the second
is a count of the number of non-
NULL values in the
mysql> SELECT COUNT(*), COUNT(age) FROM person;
For some column types, MySQL handles
NULL values specially. If you
NULL into a
TIMESTAMP column, the
current date and time is inserted. If you insert
NULL into an
AUTO_INCREMENT column, the next number in the sequence is inserted.
You can use an alias to refer to a column in
ORDER BY, or
HAVING clauses. Aliases can also be used
to give columns better names:
SELECT SQRT(a*b) AS rt FROM tbl_name GROUP BY rt HAVING rt > 0; SELECT id, COUNT(*) AS cnt FROM tbl_name GROUP BY id HAVING cnt > 0; SELECT id AS 'Customer identity' FROM tbl_name;
Note that standard SQL doesn't allow you to refer to a column alias in a
WHERE clause. This is because when the
WHERE code is
executed, the column value may not yet be determined. For example, the
following query is illegal:
SELECT id, COUNT(*) AS cnt FROM tbl_name WHERE cnt > 0 GROUP BY id;
WHERE statement is executed to determine which rows should
be included in the
GROUP BY part, whereas
HAVING is used to
decide which rows from the result set should be used.
MySQL does not support subqueries prior to Version 4.1, or the use of more
than one table in the
DELETE statement prior to Version 4.0. If your
version of MySQL does not support subqueries or multiple-table
statements, you can use the following approach to delete rows from two
SELECTthe rows based on some
WHEREcondition in the main table.
DELETEthe rows in the main table based on the same condition.
DELETE FROM related_table WHERE related_column IN (selected_rows).
If the total length of the
DELETE statement for
more than 1MB (the default value of the
variable), you should split it into smaller parts and execute multiple
DELETE statements. You will probably get the fastest
by specifying only 100 to 1000
related_column values per statement if the
related_column is indexed. If the
indexed, the speed is independent of the number of arguments in the
If you have a complicated query that uses many tables but that doesn't return any rows, you should use the following procedure to find out what is wrong:
EXPLAINto check whether you can find something that is obviously wrong. See section 7.2.1
EXPLAINSyntax (Get Information About a
LIMIT 10with the query.
SELECTfor the column that should have matched a row against the table that was last removed from the query.
DOUBLEcolumns with numbers that have decimals, you can't use equality (
=) comparisons. This problem is common in most computer languages because not all floating-point values can be stored with exact precision. In some cases, changing the
DOUBLEwill fix this. See section A.5.7 Problems with Floating-point Comparisons.
mysql test < query.sqlthat shows your problems. You can create a test file by dumping the tables with
mysqldump --quick db_name tbl_name_1 ... tbl_name_n > query.sql. Open the file in an editor, remove some insert lines (if there are too many of them), and add your
SELECTstatement at the end of the file. Verify that the test file demonstrates your problem by executing these commands:
shell> mysqladmin create test2 shell> mysql test2 < query.sqlPost the test file using
mysqlbugto the general MySQL mailing list. See section 184.108.40.206 The MySQL Mailing Lists.
Floating-point numbers sometimes cause confusion because they
are not stored as exact values inside computer architecture. What you
can see on the screen usually is not the exact value of the number.
The column types
DECIMAL are such.
DECIMAL columns store values with exact precision because they are
represented as strings, but calculations on
DECIMAL values may be done
using floating-point operations.
The following example demonstrate the problem. It shows that even for the
DECIMAL column type, calculations that are done using floating-point
operations are subject to floating-point error.
mysql> CREATE TABLE t1 (i INT, d1 DECIMAL(9,2), d2 DECIMAL(9,2)); mysql> 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 (the values of
not appear to be different), they may do so because the difference between
the numbers shows up around tenth decimal or so, depending on computer
The problem cannot be solved by using
ROUND() or similar functions,
because the result is still a floating-point number:
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 when displayed with more
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 your computer architecture, you may or may not see similar results. Different CPUs may evaluate floating-point numbers differently. For example, on some machines you may get the ``correct'' results by multiplying both arguments by 1, as the following example shows.
Warning: Never use this method in your applications. It is not an example of a trustworthy 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 that the preceding example seems to work is that on the particular machine where the test was done, CPU floating-point arithmetic happens to round the numbers to the same value. However, there is no rule that any CPU should do so, so this method cannot be trusted.
The correct way to do floating-point number comparison is to first decide on what is the desired tolerance between the numbers and then do the comparison against the tolerance value. For example, if we agree that floating-point numbers should be regarded the same if they are same within a precision of one in ten thousand (0.0001), the comparison should be written to find differences larger than the tolerance value:
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)
Conversely, if we wanted to get rows where the numbers are the same, the test should find differences within the tolerance value:
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 | +------+-------+-------+
MySQL uses a cost-based optimizer to determine the best way to resolve a query. In many cases, MySQL can calculate the best possible query plan, but sometimes MySQL doesn't have enough information about the data at hand and has to make ``educated'' guesses about the data.
This section is intended for the cases when MySQL doesn't get it right.
The tools you have available to help MySQL do the ``right'' things are:
EXPLAIN. See section 7.2.1
EXPLAINSyntax (Get Information About a
ANALYZE TABLE. See section 220.127.116.11
IGNORE INDEX. See section 14.1.7
STRAIGHT JOIN. See section 14.1.7
The output from
EXPLAIN will show
ALL in the
column when MySQL uses a table scan to resolve a query. This usually happens
under the following conditions:
WHEREclause for indexed columns.
For small tables, a table scan often is appropriate. For large tables, try the following techniques to to avoid having the optimizer incorrectly choose a table scan:
ANALYZE TABLEto update the key distributions for the scanned table. See section 18.104.22.168
FORCE INDEXfor the scanned table to tell MySQL that table scans are very expensive compared to using the given index. See section 14.1.7
SELECT * FROM t1,t2 force index(index_for_column) WHERE t1.column=t2.column;
--max-seeks-for-key=1000option or use
SET MAX_SEEKS_FOR_KEY=1000to tell the optimizer to assume that no key scan will cause more than 1000 key seeks. See section 5.2.3 Server System Variables.
ALTER TABLE changes a table to the current character set.
If you get a duplicate-key error during
ALTER TABLE, the cause
is either that the new character sets maps two keys to the same value
or that the table is corrupted. In the latter case, you should run
REPAIR TABLE on the table.
ALTER TABLE dies with the following error, the problem may be that
MySQL crashed during an earlier
ALTER TABLE operation and there is an
old table named `A-something' or `B-something' lying around:
Error on rename of './database/name.frm' to './database/B-a.frm' (Errcode: 17)
In this case, go to the MySQL data directory and delete all files that have
names starting with
B-. (You may want to move them
elsewhere instead of deleting them.)
ALTER TABLE works the following way:
If something goes wrong with the renaming operation, MySQL tries to undo the changes. If something goes seriously wrong (although this shouldn't happen), MySQL may leave the old table as `B-xxx', but a simple rename of the table files at the system level should get your data back.
If you use
ALTER TABLE on a transactional table or if you are using
Windows or OS/2,
ALTER TABLE will
UNLOCK the table if you had
LOCK TABLE on it. This is because
InnoDB and these
operating systems cannot drop a table that is in use.
First, consider whether you really need to change the column order 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. The first of the following statements returns columns
in the order
the second returns them in the order
mysql> SELECT col_name1, col_name2, col_name3 FROM tbl_name; mysql> SELECT col_name1, col_name3, col_name2 FROM tbl_name;
If you decide to change the order of table columns anyway, you can do so as follows:
mysql> INSERT INTO new_table -> SELECT columns-in-new_table-order FROM old_table;
mysql> ALTER TABLE new_table RENAME old_table;
SELECT * is quite suitable for testing queries. However, in an
application, you should never rely on using
SELECT * and
retrieving the columns based on their position. The order and position
in which columns are returned will not remain the same if you add, move,
or delete columns. A simple change to your table structure will then cause
your application to fail.
The following list indicates limitations on the use of
TEMPORARYtable can only be of type
TEMPORARYtable more than once in the same query. For example, the following does not work.
mysql> SELECT * FROM temp_table, temp_table AS t2; ERROR 1137: Can't reopen table: 'temp_table'
SHOW TABLESstatement does not list
RENAMEto rename a
TEMPORARYtable. However, you can use
mysql> ALTER TABLE orig_name RENAME new_name;
Go to the first, previous, next, last section, table of contents.