This appendix describes the types of error information MySQL
provides and how to obtain information about them. It also lists the
error messages that the MySQL server and MySQL client programs
generate. The final section is for troubleshooting. It describes
common problems and errors that may occur and potential resolutions.

Error Message Sources

On the server side, error messages may occur during the
startup and shutdown processes, as a result of issues that
occur during SQL statement execution, and so forth.

The MySQL server writes some error messages to its error
log. These indicate issues of interest to database
administrators or that require DBA action.

The server sends other error messages to client
programs. These indicate issues pertaining only to a
particular client. The MySQL client library takes errors
received from the server and makes them available to the
host client program.

Client-side error messages are generated from within the
MySQL client library, usually involving problems
communicating with the server.

Example server-side error messages written to the error log:

This message produced during the startup process provides a
status or progress indicator:

Whether an error originates from within the client library or is
received from the server, a MySQL client program may respond in
varying ways. As just illustrated, the client may display the
error message so the user can take corrective measures. The
client may instead internally attempt to resolve or retry a
failed operation, or take other action.

Error Message Components

When an error occurs, error information includes several
components: an error code, SQLSTATE value, and message string.
These components have the following characteristics:

Error code: This value is numeric. It is MySQL-specific and
is not portable to other database systems.

Error codes are stable across General Availability (GA)
releases of a given MySQL series. Before a series reaches GA
status, new codes may still be under development and are
subject to change.

SQLSTATE value: This value is a five-character string (for
example, '42S02'). SQLSTATE values are
taken from ANSI SQL and ODBC and are more standardized than
the numeric error codes. The first two characters of an
SQLSTATE value indicate the error class:

Class = '00' indicates success.

Class = '01' indicates a warning.

Class = '02' indicates “not
found.” This is relevant within the context of
cursors and is used to control what happens when a
cursor reaches the end of a data set. This condition
also occurs for SELECT ... INTO
var_list statements
that retrieve no rows.

Class > '02' indicates an
exception.

For server-side errors, not all MySQL error numbers have
corresponding SQLSTATE values. In these cases,
'HY000' (general error) is used.

For client-side errors, the SQLSTATE value is always
'HY000' (general error), so it is not
meaningful for distinguishing one client error from another.

Message string: This string provides a textual description
of the error.

For error checking from within programs, use error code numbers or
symbols, not error message strings. Message strings do not change
often, but it is possible. Also, if the database administrator
changes the language setting, that affects the language of message
strings; see Section 10.11, “Setting the Error Message Language”.

Error information in MySQL is available in the server error log,
at the SQL level, from within client programs, and at the command
line.

SQL Error Message Interface

At the SQL level, there are several sources of error information
in MySQL:

SQL statement warning and error information is available
through the SHOW WARNINGS and
SHOW ERRORS statements. The
warning_count system
variable indicates the number of errors, warnings, and notes
(with notes excluded if the
sql_notes system variable
is disabled). The
error_count system variable
indicates the number of errors. Its value excludes warnings
and notes.

Client Error Message Interface

Errors that originate on the client side from within the
MySQL client library.

Errors that originate on the server side and are sent to the
client by the server. These are received within the client
library, which makes them available to the host client
program.

Regardless of whether an error originates from within the client
library or is received from the server, a MySQL client program
obtains the error code, SQLSTATE value, message string, and
other related information by calling C API functions in the
client library:

A MySQL client program may respond to an error in varying ways.
The client may display the error message so the user can take
corrective measures, internally attempt to resolve or retry a
failed operation, or take other action. For example, (using the
mysql client), a failure to connect to the
server might result in this message:

InnoDB reports this error when a table cannot
be created. If the error message refers to error 150, table
creation failed because a
foreign key
constraint was not correctly formed. If the error message
refers to error −1, table creation probably failed because
the table includes a column name that matched the name of an
internal InnoDB table.

An attempt to create a database failed because the database
already exists.

Drop the database first if you really want to replace an existing
database, or add an IF NOT EXISTS clause to the
CREATE DATABASE statement if to
retain an existing database without having the statement produce
an error.

Message: Row size too large. The maximum row size for the used
table type, not counting BLOBs, is %ld. This includes storage
overhead, check the manual. You have to change some columns to
TEXT or BLOBs

InnoDB reports this error when lock wait
timeout expires. The statement that waited too long was
rolled back (not the entire
transaction). You can
increase the value of the
innodb_lock_wait_timeout
configuration option if SQL statements should wait longer for
other transactions to complete, or decrease it if too many
long-running transactions are causing
locking problems and reducing
concurrency on a busy
system.

InnoDB reports this error when the total number
of locks exceeds the amount of memory devoted to managing locks.
To avoid this error, increase the value of
innodb_buffer_pool_size. Within
an individual application, a workaround may be to break a large
operation into smaller pieces. For example, if the error occurs
for a large INSERT, perform several
smaller INSERT operations.

Message: Deadlock found when trying to get lock; try restarting
transaction

InnoDB reports this error when a
transaction encounters a
deadlock and is automatically
rolled back so that your
application can take corrective action. To recover from this
error, run all the operations in this transaction again. A
deadlock occurs when requests for locks arrive in inconsistent
order between transactions. The transaction that was rolled back
released all its locks, and the other transaction can now get all
the locks it requested. Thus, when you re-run the transaction that
was rolled back, it might have to wait for other transactions to
complete, but typically the deadlock does not recur. If you
encounter frequent deadlocks, make the sequence of locking
operations (LOCK TABLES, SELECT ...
FOR UPDATE, and so on) consistent between the different
transactions or applications that experience the issue. See
Section 14.7.5, “Deadlocks in InnoDB” for details.

Message: This function has none of DETERMINISTIC, NO SQL, or READS
SQL DATA in its declaration and binary logging is enabled (you
*might* want to use the less safe log_bin_trust_function_creators
variable)

InnoDB reports this error when you attempt to
drop the last index that can enforce a particular referential
constraint.

For optimal performance with DML statements,
InnoDB requires an index to exist on
foreign key columns, so
that UPDATE and DELETE
operations on a parent
table can easily check whether corresponding rows exist in
the child table. MySQL
creates or drops such indexes automatically when needed, as a
side-effect of CREATE TABLE,
CREATE INDEX, and
ALTER TABLE statements.

When you drop an index, InnoDB checks if the
index is used for checking a foreign key constraint. It is still
OK to drop the index if there is another index that can be used to
enforce the same constraint. InnoDB prevents
you from dropping the last index that can enforce a particular
referential constraint.

Message: INSERT IGNORE... SELECT is unsafe because the order in
which rows are retrieved by the SELECT determines which (if any)
rows are ignored. This order cannot be predicted and may differ on
master and the slave.

Message: INSERT... SELECT... ON DUPLICATE KEY UPDATE is unsafe
because the order in which rows are retrieved by the SELECT
determines which (if any) rows are updated. This order cannot be
predicted and may differ on master and the slave.

Message: REPLACE... SELECT is unsafe because the order in which
rows are retrieved by the SELECT determines which (if any) rows
are replaced. This order cannot be predicted and may differ on
master and the slave.

Message: CREATE... IGNORE SELECT is unsafe because the order in
which rows are retrieved by the SELECT determines which (if any)
rows are ignored. This order cannot be predicted and may differ on
master and the slave.

Message: CREATE... REPLACE SELECT is unsafe because the order in
which rows are retrieved by the SELECT determines which (if any)
rows are replaced. This order cannot be predicted and may differ
on master and the slave.

Message: Statements writing to a table with an auto-increment
column after selecting from another table are unsafe because the
order in which rows are retrieved determines what (if any) rows
will be written. This order cannot be predicted and may differ on
master and the slave.

Message: CREATE TABLE... SELECT... on a table with an
auto-increment column is unsafe because the order in which rows
are retrieved by the SELECT determines which (if any) rows are
inserted. This order cannot be predicted and may differ on master
and the slave.

Message: Storing MySQL user name or password information in the
master info repository is not secure and is therefore not
recommended. Please consider using the USER and PASSWORD
connection options for START SLAVE; see the 'START SLAVE Syntax'
in the MySQL Manual for more information.

Message: When @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1, updates to
non-transactional tables can only be done in either autocommitted
statements or single-statement transactions, and never in the same
statement as updates to transactional tables.

Message: When @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1, the
statements CREATE TEMPORARY TABLE and DROP TEMPORARY TABLE can be
executed in a non-transactional context only, and require that
AUTOCOMMIT = 1. These statements are also not allowed in a
function or trigger because functions and triggers are also
considered to be multi-statement transactions.

Message: The value of @@GLOBAL.GTID_MODE can only change one step
at a time: OFF <-> UPGRADE_STEP_1 <-> UPGRADE_STEP_2
<-> ON. Also note that this value must be stepped up or down
simultaneously on all servers; see the Manual for instructions.

Message: Slave is not configured or failed to initialize properly.
You must at least set --server-id to enable either a master or a
slave. Additional error messages can be found in the MySQL error
log.

Message: When @@SESSION.GTID_NEXT is set to a GTID, you must
explicitly set it to a different value after a COMMIT or ROLLBACK.
Please check GTID_NEXT variable manual page for detailed
explanation. Current @@SESSION.GTID_NEXT is '%s'.

Message: sql_slave_skip_counter can not be set when the server is
running with @@GLOBAL.GTID_MODE = ON. Instead, for each
transaction that you want to skip, generate an empty transaction
with the same GTID as the transaction

Message: Slave has more GTIDs than the master has, using the
master's SERVER_UUID. This may indicate that the end of the binary
log was truncated or that the last binary log file was lost, e.g.,
after a power or disk failure when sync_binlog != 1. The master
may or may not have rolled back transactions that were already
replicated to the slave. Suggest to replicate any transactions
that master has rolled back from slave to master, and/or commit
empty transactions on master to account for transactions that have
been committed on master but are not included in GTID_EXECUTED.

The client library also makes available to host client programs
any errors that originate on the server side and are recieved by
the client from the server. For a list of server-side errors, see
Section B.3, “Server Error Message Reference”.

B.5 Global Error Message Reference

This section lists global error messages that are shared in the
sense that they can be produced by the MySQL server or by MySQL
client programs. These errors have error codes in the range from 1
to 999.

This section lists some common problems and error messages that
you may encounter. It describes how to determine the causes of the
problems and what to do to solve them.

B.6.1 How to Determine What Is Causing a Problem

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:

If you have one of the following symptoms, then it is
probably a hardware problems (such as memory, motherboard,
CPU, or hard disk) or kernel problem:

The keyboard does not work. This can normally be checked
by pressing the Caps Lock key. If the Caps Lock light
does not change, you have to replace your keyboard.
(Before doing this, you should try to restart your
computer and check all cables to the keyboard.)

The mouse pointer does not move.

The machine does not answer to a remote machine's pings.

Other programs that are not related to MySQL do not
behave correctly.

Your system restarted unexpectedly. (A faulty user-level
program should never be able to take down your system.)

In this case, you should start by checking all your cables
and run some diagnostic tool to check your hardware! You
should also check whether there are any patches, updates, or
service packs for your operating system that could likely
solve your problem. Check also that all your libraries (such
as glibc) are up to date.

It is always good to use a machine with ECC memory to
discover memory problems early.

If your keyboard is locked up, you may be able to recover by
logging in to your machine from another machine and
executing kbd_mode -a.

Please examine your system log file
(/var/log/messages or similar) for
reasons for your problem. If you think the problem is in
MySQL, you should also examine MySQL's log files. See
Section 5.4, “MySQL Server Logs”.

If you do not think you have hardware problems, you should
try to find out which program is causing problems. Try using
top, ps, Task Manager,
or some similar program, to check which program is taking
all CPU or is locking the machine.

Use top, df, or a
similar program to check whether you are out of memory, disk
space, file descriptors, or some other critical resource.

If the problem is some runaway process, you can always try
to kill it. If it does not want to die, there is probably a
bug in the operating system.

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 is 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 does not work.” This
provides us with no information about what could be the problem.

If a program fails, it is always useful to know the following
information:

Has the program in question made a segmentation fault (did
it dump core)?

Is the program taking up all available CPU time? Check with
top. Let the program run for a while, it
may simply be evaluating something computationally
intensive.

This section lists some errors that users frequently encounter
when running MySQL programs. Although the problems show up when
you try to run client programs, the solutions to many of the
problems involves changing the configuration of the MySQL
server.

B.6.2.2 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 file
system (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 do not specify a host name or if
you specify the special host name
localhost.

If the MySQL server is running on Windows, you can connect
using TCP/IP. If the server is started with the
--enable-named-pipe option, you
can also connect with named pipes if you run the client on the
host where the server is running. The name of the named pipe
is MySQL by default. If you do not give a
host name when connecting to mysqld, a
MySQL client first tries to connect to the named pipe. If that
does not work, it connects to the TCP/IP port. You can force
the use of named pipes on Windows by using
. as the host name.

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 file
name or TCP/IP port number when trying to connect to the
server. You should also check that the TCP/IP port you are
using has not been blocked by a firewall or port blocking
service.

The error (2003) Can't connect to MySQL server on
'server' (10061)
indicates that the network connection has been refused. You
should check that there is a MySQL server running, that it has
network connections enabled, and that the network port you
specified is the one configured on the server.

Start by checking whether there is a process named
mysqld running on your server host. (Use
ps xa | grep mysqld on Unix or the Task
Manager on Windows.) If there is no such process, you should
start the server. See Section 2.10.2, “Starting the Server”.

If a mysqld process is running, you can
check it by trying the following commands. The port number or
Unix socket file name might be different in your setup.
host_ip represents the IP address of the
machine where the server is running.

Regarding the use of backticks rather than forward quotation
marks with the hostname command; these
cause the output of hostname (that is, the
current host name) to be substituted into the
mysqladmin command. If you have no
hostname command or are running on Windows,
you can manually type the host name of your machine (without
backticks) following the -h option. You can
also try -h 127.0.0.1 to connect with
TCP/IP to the local host.

Make sure that the server has not been configured to ignore
network connections or (if you are attempting to connect
remotely) that it has not been configured to listen only
locally on its network interfaces. If the server was started
with --skip-networking, it will
not accept TCP/IP connections at all. If the server was
started with
--bind-address=127.0.0.1, it
will listen for TCP/IP connections only locally on the
loopback interface and will not accept remote connections.

Check to make sure that there is no firewall blocking access
to MySQL. Your firewall may be configured on the basis of the
application being executed, or the port number used by MySQL
for communication (3306 by default). Under Linux or Unix,
check your IP tables (or similar) configuration to ensure that
the port has not been blocked. Under Windows, applications
such as ZoneAlarm or Windows Firewall may need to be
configured not to block the MySQL port.

Here are some reasons the Can't connect to local
MySQL server error might occur:

mysqld is not running on the local
host. Check your operating system's process list to ensure
the mysqld process is present.

You have started the mysqld server with
the
--socket=/path/to/socket
option, but forgotten to tell client programs the new name
of the socket file. If you change the socket path name for
the server, you must also notify the MySQL clients. You
can do this by providing the same
--socket option when you
run client programs. You also need to ensure that clients
have permission to access the
mysql.sock file. To find out where
the socket file is, you can do:

The server or client program might not have the proper
access privileges for the directory that holds the Unix
socket file or the socket file itself. In this case, you
must either change the access privileges for the directory
or socket file so that the server and clients can access
them, or restart mysqld with a
--socket option that
specifies a socket file name 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 problem is:

Check whether the server is running on that host by
executing telnet some_host 3306 and
pressing the Enter key 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.

If the server is running on the local host, try using
mysqladmin -h localhost variables to
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 port
variable.)

If you are running under Linux and Security-Enhanced Linux
(SELinux) is enabled, make sure you have disabled SELinux
protection for the mysqld process.

B.6.2.2.1 Connection to MySQL Server Failing on Windows

When you're running a MySQL server on Windows with many
TCP/IP connections to it, and you're experiencing that quite
often your clients get a Can't connect to MySQL
server error, the reason might be that Windows
does not allow for enough ephemeral (short-lived) ports to
serve those connections.

The purpose of TIME_WAIT is to keep a
connection accepting packets even after the connection has
been closed. This is because Internet routing can cause a
packet to take a slow route to its destination and it may
arrive after both sides have agreed to close. If the port is
in use for a new connection, that packet from the old
connection could break the protocol or compromise personal
information from the original connection. The
TIME_WAIT delay prevents this by ensuring
that the port cannot be reused until after some time has
been permitted for those delayed packets to arrive.

It is safe to reduce TIME_WAIT greatly on
LAN connections because there is little chance of packets
arriving at very long delays, as they could through the
Internet with its comparatively large distances and
latencies.

Windows permits ephemeral (short-lived) TCP ports to the
user. After any port is closed it will remain in a
TIME_WAIT status for 120 seconds. The
port will not be available again until this time expires.
The default range of port numbers depends on the version of
Windows, with a more limited number of ports in older
versions:

Windows through Server 2003: Ports in range
1025–5000

Windows Vista, Server 2008, and newer: Ports in range
49152–65535

With a small stack of available TCP ports (5000) and a high
number of TCP ports being open and closed over a short
period of time along with the TIME_WAIT
status you have a good chance for running out of ports.
There are two ways to address this problem:

Reduce the number of TCP ports consumed quickly by
investigating connection pooling or persistent
connections where possible

Tune some settings in the Windows registry (see below)

Important

The following procedure involves modifying the Windows
registry. Before you modify the registry, make sure to
back it up and make sure that you understand how to
restore it if a problem occurs. For information about how
to back up, restore, and edit the registry, view the
following article in the Microsoft Knowledge Base:
http://support.microsoft.com/kb/256986/EN-US/.

Start Registry Editor
(Regedt32.exe).

Locate the following key in the registry:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

On the Edit menu, click Add
Value, and then add the following registry
value:

Value Name: MaxUserPort
Data Type: REG_DWORD
Value: 65534

This sets the number of ephemeral ports available to any
user. The valid range is between 5000 and 65534
(decimal). The default value is 0x1388 (5000 decimal).

On the Edit menu, click Add
Value, and then add the following registry
value:

Value Name: TcpTimedWaitDelay
Data Type: REG_DWORD
Value: 30

This sets the number of seconds to hold a TCP port
connection in TIME_WAIT state before
closing. The valid range is between 30 and 300 decimal,
although you may wish to check with Microsoft for the
latest permitted values. The default value is 0x78 (120
decimal).

Quit Registry Editor.

Reboot the machine.

Note

Undoing the above should be as simple as deleting the
registry entries you've created.

B.6.2.3 Lost connection to MySQL server

There are three likely causes for this error message.

Usually it indicates network connectivity trouble and you
should check the condition of your network if this error
occurs frequently. If the error message includes “during
query,” this is probably the case you are experiencing.

Sometimes the “during query” form happens when
millions of rows are being sent as part of one or more
queries. If you know that this is happening, you should try
increasing net_read_timeout
from its default of 30 seconds to 60 seconds or longer,
sufficient for the data transfer to complete.

More rarely, it can happen when the client is attempting the
initial connection to the server. In this case, if your
connect_timeout value is set
to only a few seconds, you may be able to resolve the problem
by increasing it to ten seconds, perhaps more if you have a
very long distance or slow connection. You can determine
whether you are experiencing this more uncommon cause by using
SHOW GLOBAL STATUS LIKE 'Aborted_connects'.
It will increase by one for each initial connection attempt
that the server aborts. You may see “reading
authorization packet” as part of the error message; if
so, that also suggests that this is the solution that you
need.

B.6.2.4 Client does not support authentication protocol

The current implementation of the authentication protocol uses
a password hashing algorithm that is incompatible with that
used by older (pre-4.1) clients. Attempts to connect to a 4.1
or higher server with an older client may fail with the
following message:

To deal with this problem, the preferred solution is to
upgrade all client programs to use a 4.1.1 or higher client
library. If that is not possible, use one of the following
approaches:

To connect to the server with a pre-4.1 client program,
use an account that still has a pre-4.1-style password.

Reset the password to pre-4.1 style for each user that
needs to use a pre-4.1 client program. This can be done
using the SET PASSWORD
statement and the
OLD_PASSWORD() function. As
of MySQL 5.6.6, it is also necessary to first ensure that
the authentication plugin for the account is
mysql_old_password:

For each account record displayed by the query, use
the Host and
User values and assign a password
using one of the methods described previously.

The Client does not support authentication
protocol error also can occur if multiple versions
of MySQL are installed but client programs are dynamically
linked and link to an older library. Make sure that clients
use the most recent library version with which they are
compatible. The procedure to do this will depend on your
system.

Note

The PHP mysql extension does not support
the authentication protocol in MySQL 4.1.1 and higher. This
is true regardless of the PHP version being used. If you
wish to use the mysql extension with
MySQL 4.1 or higher, you may need to follow one of the
options discussed above for configuring MySQL to work with
old clients. The mysqli extension (stands
for "MySQL, Improved"; added in PHP 5) is compatible with
the improved password hashing employed in MySQL 4.1 and
higher, and no special configuration of MySQL need be done
to use this MySQL client library. For more information about
the mysqli extension, see
http://php.net/mysqli.

B.6.2.5 Password Fails When Entered Interactively

MySQL client programs prompt for a password when invoked with
a --password or
-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 at the 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). That
is a problem with the system library, not with MySQL. To work
around it, change your MySQL password to a value that is eight
or fewer characters long, or put your password in an option
file.

B.6.2.6 Host 'host_name' is blocked

If the following error occurs, it means that
mysqld has received many connection
requests from the given host that were interrupted in the
middle:

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

The value of the
max_connect_errors system
variable determines how many successive interrupted connection
requests are permitted. After
max_connect_errors failed
requests without a successful connection,
mysqld assumes that something is wrong (for
example, that someone is trying to break in), and blocks the
host from further connections until you flush the host cache
by executing a FLUSH HOSTS
statement, a TRUNCATE TABLE
statement that truncates the Performance Schema
host_cache table, or a
mysqladmin flush-hosts command.

To adjust the permitted number of successive connection
errors, set
max_connect_errors at server
startup. For example, put these lines in the server
my.cnf file:

[mysqld]
max_connect_errors=10000

The value can also be set at runtime:

SET GLOBAL max_connect_errors=10000;

If you get the Host
'host_name' is blocked
error message for a given host, you should first verify that
there is nothing wrong with TCP/IP connections from that host.
If you are having network problems, it does no good to
increase the value of
max_connect_errors.

B.6.2.7 Too many connections

If clients encounter Too many connections
errors when attempting to connect to the
mysqld server, all available connections
are in use by other clients.

The permitted number of connections is controlled by the
max_connections system
variable. The default value is 151 to improve performance when
MySQL is used with the Apache Web server. To support more
connections, set
max_connections to a larger
value.

mysqld actually permits
max_connections
+ 1 client connections. The extra connection is reserved for
use by accounts that have the
SUPER privilege. By granting
the privilege to administrators and not to normal users (who
should not need it), an administrator who also has the
PROCESS privilege can connect
to the server and use SHOW
PROCESSLIST to diagnose problems even if the maximum
number of unprivileged clients are connected. See
Section 13.7.5.30, “SHOW PROCESSLIST Syntax”.

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
--quick option. This causes it
to use the mysql_use_result()
C API function to retrieve the result set, which places less
of a load on the client (but more on the server).

B.6.2.9 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. In this case, you normally get one of the
following error codes (which one you get is operating
system-dependent).

If you have a script, you just have to issue the query again
for the client to do an automatic reconnection. This assumes
that you have automatic reconnection in the client enabled
(which is the default for the mysql
command-line client).

Some other common reasons for the MySQL server has
gone away error are:

You (or the db administrator) has killed the running
thread with a KILL
statement or a mysqladmin kill command.

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.

A client application running on a different host does not
have the necessary privileges to connect to the MySQL
server from that host.

You have encountered a timeout on the server side and the
automatic reconnection in the client is disabled (the
reconnect flag in the
MYSQL structure is equal to 0).

You are using a Windows client and the server had dropped
the connection (probably because
wait_timeout expired)
before the command was issued.

The problem on Windows is that in some cases MySQL does
not get an error from the OS when writing to the TCP/IP
connection to the server, but instead gets the error when
trying to read the answer from the connection.

The solution to this is to either do a
mysql_ping() on the
connection if there has been a long time since the last
query (this is what Connector/ODBC does) or set
wait_timeout on the
mysqld server so high that it in
practice never times out.

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 4MB (1MB before
MySQL 5.6.6). You may also need to increase the maximum
packet size on the client end. More information on setting
the packet size is given in
Section B.6.2.10, “Packet Too Large”.

An INSERT or
REPLACE statement that
inserts a great many rows can also cause these sorts of
errors. Either one of these statements sends a single
request to the server irrespective of the number of rows
to be inserted; thus, you can often avoid the error by
reducing the number of rows sent per
INSERT or
REPLACE.

It is also possible to see this error if host name lookups
fail (for example, if the DNS server on which your server
or network relies goes down). This is because MySQL is
dependent on the host system for name resolution, but has
no way of knowing whether it is working—from MySQL's
point of view the problem is indistinguishable from any
other network timeout.

You may also see the MySQL server has gone
away error if MySQL is started with the
--skip-networking option.

Another networking issue that can cause this error occurs
if the MySQL port (default 3306) is blocked by your
firewall, thus preventing any connections at all to the
MySQL server.

You can also encounter this error with applications that
fork child processes, all of which try to use the same
connection to the MySQL server. This can be avoided by
using a separate connection for each child process.

You have encountered a bug where the server died while
executing the query.

You can check whether the MySQL server died and restarted by
executing mysqladmin version and examining
the server's uptime. If the client connection was broken
because mysqld crashed and restarted, you
should concentrate on finding the reason for the crash. Start
by checking whether issuing the query again kills the server
again. See Section B.6.3.3, “What to Do If MySQL Keeps Crashing”.

B.6.2.10 Packet Too Large

A communication packet is a single SQL statement sent to the
MySQL server, a single row that is sent to the client, or a
binary log event sent from a master replication server to a
slave.

The largest possible packet that can be transmitted to or from
a MySQL 5.6 server or client is 1GB.

When a MySQL client or the mysqld server
receives a packet bigger than
max_allowed_packet bytes, it
issues an
ER_NET_PACKET_TOO_LARGE error
and closes the connection. With some clients, you may also get
a Lost connection to MySQL server during
query error if the communication packet is too
large.

Both the client and the server have their own
max_allowed_packet variable,
so if you want to handle big packets, you must increase this
variable both in the client and in the server.

The server's default
max_allowed_packet value is
4MB (1MB before MySQL 5.6.6). 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:

shell> mysqld --max_allowed_packet=16M

You can also use an option file to set
max_allowed_packet. For
example, to set the size for the server to 16MB, add the
following lines in an option file:

[mysqld]
max_allowed_packet=16M

It is 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 a precaution to catch incorrect packets between
the client and server and also to ensure that you do not run
out of memory by using large packets accidentally.

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 mysqld_safe script and
restarting mysqld.

B.6.2.11 Communication Errors and Aborted Connections

If connection problems occur such as communication errors or
aborted connections, use these sources of information to
diagnose problems:

If these kinds of things happen, it might indicate that
someone is trying to break into your server! If the general
query log is enabled, messages for these types of problems are
logged to it.

If a client successfully connects but later disconnects
improperly or is terminated, the server increments the
Aborted_clients status
variable, and logs an Aborted
connection message to the error log. The cause can
be any of the following:

Use of Ethernet protocol with Linux, both half and full
duplex. Some Linux Ethernet drivers have this bug. You
should test for this bug by transferring a huge file using
FTP between the client and server machines. If a transfer
goes in burst-pause-burst-pause mode, you are experiencing
a Linux duplex syndrome. Switch the duplex mode for both
your network card and hub/switch to either full duplex or
to half duplex and test the results to determine the best
setting.

A problem with the thread library that causes interrupts
on reads.

Badly configured TCP/IP.

Faulty Ethernets, hubs, switches, cables, and so forth.
This can be diagnosed properly only by replacing hardware.

B.6.2.12 The table is full

If a table-full error occurs, it may be that the disk is full
or that the table has reached its maximum size. The effective
maximum table size for MySQL databases is usually determined
by operating system constraints on file sizes, not by MySQL
internal limits. See Section C.10.3, “Limits on Table Size”.

B.6.2.13 Can't create/write to file

If you get an error of the following type for some queries, it
means that MySQL cannot 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 message for Windows; the Unix
message is similar.

One 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:

Another cause of this error can be permissions issues. Make
sure that the MySQL server can write to the
tmpdir directory.

Check also the error code that you get with
perror. One reason the server cannot write
to a table is that the file system is full:

shell> perror 28
OS error code 28: No space left on device

If you get an error of the following type during startup, it
indicates that the file system or directory used for storing
data files is write protected. Provided that the write error
is to a test file, the error is not serious and can be safely
ignored.

Can't create test file /usr/local/mysql/data/master.lower-test

B.6.2.14 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.

B.6.2.15 Ignoring user

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
user 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:

You may be running a new version of
mysqld with an old
user table. Check whether the
Password column of that table is
shorter than 16 characters. If so, correct this condition
by running mysql_upgrade.

The account has an old password (eight characters long).
Update the account in the user table to
have a new password.

You have specified a password in the
user table without using the
PASSWORD() function. Use
mysql to update the account in the
user table with a new password, making
sure to use the PASSWORD()
function:

mysql> UPDATE user SET Password=PASSWORD('new_password')
-> WHERE User='some_user' AND Host='some_host';

B.6.2.16 Table 'tbl_name' doesn't exist

If you get either of the following errors, it usually means
that no table exists in the default database with the given
name:

Table 'tbl_name' doesn't exist
Can't find file: 'tbl_name' (errno: 2)

In some cases, it may be that the table does exist but that
you are referring to it incorrectly:

Because MySQL uses directories and files to store
databases and tables, database and table names are case
sensitive if they are located on a file system that has
case-sensitive file names.

Even for file systems that are not case-sensitive, such as
on Windows, all references to a given table within a query
must use the same lettercase.

Specify to the client the directory where the
character set definition files are located. For many
clients, you can do this with the
--character-sets-dir option.

Copy the character definition files to the path where
the client expects them to be.

B.6.2.18 File Not Found and Similar Errors

If you get ERROR
'file_name' not found (errno:
23), Can't open file:
file_name (errno: 24), or
any other error with errno 23 or
errno 24 from MySQL, it means that you have
not allocated enough file descriptors for the MySQL server.
You can use the perror utility to get a
description of what the error number means:

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 available to
mysqld.

To tell mysqld to keep open fewer files at
a time, you can make the table cache smaller by reducing the
value of the table_open_cache
system variable (the default value is 64). This may not
entirely prevent running out of file descriptors because in
some circumstances the server may attempt to extend the cache
size temporarily, as described in
Section 8.4.3.1, “How MySQL Opens and Closes Tables”. Reducing the value of
max_connections also reduces
the number of open files (the default value is 100).

--open-files-limit and
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 be
overridden only if you start mysqld_safe or
mysqld as root (just
remember that you also need to start the server with the
--user option in this case so
that it does not continue to run as root
after it starts up). If you need to increase the operating
system limit on the number of file descriptors available to
each process, consult the documentation for your system.

Note

If you run the tcsh shell,
ulimit does not work!
tcsh also reports incorrect values when
you ask for the current limits. In this case, you should
start mysqld_safe using
sh.

B.6.2.19 Table-Corruption Issues

If you have started mysqld with
--myisam-recover-options, MySQL
automatically checks and tries to repair
MyISAM tables if they are marked as 'not
closed properly' or 'crashed'. If this happens, MySQL writes
an entry in the hostname.err file
'Warning: Checking table ...' which is
followed by Warning: Repairing table if the
table needs to be repaired. If you get a lot of these errors,
without mysqld having died unexpectedly
just before, then something is wrong and needs to be
investigated further.

When the server detects MyISAM table
corruption, it writes additional information to the error log,
such as the name and line number of the source file, and the
list of threads accessing the table. Example: Got an
error from thread_id=1, mi_dynrec.c:368. This is
useful information to include in bug reports.

B.6.3.1 Problems with File Permissions

If you have problems with file permissions, the
UMASK or UMASK_DIR
environment 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 and
UMASK_DIR values are
0660 and 0700,
respectively. MySQL assumes that the value for
UMASK or UMASK_DIR is in
octal if it starts with a zero. For example, setting
UMASK=0600 is equivalent to
UMASK=384 because 0600 octal is 384
decimal.

By default, MySQL creates database directories with an access
permission value of 0700. To modify this
behavior, set the UMASK_DIR variable. If
you set its value, new directories are created with the
combined UMASK and
UMASK_DIR values. For example, to give
group access to all new directories, start
mysqld_safe as follows:

If you assigned a root password previously
but have forgotten it, you can assign a new password. The
following sections provide instructions for Windows and Unix
and Unix-like systems, as well as generic instructions that
apply to any system.

B.6.3.2.1 Resetting the Root Password: Windows Systems

On Windows, use the following procedure to reset the
password for the MySQL 'root'@'localhost'
account. To change the password for a
root account with a different host name
part, modify the instructions to use that host name.

Log on to your system as Administrator.

Stop the MySQL server if it is running. For a server
that is running as a Windows service, go to the Services
manager: From the Start menu, select
Control Panel, then
Administrative Tools, then
Services. 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.

Create a text file containing the following statement on
a single line. Replace the password with the password
that you want to use.

SET PASSWORD FOR 'root'@'localhost' = PASSWORD('MyNewPass');

Save the file. This example assumes that you name the
file C:\mysql-init.txt.

Open a console window to get to the command prompt: From
the Start menu, select
Run, then enter
cmd as the command to be run.

Start the MySQL server with the special
--init-file option
(notice that the backslash in the option value is
doubled):

The appropriate
--defaults-file setting
can be found using the Services Manager: From the
Start menu, select
Control Panel, then
Administrative Tools, then
Services. Find the MySQL
service in the list, right-click it, and choose the
Properties option. The Path
to executable field contains the
--defaults-file setting.

After the server has started successfully, delete
C:\mysql-init.txt.

You should now be able to connect to the MySQL server as
root using the new password. Stop the
MySQL server and restart it normally. If you run the server
as a service, start it from the Windows Services window. If
you start the server manually, use whatever command you
normally use.

B.6.3.2.2 Resetting the Root Password: Unix and Unix-Like Systems

On Unix, use the following procedure to reset the password
for the MySQL 'root'@'localhost' account.
To change the password for a root account
with a different host name part, modify the instructions to
use that host name.

The instructions assume that you will start the MySQL server
from the Unix login account that you normally use for
running it. For example, if you run the server using the
mysql login account, you should log in as
mysql before using the instructions.
Alternatively, you can log in as root,
but in this case you must start
mysqld with the
--user=mysql option. If you
start the server as root without using
--user=mysql, the server may
create root-owned files in the data
directory, such as log files, and these may cause
permission-related problems for future server startups. If
that happens, you will need to either change the ownership
of the files to mysql or remove them.

Log on to your system as the Unix user that the MySQL
server runs as (for example, mysql).

Stop the MySQL server if it is running. Locate the
.pid file that contains the
server's process ID. The exact location and name of this
file depend on your distribution, host name, and
configuration. Common locations are
/var/lib/mysql/,
/var/run/mysqld/, and
/usr/local/mysql/data/. Generally,
the file name has an extension of
.pid and begins with either
mysqld or your system's host name.

Stop the MySQL server by sending a normal
kill (not kill -9)
to the mysqld process. Use the actual
path name of the .pid file in the
following command:

shell> kill `cat /mysql-data-directory/host_name.pid`

Use backticks (not forward quotation marks) with the
cat command. These cause the output
of cat to be substituted into the
kill command.

Create a text file containing the following statement on
a single line. Replace the password with the password
that you want to use.

SET PASSWORD FOR 'root'@'localhost' = PASSWORD('MyNewPass');

Save the file. This example assumes that you name the
file /home/me/mysql-init. The file
contains the password, so do not save it where it can be
read by other users. If you are not logged in as
mysql (the user the server runs as),
make sure that the file has permissions that permit
mysql to read it.

The server executes the contents of the file named by
the --init-file option at
startup, changing the
'root'@'localhost' account password.

Other options may be necessary as well, depending on how
you normally start your server. For example,
--defaults-file may be
needed before
--init-file.

After the server has started successfully, delete
/home/me/mysql-init.

You should now be able to connect to the MySQL server as
root using the new password. Stop the
server and restart it normally.

B.6.3.2.3 Resetting the Root Password: Generic Instructions

The preceding sections provide password-resetting
instructions specifically for Windows and Unix and Unix-like
systems. Alternatively, on any platform, you can reset the
password using the mysql client (but this
approach is less secure):

Stop the MySQL server if necessary, then restart it with
the --skip-grant-tables
option. This enables anyone to connect without a
password and with all privileges, and disables
account-management statements such as
SET PASSWORD. Because
this is insecure, you might want to use
--skip-grant-tables in
conjunction with
--skip-networking to
prevent remote clients from connecting.

Connect to the MySQL server using the
mysql client; no password is
necessary because the server was started with
--skip-grant-tables:

shell> mysql

In the mysql client, tell the server
to reload the grant tables so that account-management
statements work:

mysql> FLUSH PRIVILEGES;

Then change the 'root'@'localhost'
account password. Replace the password with the password
that you want to use. To change the password for a
root account with a different host
name part, modify the instructions to use that host
name.

mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('MyNewPass');

You should now be able to connect to the MySQL server as
root using the new password. Stop the
server and restart it normally (without the
--skip-grant-tables and
--skip-networking options).

B.6.3.3 What to Do If MySQL Keeps Crashing

Each MySQL version is tested on many platforms before it is
released. This does not 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 always helps if you try to
find out exactly what crashes your system, because you 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 executing
mysqladmin version. If
mysqld has died and restarted, you may find
the reason by looking in the server's error log. See
Section 5.4.2, “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 resolve_stack_dump program. See
Section 24.5, “Debugging and Porting MySQL”. 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 updates 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 data files are written but not index files.) This means
that data file contents are safe even if
mysqld crashes, because the operating
system ensures 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
--flush option.

The preceding means that normally you should not get corrupted
tables unless one of the following happens:

The MySQL server or the server host was killed in the
middle of an update.

You have found a bug in mysqld that
caused it to die in the middle of an update.

Some external program is manipulating data files or index
files at the same time as mysqld
without locking the table properly.

You are running many mysqld servers
using the same data directory on a system that does not
support good file system locks (normally handled by the
lockd lock manager), or you are running
multiple servers with external locking disabled.

You have a crashed data file or index file that contains
very corrupt data that confused mysqld.

You have found a bug in the data storage code. This isn't
likely, but it is at least possible. In this case, you can
try to change the storage engine to another engine by
using ALTER TABLE on 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. Try the following things:

Make sure that you have applied the latest patches for
your operating system.

Use the
--skip-external-locking
option to mysqld. On some systems, the
lockd lock manager does not work
properly; the
--skip-external-locking
option tells mysqld not to use external
locking. (This means that you cannot run two
mysqld servers 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.)

If mysqld appears to be running but not
responding, try mysqladmin -u root
processlist. Sometimes mysqld
is not hung even though it seems unresponsive. The problem
may be that all connections are in use, or there may be
some internal lock problem. mysqladmin -u root
processlist usually is able to make a connection
even in these cases, and can provide useful information
about the current number of connections and their status.

Print the backtrace and the local variables at the
three lowest levels. In gdb, you
can do this with the following commands when
mysqld has crashed inside
gdb:

backtrace
info local
up
info local
up
info local

With gdb, you can also examine
which threads exist with info
threads and switch to a specific thread with
thread
N, where
N is the thread ID.

Try to simulate your application with a Perl script to
force MySQL to crash or misbehave.

Send a normal bug report. See
Section 1.6, “How to Report Bugs or Problems”. Be even more detailed than
usual. Because MySQL works for many people, the crash
might result from something that exists only on your
computer (for example, an error that is related to your
particular system libraries).

If you have a problem with tables containing
dynamic-length rows and you are using only
VARCHAR columns (not
BLOB or
TEXT columns), you can try
to change all VARCHAR to
CHAR with
ALTER TABLE. This forces
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 for several
years with very few problems, but dynamic-length rows are
by nature more prone to errors, so it may be a good idea
to try this strategy to see whether it helps.

Consider the possibility of hardware faults when
diagnosing problems. Defective hardware can be the cause
of data corruption. Pay particular attention to your
memory and disk subsystems when troubleshooting hardware.

B.6.3.4 How MySQL Handles a Full Disk

This section describes how MySQL responds to disk-full errors
(such as “no space left on device”), and to
quota-exceeded errors (such as “write failed” or
“user block limit reached”).

This section is relevant for writes to
MyISAM tables. It also applies for writes
to binary log files and binary log index file, except that
references to “row” and “record”
should be understood to mean “event.”

When a disk-full condition occurs, MySQL does the following:

It checks once every minute to see whether there is enough
space to write the current row. If there is enough space,
it continues as if nothing had happened.

Every 10 minutes it writes an entry to the log file,
warning about the disk-full condition.

To alleviate the problem, take the following actions:

To continue, you only have to free enough disk space to
insert all records.

Alternatively, to abort the thread, use
mysqladmin kill. The thread is aborted
the next time it checks the disk (in one minute).

Other threads might be waiting for the table that caused
the disk-full condition. If you have several
“locked” threads, killing the one thread that
is waiting on the disk-full condition enables the other
threads to continue.

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 or after an ALTER
TABLE statement. All of these statements may create
large temporary files that, if 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 removes
the big temporary files and mark the table as crashed. The
exception is that for ALTER
TABLE, the old table is left unchanged.

B.6.3.5 Where MySQL Stores Temporary Files

On Unix, MySQL uses the value of the TMPDIR
environment variable as the path name of the directory in
which to store temporary files. If TMPDIR
is not set, MySQL uses the system default, which is usually
/tmp, /var/tmp, or
/usr/tmp.

On Windows, MySQL checks in order the values of the
TMPDIR, TEMP, and
TMP environment variables. For the first
one found to be set, MySQL uses it and does not check those
remaining. If none of TMPDIR,
TEMP, or TMP are set,
MySQL uses the Windows system default, which is usually
C:\windows\temp\.

If the file system containing your temporary file directory is
too small, you can use the mysqld--tmpdir option to specify a
directory in a file system where you have enough space. On
replication slaves, you can use
--slave-load-tmpdir to specify
a separate directory for holding temporary files when
replicating LOAD DATA
statements.

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.

Note

To spread the load effectively, these paths should be
located on different physical disks,
not different partitions of the same disk.

If the MySQL server is acting as a replication slave, you
should be sure to set
--slave-load-tmpdir not to
point to a directory that is on a memory-based file system 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 operations.
If files in the slave temporary file directory are lost when
the server restarts, replication fails.

MySQL arranges that temporary files are removed if
mysqld is terminated. On platforms that
support it (such as Unix), this is done by unlinking the file
after opening it. The disadvantage of this is that the name
does not appear in directory listings and you do not see a big
temporary file that fills up the file system in which the
temporary file directory is located. (In such cases,
lsof +L1 may be helpful in identifying
large files associated with mysqld.)

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.

For some SELECT queries, MySQL
also creates temporary SQL tables. These are not hidden and
have names of the form SQL_*.

DDL operations that rebuild the table and are not performed
online using the ALGORITHM=INPLACE
technique create a temporary copy of the original table in the
same directory as the original table.

B.6.3.6 How to Protect or Change the MySQL Unix Socket File

The default location for the Unix socket file that the server
uses for communication with local clients is
/tmp/mysql.sock. (For some distribution
formats, the directory might be different, such as
/var/lib/mysql for RPMs.)

On some versions of Unix, anyone can delete files in the
/tmp directory or other similar
directories used for temporary files. If the socket file is
located in such a directory on your system, this might cause
problems.

On most versions of Unix, you can protect your
/tmp directory so that files can be
deleted only by their owners or the superuser
(root). 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 ls -ld /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:

Specify the path in a global or local option file. For
example, put the following lines in
/etc/my.cnf:

B.6.4.1 Case Sensitivity in String Searches

For nonbinary strings (CHAR,
VARCHAR,
TEXT), string searches use the
collation of the comparison operands. For binary strings
(BINARY,
VARBINARY,
BLOB), comparisons use the
numeric values of the bytes in the operands; this means that
for alphabetic characters, comparisons will be case-sensitive.

A comparison between a nonbinary string and binary string is
treated as a comparison of binary strings.

Simple comparison operations (>=, >, =, <,
<=, sorting, and grouping) are based on each
character's “sort value.” Characters with the
same sort value are treated as the same character. For
example, if e and
é have the same sort value in a
given collation, they compare as equal.

The default character set and collation are
latin1 and
latin1_swedish_ci, so nonbinary string
comparisons are case insensitive by default. This means that
if you search with
col_name LIKE
'a%', you get all column values that start with
A or a. To make this
search case-sensitive, make sure that one of the operands has
a case-sensitive or binary collation. For example, if you are
comparing a column and a string that both have the
latin1 character set, you can use the
COLLATE operator to cause either operand to
have the latin1_general_cs or
latin1_bin collation:

To cause a case-sensitive comparison of nonbinary strings to
be case insensitive, use COLLATE to name a
case-insensitive collation. The strings in the following
example normally are case-sensitive, but
COLLATE changes the comparison to be case
insensitive:

To determine whether a value will compare as a nonbinary or
binary string, use the
COLLATION() function. This
example shows that VERSION()
returns a string that has a case-insensitive collation, so
comparisons are case insensitive:

For binary strings, the collation value is
binary, so comparisons will be case
sensitive. One context in which you will see
binary is for compression functions, which
return binary strings as a general rule: string:

B.6.4.2 Problems Using DATE Columns

The format of a DATE value is
'YYYY-MM-DD'. According to standard SQL, no
other format is permitted. You should use this format in
UPDATE expressions and in the
WHERE clause of
SELECT statements. For example:

SELECT * FROM t1 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. MySQL also permits a “relaxed” string
format when updating and in a WHERE clause
that compares a date to a DATE,
DATETIME, or
TIMESTAMP column.
“Relaxed” format means that any punctuation
character may be used as the separator between parts. For
example, '2004-08-15' and
'2004#08#15' are equivalent. MySQL can also
convert a string containing no separators (such as
'20040815'), provided it makes sense as a
date.

When you compare a DATE,
TIME,
DATETIME, or
TIMESTAMP to a constant string
with the <, <=,
=, >=,
>, or BETWEEN
operators, MySQL normally converts the string to an internal
long integer for faster comparison (and also for a bit more
“relaxed” string checking). However, this
conversion is subject to the following exceptions:

When you use any comparison method other than those just
listed, such as IN or
STRCMP().

For those exceptions, the comparison is done by converting the
objects to strings and performing a string comparison.

To be on the safe side, assume that strings are compared as
strings and use the appropriate string functions if you want
to compare a temporal value to a string.

The special “zero” date
'0000-00-00' can be stored and retrieved as
'0000-00-00'. When a
'0000-00-00' date is used through
Connector/ODBC, it is automatically converted to
NULL because ODBC cannot handle that kind
of date.

Because MySQL performs the conversions just described, the
following statements work (assume that
idate is a
DATE column):

STRCMP() is a string function,
so it converts idate to a string in
'YYYY-MM-DD' format and performs a string
comparison. It does not convert '20030505'
to the date '2003-05-05' and perform a date
comparison.

If you enable the
ALLOW_INVALID_DATES SQL
mode, MySQL permits you to store dates that are given only
limited checking: MySQL requires only that the day is in the
range from 1 to 31 and the month is in the range from 1 to 12.
This makes MySQL very convenient for Web applications where
you obtain year, month, and day in three different fields and
you want to store exactly what the user inserted (without date
validation).

MySQL permits you to store dates where the day or month and
day are zero. This is convenient if you want to store a
birthdate in a DATE column and
you know only part of the date. To disallow zero month or day
parts in dates, enable the
NO_ZERO_IN_DATE SQL mode.

MySQL permits you to store a “zero” value of
'0000-00-00' as a “dummy
date.” This is in some cases more convenient than using
NULL values. If a date to be stored in a
DATE column cannot be converted
to any reasonable value, MySQL stores
'0000-00-00'. To disallow
'0000-00-00', enable the
NO_ZERO_DATE SQL mode.

To have MySQL check all dates and accept only legal dates
(unless overridden by IGNORE), set the
sql_mode system variable to
"NO_ZERO_IN_DATE,NO_ZERO_DATE".

B.6.4.3 Problems with NULL Values

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 empty string
''. This is not the case. For example, the
following statements are completely different:

Both statements insert a value into the
phone column, but the first inserts a
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.”

In SQL, the NULL value is never true in
comparison to any other value, even NULL.
An expression that contains NULL 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 NULL:

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

To search for column values that are NULL,
you cannot use an expr = NULL test. The
following statement returns no rows, because 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 show how to find the NULL phone
number and the empty phone number:

You can add an index on a column that can have
NULL values if you are using the
MyISAM, InnoDB, or
MEMORY storage engine. Otherwise, you must
declare an indexed column NOT NULL, and you
cannot insert NULL into the column.

When reading data with LOAD
DATA, empty or missing columns are updated with
''. To load a NULL value
into a column, use \N in the data file. The
literal word NULL may also be used under
some circumstances. See Section 13.2.6, “LOAD DATA Syntax”.

When using DISTINCT, GROUP
BY, or ORDER BY, all
NULL values are regarded as equal.

When using ORDER BY,
NULL values are presented first, or last if
you specify DESC to sort in descending
order.

Aggregate (summary) functions such as
COUNT(),
MIN(), and
SUM() ignore
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
age column:

mysql> SELECT COUNT(*), COUNT(age) FROM person;

For some data types, MySQL handles NULL
values specially. If you insert NULL into a
TIMESTAMP column, the current
date and time is inserted. If you insert
NULL into an integer or floating-point
column that has the AUTO_INCREMENT
attribute, the next number in the sequence is inserted.

B.6.4.4 Problems with Column Aliases

An alias can be used in a query select list to give a column a
different name. You can use the alias in GROUP
BY, ORDER BY, or
HAVING clauses to refer to the column:

SELECT SQRT(a*b) AS root FROM tbl_name
GROUP BY root HAVING root > 0;
SELECT id, COUNT(*) AS cnt FROM tbl_name
GROUP BY id HAVING cnt > 0;
SELECT id AS 'Customer identity' FROM tbl_name;

Standard SQL disallows references to column aliases in a
WHERE clause. This restriction is imposed
because when the WHERE clause is evaluated,
the column value may not yet have been determined. For
example, the following query is illegal:

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

The WHERE clause determines which rows
should be included in the GROUP BY clause,
but it refers to the alias of a column value that is not known
until after the rows have been selected, and grouped by the
GROUP BY.

In the select list of a query, a quoted column alias can be
specified using identifier or string quoting characters:

SELECT 1 AS `one`, 2 AS 'two';

Elsewhere in the statement, quoted references to the alias
must use identifier quoting or the reference is treated as a
string literal. For example, this statement groups by the
values in column id, referenced using the
alias `a`:

SELECT id AS 'a', COUNT(*) AS cnt FROM tbl_name
GROUP BY `a`;

But this statement groups by the literal string
'a' and will not work as expected:

SELECT id AS 'a', COUNT(*) AS cnt FROM tbl_name
GROUP BY 'a';

B.6.4.5 Rollback Failure for Nontransactional Tables

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 nontransactional tables are not affected by the
ROLLBACK
statement.

If you were not deliberately mixing transactional and
nontransactional 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 does not support a storage engine,
it instead creates the table as a MyISAM
table, which is nontransactional.

You can check the storage engine for a table by using either
of these statements:

B.6.4.6 Deleting Rows from Related Tables

If the total length of the
DELETE statement for
related_table is more than 1MB (the default
value of the
max_allowed_packet system
variable), you should split it into smaller parts and execute
multiple DELETE statements. You
probably get the fastest DELETE
by specifying only 100 to 1,000
related_column values per statement if the
related_column is indexed. If the
related_column isn't indexed, the speed is
independent of the number of arguments in the
IN clause.

B.6.4.7 Solving Problems with No Matching Rows

If you have a complicated query that uses many tables but that
returns no rows, you should use the following procedure to
find out what is wrong:

If you still cannot figure out what is wrong, create a
minimal test that can be run with mysql test <
query.sql that 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 more than needed to
demonstrate the problem), and add your
SELECT statement at the end
of the file.

Verify that the test file demonstrates the problem by
executing these commands:

B.6.4.8 Problems with Floating-Point Values

Floating-point numbers sometimes cause confusion because they
are approximate and not stored as exact values. A
floating-point value as written in an SQL statement may not be
the same as the value represented internally. Attempts to
treat floating-point values as exact in comparisons may lead
to problems. They are also subject to platform or
implementation dependencies. The
FLOAT and
DOUBLE data types are subject
to these issues. For DECIMAL
columns, MySQL performs operations with a precision of 65
decimal digits, which should solve most common inaccuracy
problems.

The following example uses
DOUBLE to demonstrate how
calculations that are done using floating-point operations are
subject to floating-point error.

The result is correct. Although the first five records look
like they should not satisfy the comparison (the values of
a and b do not appear to
be different), they may do so because the difference between
the numbers shows up around the tenth decimal or so, depending
on factors such as computer architecture or the compiler
version or optimization level. For example, different CPUs may
evaluate floating-point numbers differently.

If columns d1 and d2 had
been defined as DECIMAL rather
than DOUBLE, the result of the
SELECT query would have
contained only one row—the last one shown above.

The correct way to do floating-point number comparison is to
first decide on an acceptable tolerance for differences
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:

On some platforms, the SELECT statement
returns inf and -inf. On
others, it returns 0 and
-0.

An implication of the preceding issues is that if you attempt
to create a replication slave by dumping table contents with
mysqldump on the master and reloading the
dump file into the slave, tables containing floating-point
columns might differ between the two hosts.

B.6.5 Optimizer-Related Issues

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 does not have enough
information about the data at hand and has to make
“educated” guesses about the data.

For the cases when MySQL does not do the "right" thing, tools
that you have available to help MySQL are:

Use the EXPLAIN statement to
get information about how MySQL processes a query. To use
it, just add the keyword
EXPLAIN to the front of your
SELECT statement:

B.6.6 Table Definition-Related Issues

B.6.6.1 Problems with ALTER TABLE

If you get a duplicate-key error when using
ALTER TABLE to change the
character set or collation of a character column, the cause is
either that the new column collation 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. REPAIR TABLE works for
MyISAM, ARCHIVE, and
CSV tables.

If 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-xxx or
B-xxx lying
around:

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

In this case, go to the MySQL data directory and delete all
files that have names starting with A- or
B-. (You may want to move them elsewhere
instead of deleting them.)

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. 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,
ALTER TABLE unlocks the table
if you had done a
LOCK
TABLE on it. This is done because
InnoDB and these operating systems cannot
drop a table that is in use.

To rename TEMPORARY tables,
RENAME TABLE does not work. Use
ALTER TABLE instead:

ALTER TABLE old_name RENAME new_name;

You cannot refer to a TEMPORARY table
more than once in the same query. For example, the
following does not work:

SELECT * FROM temp_table JOIN temp_table AS t2;

The statement produces this error:

ERROR 1137: Can't reopen table: 'temp_table'

The Can't reopen table error also
occurs if you refer to a temporary table multiple times in
a stored function under different aliases, even if the
references occur in different statements within the
function. It may occur for temporary tables created
outside stored functions and referred to across multiple
calling and callee functions.

If a TEMPORARY is created with the same
name as an existing non-TEMPORARY
table, the non-TEMPORARY table is
hidden until the TEMPORARY table is
dropped, even if the tables use different storage engines.

Even if you use lower_case_table_names=2
(which enables MySQL to remember the case used for databases
and table names), MySQL does not remember the case used for
database names for the function
DATABASE() or within the
various logs (on case-insensitive systems).

Dropping a FOREIGN KEY constraint does
not work in replication because the constraint may have
another name on the slave.

With statement-based binary logging, the master writes the
executed queries to the binary log. This is a very fast,
compact, and efficient logging method that works perfectly
in most cases. However, it is possible for the data on the
master and slave to become different if a query is designed
in such a way that the data modification is nondeterministic
(generally not a recommended practice, even outside of
replication).

If and only if the preceding queries
have no ORDER BY clause guaranteeing a
deterministic order.

For example, for
INSERT ...
SELECT with no ORDER BY, the
SELECT may return rows in a
different order (which results in a row having different
ranks, hence getting a different number in the
AUTO_INCREMENT column), depending on the
choices made by the optimizers on the master and slave.

A query is optimized differently on the master and slave
only if:

The table is stored using a different storage engine on
the master than on the slave. (It is possible to use
different storage engines on the master and slave. For
example, you can use InnoDB on the
master, but MyISAM on the slave if
the slave has less available disk space.)

MySQL buffer sizes
(key_buffer_size, and
so on) are different on the master and slave.

The master and slave run different MySQL versions, and
the optimizer code differs between these versions.

This problem may also affect database restoration using
mysqlbinlog|mysql.

The easiest way to avoid this problem is to add an
ORDER BY clause to the aforementioned
nondeterministic queries to ensure that the rows are always
stored or modified in the same order. Using row-based or
mixed logging format also avoids the problem.

Log file names are based on the server host name if you do
not specify a file name with the startup option. To retain
the same log file names if you change your host name to
something else, you must explicitly use options such as
--log-bin=old_host_name-bin.
See Section 5.1.6, “Server Command Options”. Alternatively, rename
the old files to reflect your host name change. If these are
binary logs, you must edit the binary log index file and fix
the binary log file names there as well. (The same is true
for the relay logs on a slave server.)

The server uses only the first
max_sort_length bytes when
comparing data values. This means that values cannot
reliably be used in GROUP BY,
ORDER BY, or DISTINCT
if they differ only after the first
max_sort_length bytes. To
work around this, increase the variable value. The default
value of max_sort_length is
1024 and can be changed at server startup time or at
runtime.

Numeric calculations are done with
BIGINT or
DOUBLE (both are normally 64
bits long). Which precision you get depends on the function.
The general rule is that bit functions are performed with
BIGINT precision,
IF() and
ELT() with
BIGINT or
DOUBLE precision, and the
rest with DOUBLE precision.
You should try to avoid using unsigned long long values if
they resolve to be larger than 63 bits (9223372036854775807)
for anything other than bit fields.

In MIN(),
MAX(), and other aggregate
functions, MySQL currently compares
ENUM and
SET columns by their string
value rather than by the string's relative position in the
set.

In an UPDATE statement,
columns are updated from left to right. If you refer to an
updated column, you get the updated value instead of the
original value. For example, the following statement
increments KEY by 2,
not1:

mysql> UPDATE tbl_name SET KEY=KEY+1,KEY=KEY+1;

You can refer to multiple temporary tables in the same
query, but you cannot refer to any given temporary table
more than once. For example, the following does not work:

The optimizer may handle DISTINCT
differently when you are using “hidden” columns
in a join than when you are not. In a join, hidden columns
are counted as part of the result (even if they are not
shown), whereas in normal queries, hidden columns do not
participate in the DISTINCT comparison.

An example of this is:

SELECT DISTINCT mp3id FROM band_downloads
WHERE userid = 9 ORDER BY id DESC;

In the second case, you may get two identical rows in the
result set (because the values in the hidden
id column may differ).

This happens only for queries that do not have the
ORDER BY columns in the result.

If you execute a PROCEDURE on a query
that returns an empty set, in some cases the
PROCEDURE does not transform the columns.

Creation of a table of type MERGE does
not check whether the underlying tables are compatible
types.

If you use ALTER TABLE to add
a UNIQUE index to a table used in a
MERGE table and then add a normal index
on the MERGE table, the key order is
different for the tables if there was an old,
non-UNIQUE key in the table. This is
because ALTER TABLE puts
UNIQUE indexes before normal indexes to
be able to detect duplicate keys as early as possible.