\input texinfo  @c -*-texinfo-*-
@c Copyright 1997-2004 TcX AB, Detron HB and MySQL Finland AB

@c
@c This manual is NOT distributed under a GPL style license.
@c Use of the manual is subject to the following terms:
@c - Conversion to other formats is allowed, but the actual
@c   content may not be altered or edited in any way.
@c - You may create a printed copy for your own personal use.
@c - For all other uses, such as selling printed copies or
@c   using (parts of) the manual in another publication,
@c   prior written agreement from MySQL AB is required.
@c
@c Please email docs@mysql.com for more information or if
@c you are interested in doing a translation.
@c
@c *********************************************************
@c Note that @node names are used on our Web site.
@c So do not change node names without checking
@c Makefile.am and SitePages first.
@c *********************************************************
@c
@c %**start of header

@c there's a better way to do this... i just don't know it yet
@c sed will remove the "@c ifnusphere " to make this valid
@c ifnusphere @set nusphere 1

@setfilename mysql.info
@set language en

@c We want the types in the same index
@syncodeindex tp fn

@c Get version information. This file is generated by the Makefile!!
@include include.texi

@ifclear tex-debug
@c This removes the black squares in the right margin
@finalout
@end ifclear

@c Set background for HTML
@set _body_tags BGCOLOR=silver TEXT=#000000 LINK=#101090 VLINK=#7030B0
@c Set some style elements for the manual in HTML form. 'suggested'
@c natural language colors: aqua, black, blue, fuchsia, gray, green,
@c lime, maroon, navy, olive, purple, red, silver, teal, white, and
@c yellow. From Steeve Buehler <ahr@YogElements.com>
@set _extra_head <style> code {color:purple} tt {color:green} samp {color:navy} pre {color:maroon} </style>
@ifclear nusphere
@setchapternewpage on
@end ifclear

@settitle MySQL Reference Manual for version @value{mysqlversion}

@c We want single-sided heading format, with chapters on new pages. To
@c get double-sided format change 'on' below to 'odd'
@ifset nusphere
@setchapternewpage odd
@end ifset

@paragraphindent 0

@ifset nusphere
@smallbook
@end ifset

@c %**end of header

@ifinfo
@format
START-INFO-DIR-ENTRY
* mysql: (mysql).               MySQL documentation.
END-INFO-DIR-ENTRY
@end format
@end ifinfo

@titlepage
@sp 10
@center @titlefont{MySQL Reference Manual}
@sp 10
@center Copyright @copyright{} 1997-2004 MySQL AB
@c blank page after title page makes page 1 be a page front.
@c also makes the back of the title page blank.
@page
@end titlepage

@c Short contents, blank page, long contents.
@c until i can figure out the blank page, no short contents.
@c @shortcontents
@c @page
@c @page
@contents

@c This should be added. The HTML conversion also needs a MySQL version
@c number somewhere.

@iftex
@c change this to double if you want formatting for double-sided
@c printing
@headings single

@oddheading @thischapter @| @| @thispage
@evenheading @thispage @| @| MySQL Technical Reference for Version @value{mysqlversion}

@end iftex


@node Top, Introduction, (dir), (dir)

@c NOTE: Next para also appears in @node Manual-info

@ifinfo
This is the Reference Manual for the MySQL Database System.
It documents MySQL up to Version @value{mysqlversion}, but is also
applicable for older versions of the MySQL software (such as 3.23 or
4.0-production) because functional changes are indicated with reference to a
version number.
@end ifinfo

@menu
* Introduction::                General Information
* Installing::                  Installing MySQL
* Tutorial::                    MySQL Tutorial
* Using MySQL Programs::        Using MySQL Programs
* MySQL Database Administration::  Database Administration
* Replication::                 Replication in MySQL
* MySQL Optimization::          MySQL Optimization
* Client-Side Scripts::         MySQL Client and Utility Programs
* Language Structure::          Language Structure
* Charset::                     Character Set Support
* Column types::                Column Types
* Functions::                   Functions and Operators
* SQL Syntax::                  SQL Statement Syntax
* Storage engines::             MySQL Storage Engines and Table Types
* InnoDB::                      The @code{InnoDB} Storage Engine
* NDBCluster::                  MySQL Cluster
* MaxDB::                       Introduction to MaxDB
* Spatial extensions in MySQL::  Spatial Extensions in MySQL
* Stored Procedures::           Stored Procedures and Functions
* Triggers::                    Triggers
* MySQL APIs::                  MySQL APIs
* MySQL Connectors::            MySQL Connectors
* Error-handling::              Error Handling in MySQL
* Extending MySQL::             Extending MySQL
* Problems::                    Problems and Common Errors
* Credits::                     Credits
* TODO::                        MySQL and the Future (the TODO)
* News::                        MySQL Change History
* Porting::                     Porting to Other Systems
* Environment variables::       Environment Variables
* Regexp::                      MySQL Regular Expressions
* GPL license::                 GNU General Public License
* MySQL FLOSS License Exception::  MySQL FLOSS License Exception
* Function Index::              SQL Command, Type, and Function Index
* Concept Index::               Concept Index
@end menu


@node Introduction, Installing, Top, Top
@chapter General Information

@cindex overview
@cindex general information

@c TODO: change this to a Registered symbol

The MySQL (R) software delivers a very fast, multi-threaded,
multi-user, and robust SQL (Structured Query Language)
database server.
MySQL Server is intended for mission-critical, heavy-load
production systems as well as for embedding into mass-deployed software.
MySQL is a registered trademark of MySQL AB.

The MySQL software is Dual Licensed. Users can choose to
use the MySQL software as an Open Source
product under the terms of the GNU General Public License
(@uref{http://www.fsf.org/licenses/}) or can purchase a standard
commercial license from MySQL AB. See 
@uref{http://www.mysql.com/company/legal/licensing/} 
for more information on our licensing policies.

The following list describes some sections of particular interest in this manual:

@itemize @bullet
@item
For a discussion about the capabilities of the MySQL Database Server,
see @ref{Features}.

@item
For installation instructions, see @ref{Installing}.

@item
For tips on porting the MySQL Database Software to new architectures
or operating systems, see @ref{Porting}.

@item
For information about upgrading from a Version 4.0 release, see
@ref{Upgrading-from-4.0}.

@item
For information about upgrading from a Version 3.23 release, see
@ref{Upgrading-from-3.23}.

@item
For information about upgrading from a Version 3.22 release, see
@ref{Upgrading-from-3.22}.

@item
For a tutorial introduction to the MySQL Database Server,
see @ref{Tutorial}.

@item
For examples of SQL and benchmarking information, see the
benchmarking directory (@file{sql-bench} in the distribution).

@item
For a history of new features and bugfixes, see @ref{News}.

@item
For a list of currently known bugs and misfeatures, see @ref{Bugs}.

@item
For future plans, see @ref{TODO}.

@item
For a list of all the contributors to this project, see @ref{Credits}.
@end itemize

@strong{Important}:

Reports of errors (often called ``bugs''), as well as questions and comments,
should be sent to @uref{http://bugs.mysql.com}. @xref{Bug reports}.

If you have found a sensitive security bug in MySQL Server, please let
us know immediately by sending an email message to @email{security@@mysql.com}.

@cindex errors, reporting
@cindex reporting, errors
@cindex mailing list address
@cindex @command{mysqlbug} script, location


@menu
* Manual-info::                 About This Manual
* What-is::                     Overview of the MySQL Database Management System
* Roadmap::                     MySQL Development Roadmap
* MySQL Information Sources::   MySQL Information Sources
* Compatibility::               MySQL Standards Compliance
@end menu


@node Manual-info, What-is, Introduction, Introduction
@section About This Manual

@cindex online location of manual
@cindex manual, online location

@c NOTE: Next para also appears in @node Top

This is the Reference Manual for the MySQL Database System.
It documents MySQL up to Version @value{mysqlversion}, but is also
applicable for older versions of the MySQL software (such as 3.23 or
4.0-production) because functional changes are indicated with reference to a
version number.

Because this manual serves as a reference, it does not provide general
instruction on SQL or relational database concepts. It also will not teach
you how to use your operating system or command-line interpreter.

The MySQL Database Software is under constant development, and the
Reference Manual is updated frequently as well.  The most recent version of
the manual is available online in searchable form at
@uref{http://dev.mysql.com/doc/}.  Other formats also are available,
including HTML, PDF, and Windows CHM versions.

@cindex manual, available formats
@cindex Texinfo

The primary document is the Texinfo file.
The HTML version is produced automatically using a modified version of
@command{texi2html}.
The plain text and Info versions are produced with @command{makeinfo}.
The PostScript version is produced using @command{texi2dvi} and @command{dvips}.
The PDF version is produced with @command{pdftex}.

If you have any suggestions concerning additions or corrections to this
manual, please send them to the documentation team at @email{docs@@mysql.com}.

This manual was initially written by David Axmark and Michael ``Monty''
Widenius. It is now maintained by the MySQL Documentation Team,
consisting of Paul DuBois, Stefan Hinz, Mike Hillyer, and Jon Stephens.
For the many other contributors, see @ref{Credits}.

The copyright (2004) to this manual is owned by the Swedish company
MySQL AB.
MySQL and the MySQL logo are (registered) trademarks of MySQL AB.
Other trademarks and registered trademarks referred to in this manual
are the property of their respective owners, and are used for
identification purposes only.


@menu
* Manual conventions::          Conventions Used in This Manual
@end menu

@node Manual conventions,  , Manual-info, Manual-info
@subsection Conventions Used in This Manual

@c TODO: After conversion to DocBook, we'll be able to incorporate the
@c <userinput> tag. Uncomment the item below that
@c refers to the bold constant convention.  Change it
@c to <userinput>.

This manual uses certain typographical conventions:

@cindex manual, typographical conventions
@cindex typographical conventions
@cindex conventions, typographical

@table @asis
@item @code{constant}
Constant-width font is used for command names and options; SQL statements;
database, table, and column names; C and Perl code; and environment variables.
Example: ``To see how @command{mysqladmin} works, invoke it with the
@code{--help} option.''

@c @item @strong{@code{constant bold}}
@c Bold constant-width font is used to indicate input that you type in examples.

@item @var{constant italic}
Italic constant-width font is used to indicate variable input for which you
should substitute a value of your own choosing.

@item @file{filename}
Constant-width font with surrounding quotes is used for filenames and
pathnames.  Example: ``The distribution is installed under the
@file{/usr/local/} directory.''

@item @samp{c}
Constant-width font with surrounding quotes is also used to indicate
character sequences.  Example: ``To specify a wildcard, use the @samp{%}
character.''

@item @emph{italic}
Italic font is used for emphasis, @emph{like this}.

@item @strong{boldface}
Boldface font is used in table headings and to convey
@strong{especially strong emphasis}.
@end table

When commands are shown that are meant to be executed from within a particular
program, the program is indicated by a prompt shown before the command.  For
example, @code{shell>} indicates a command that you execute from your login
shell, and @code{mysql>} indicates a statement that you execute from the
@command{mysql} client program:

@example
shell> type a shell command here
mysql> type a mysql statement here
@end example

The ``shell'' is your command interpreter. On Unix, this is typically a
program such as @command{sh} or @command{csh}. On Windows, the equivalent program is
@command{command.com} or @command{cmd.exe}, typically run in a console window.

When you enter a command or statement shown in an example, do not type
the prompt shown in the example.

Database, table, and column names must often be substituted into statements.  To
indicate that such substitution is necessary, this manual uses
@var{db_name}, @var{tbl_name}, and @var{col_name}.  For example, you might
see a statement like this:

@example
mysql> SELECT @var{col_name} FROM @var{db_name}.@var{tbl_name};
@end example

This means that if you were to enter a similar statement, you would supply
your own database, table, and column names, perhaps like this:

@example
mysql> SELECT author_name FROM biblio_db.author_list;
@end example

SQL keywords are not case sensitive and may be written in uppercase or
lowercase.  This manual uses uppercase.

In syntax descriptions, square brackets (@samp{[} and @samp{]}) are used
to indicate optional words or clauses.  For example, in the following
statement, @code{IF EXISTS} is optional:

@example
DROP TABLE [IF EXISTS] @var{tbl_name}
@end example

When a syntax element consists of a number of alternatives, the alternatives
are separated by vertical bars (@samp{|}).  When one member from a set of
choices @emph{may} be chosen, the alternatives are listed within square
brackets (@samp{[} and @samp{]}):

@example
TRIM([[BOTH | LEADING | TRAILING] [@var{remstr}] FROM] @var{str})
@end example

When one member from a set of choices @emph{must} be chosen, the
alternatives are listed within braces (@samp{@{} and @samp{@}}):

@example
@{DESCRIBE | DESC@} @var{tbl_name} [@var{col_name} | @var{wild}]
@end example

An ellipsis (@code{...}) indicates the omission of a section of a statement,
typically to provide a shorter version of more complex syntax. For example,
@code{INSERT ... SELECT} is shorthand for the form of @code{INSERT} statement
that is followed by a @code{SELECT} statement.

An ellipsis can also indicate that the preceding syntax element of a statement
may be repeated. In the following example, multiple @var{reset_option} values
may be given, with each of those after the first preceded by commas:

@example
RESET @var{reset_option} [,@var{reset_option}] ...
@end example

Commands for setting shell variables are shown using Bourne shell syntax.
For example, the sequence to set an environment variable and run a command
looks like this in Bourne shell syntax:

@example
shell> @var{VARNAME}=@var{value} @var{some_command}
@end example

@cindex shell syntax
@cindex command syntax

If you are using @command{csh} or @command{tcsh}, you must issue commands somewhat
differently.  You would execute the sequence just shown like this:

@example
shell> setenv @var{VARNAME} @var{value}
shell> @var{some_command}
@end example


@node What-is, Roadmap, Manual-info, Introduction
@section Overview of the MySQL Database Management System

@cindex MySQL, defined
@cindex MySQL, introduction

MySQL, the most popular Open Source SQL database management
system, is
developed, distributed, and supported by MySQL AB.  MySQL AB is a
commercial company, founded by the MySQL developers.
It is a second generation Open Source company that unites Open
Source values and methodology with a successful business model.

The MySQL Web site (@uref{http://www.mysql.com/})
provides the latest information about MySQL software and
MySQL AB.

@table @asis

@item MySQL is a database management system.

A database is a structured collection of data.  It may be anything from a
simple shopping list to a picture gallery or the vast amounts of
information in a corporate network.  To add, access, and process data
stored in a computer database, you need a database management system
such as MySQL Server.  Since computers are very good at handling large
amounts of data, database management systems play a central role in computing,
as standalone utilities or as parts of other applications.

@item MySQL is a relational database management system.

@cindex databases, defined
A relational database stores data in separate tables rather than putting
all the data in one big storeroom.  This adds speed and flexibility.
The SQL part of ``MySQL'' stands for ``Structured
Query Language.'' SQL is the most common standardized language used to
access databases and is defined by the ANSI/ISO SQL Standard. The SQL 
standard has been evolving since 1986 and several versions exist. In this 
manual, ``SQL-92'' refers to the standard released in 1992,
``SQL:1999'' refers to the standard released in 1999, and
``SQL:2003'' refers to the current version of the standard.
We use the phrase ``the SQL standard'' to 
mean the current version of the SQL Standard at any time.


@item MySQL software is Open Source.

@cindex relational databases, defined
@cindex SQL, defined
@cindex Open Source, defined
@cindex General Public License
Open Source means that it is possible for anyone to use and modify the software.
Anybody can download the MySQL software from the Internet and use it
without paying anything.  If you wish, you may study the source code
and change it to suit your needs.  The MySQL software uses the
GPL (GNU General Public License),
@uref{http://www.fsf.org/licenses/}, to define what you
may and may not do with the software in different situations.
If you feel uncomfortable with the GPL or need to embed
MySQL code into a commercial application, you can buy a
commercially licensed version from us.
See the MySQL Licensing Overview for more information 
(@uref{http://www.mysql.com/company/legal/licensing/}).


@item The MySQL Database Server is very fast, reliable, and easy to use.

If that is what you are looking for, you should give it a try.
MySQL Server also has a practical set of features developed in
close cooperation with our users.  You can find a performance comparison
of MySQL Server with other database managers on our benchmark page.
@xref{MySQL Benchmarks}.

MySQL Server was originally developed to handle large databases
much faster than existing solutions and has been successfully used in
highly demanding production environments for several years.  Although
under constant development, MySQL Server today offers a rich and
useful set of functions.  Its connectivity, speed, and security make
MySQL Server highly suited for accessing databases on the Internet.

@item MySQL Server works in client/server or embedded systems.

The MySQL Database Software is a client/server system that consists
of a multi-threaded SQL server that supports different backends,
several different client programs and libraries, administrative tools,
and a wide range of application programming interfaces (APIs).

We also provide MySQL Server as an embedded multi-threaded library
that you can link into your application to get a smaller, faster,
easier-to-manage product.

@item A large amount of contributed MySQL software is available.

It is very likely that you will find that your favorite application or
language already supports the MySQL Database Server.

@end table

@cindex pronunciation, MySQL
@cindex MySQL, pronunciation
@cindex goals of MySQL
The official way to pronounce ``MySQL'' is ``My Ess Que Ell'' (not
``my sequel''), but we don't mind if you pronounce it as ``my sequel''
or in some other localized way.


@menu
* History::                     History of MySQL
* Features::                    The Main Features of MySQL
* Stability::                   MySQL Stability
* Table size::                  How Big MySQL Tables Can Be
* Year 2000 compliance::        Year 2000 Compliance
@end menu

@node History, Features, What-is, What-is
@subsection History of MySQL

@cindex MySQL history
@cindex history of MySQL
@cindex MySQL name
@cindex My, derivation
@cindex MySQL Dolphin name
@cindex Sakila

We started out with the intention of using @code{mSQL} to connect to our
tables using our own fast low-level (ISAM) routines. However, after some
testing, we came to the conclusion that @code{mSQL} was not fast enough or
flexible enough for our needs.  This resulted in a new SQL interface to our
database but with almost the same API interface as @code{mSQL}.  This API was
designed to allow third-party code that was written for use with @code{mSQL} to
be ported easily for use with MySQL.

The derivation of the name MySQL is not clear.  Our base
directory and a large number of our libraries and tools have had the prefix
``my'' for well over 10 years.  However, co-founder Monty Widenius's daughter
is also named My.  Which of the two gave its name to
MySQL is still a mystery, even for us.

The name of the MySQL Dolphin (our logo) is ``Sakila,'' which was chosen
by the founders of MySQL AB from a huge list of names suggested by users
in our ``Name the Dolphin'' contest. The winning name was submitted by
Ambrose Twebaze, an Open Source software developer from Swaziland, Africa.
According to Ambrose, the name Sakila has its roots in SiSwati, the local
language of Swaziland. Sakila is also the name of a town in Arusha,
Tanzania, near Ambrose's country of origin, Uganda.


@node Features, Stability, History, What-is
@subsection The Main Features of MySQL

@cindex main features of MySQL
@cindex features of MySQL

The following list describes some of the important characteristics of the
MySQL Database Software. See also @ref{Roadmap} for more information
about current and upcoming features.

@c This list is too technical and should be divided into one feature
@c list comparable to commercial competition and a very technical on
@c with max limits (from crash-me) and so on.
@table @asis
@item Internals and Portability
@itemize @bullet
@item
Written in C and C++.
@item
Tested with a broad range of different compilers.
@item
Works on many different platforms.  @xref{Which OS}.
@item
Uses GNU Automake, Autoconf, and Libtool for portability.
@item
APIs for C, C++, Eiffel, Java, Perl, PHP, Python, Ruby, and Tcl are available.
@xref{MySQL APIs}.
@item
Fully multi-threaded using kernel threads.  It can easily
use multiple CPUs if they are available.
@item
Provides transactional and non-transactional storage engines.
@item
Uses very fast B-tree disk tables (@code{MyISAM}) with index compression.
@item
Relatively easy to add another storage engine. This is useful if you
want to add an SQL interface to an in-house database.
@item
A very fast thread-based memory allocation system.
@item
Very fast joins using an optimized one-sweep multi-join.
@item
In-memory hash tables, which are used as temporary tables.
@item
SQL functions are implemented using a highly optimized class library and
should be as fast as possible.  Usually there is no memory allocation
at all after query initialization.
@item
The MySQL code is tested with Purify
(a commercial memory leakage detector) as well as with Valgrind,
a GPL tool (@uref{http://developer.kde.org/~sewardj/}).
@item
The server is available as a separate program for use in a client/server
networked environment.  It is also available as a library that can be
embedded (linked) into standalone applications. Such applications can be
used in isolation or in environments where no network is available.
@end itemize

@item Column Types
@itemize @bullet
@item
Many column types: signed/unsigned integers 1, 2, 3, 4, and 8 bytes
long, @code{FLOAT}, @code{DOUBLE}, @code{CHAR}, @code{VARCHAR},
@code{TEXT}, @code{BLOB}, @code{DATE}, @code{TIME}, @code{DATETIME},
@code{TIMESTAMP}, @code{YEAR}, @code{SET}, @code{ENUM}, and OpenGIS spatial
types.
@xref{Column types}.
@item
Fixed-length and variable-length records.
@end itemize

@item Statements and Functions
@itemize @bullet
@item
Full operator and function support in the @code{SELECT} and @code{WHERE}
clauses of queries.  For example:

@example
mysql> SELECT CONCAT(first_name, ' ', last_name)
    -> FROM citizen
    -> WHERE income/dependents > 10000 AND age > 30;
@end example

@item
Full support for SQL @code{GROUP BY} and
@code{ORDER BY} clauses.  Support
for group functions (@code{COUNT()},
@code{COUNT(DISTINCT ...)},
@code{AVG()}, @code{STD()},
@code{SUM()}, @code{MAX()}, @code{MIN()}, and @code{GROUP_CONCAT()}).
@item
Support for @code{LEFT OUTER JOIN} and @code{RIGHT OUTER JOIN} with both standard
SQL and ODBC syntax.
@item
Support for aliases on tables and columns as required by standard SQL.
@item
@code{DELETE}, @code{INSERT}, @code{REPLACE}, and @code{UPDATE} return
the number of rows that were changed (affected).  It is possible to return
the number of rows matched instead by setting a flag when connecting to the
server.
@item
The MySQL-specific @code{SHOW} command can be used to retrieve
information about databases, tables, and indexes.  The @code{EXPLAIN} command
can be used to determine how the optimizer resolves a query.
@item
Function names do not clash with table or column names.  For example,
@code{ABS} is a valid column name.  The only restriction is that for a
function call, no spaces are allowed between the function name and the
@samp{(} that follows it.  @xref{Reserved words}.
@item
You can mix tables from different databases in the same query (as of
MySQL 3.22).
@end itemize

@item Security
@itemize @bullet
@item
A privilege and password system that is very flexible and secure, and
that allows host-based verification.  Passwords are secure because all
password traffic is encrypted when you connect to a server.
@end itemize

@item Scalability and Limits
@itemize @bullet
@item
Handles large databases.  We use MySQL Server with databases that 
contain 50 million records. We also know of users who
use MySQL Server with 60,000 tables and about 5,000,000,000 rows.
@item
Up to 64 indexes per table are allowed (32 before MySQL 4.1.2).  Each index may
consist of 1 to 16 columns or parts of columns.  The maximum index width is
1000 bytes (500 before MySQL 4.1.2).
An index may use a prefix of a column for @code{CHAR}, @code{VARCHAR},
@code{BLOB}, or @code{TEXT} column types.
@end itemize

@item Connectivity
@itemize @bullet
@item
Clients can connect to the MySQL server using TCP/IP sockets
on any platform.  On Windows systems in the NT family (NT, 2000, XP, or 2003), 
clients can connect using named pipes. On Unix systems,
clients can connect using Unix domain socket files.
@item
In MySQL versions 4.1 and higher, Windows servers also support shared-memory
connections if started with the @code{--shared-memory} option.  Clients can
connect through shared memory by using the @code{--protocol=memory} option.
@item
The Connector/ODBC (MyODBC) interface provides MySQL support for client
programs that use ODBC (Open Database Connectivity) connections.  For
example, you can use MS Access to connect to your MySQL server.  Clients can
be run on Windows or Unix.  MyODBC source is available.  All ODBC
2.5 functions are supported, as are many others.
@xref{ODBC Connector}.
@item
The Connector/J interface provides MySQL support for Java client
programs that use JDBC connections.  Clients can be run on Windows or Unix.
Connector/J source is available.
@xref{Java Connector}.
@end itemize

@item Localization
@itemize @bullet
@item
The server can provide error messages to clients in many languages.
@xref{Languages}.
@item
Full support for several different character sets, including
@code{latin1} (ISO-8859-1), @code{german}, @code{big5}, @code{ujis},
and more.  For example,
the Scandinavian characters @samp{@^a}, @samp{@"a} and @samp{@"o} are
allowed in table and column names.
Unicode support is available as of MySQL 4.1.
@item
All data is saved in the chosen character set.  All comparisons for normal
string columns are case-insensitive.
@item
Sorting is done according to the chosen character set (using Swedish
collation by default).  It is possible to change this when the MySQL
server is started.  To see an example of very advanced sorting, look
at the Czech sorting code.  MySQL Server supports many different
character sets that can be specified at compile time and runtime.
@end itemize

@item Clients and Tools
@itemize @bullet
@item
The MySQL server has built-in support for SQL statements to check,
optimize, and repair tables.  These statements are available from the
command line through the @command{mysqlcheck} client. MySQL also includes
@command{myisamchk}, a very fast command-line utility for performing these
operations on @code{MyISAM} tables.
@xref{MySQL Database Administration}.
@item
All MySQL programs can be invoked with the @code{--help} or @code{-?}
options to obtain online assistance.
@end itemize

@end table


@node Stability, Table size, Features, What-is
@subsection MySQL Stability

@cindex stability

This section addresses the questions, ``@emph{How stable is MySQL Server?}''
and, ``@emph{Can I depend on MySQL Server in this project?}''
We will try to clarify these issues and answer some important
questions that concern many potential users. The information in this
section is based on data gathered from the mailing lists, which are
very active in identifying problems as well as reporting types of use.

The original code stems back to the early 1980s. It provides a stable code
base, and the @code{ISAM} table format used by the original storage engine
remains backward-compatible.
At TcX, the predecessor of MySQL AB, MySQL code has worked
in projects since mid-1996, without any problems.
When the MySQL Database Software initially was released to a wider public,
our new users quickly found some pieces of untested code. Each new release
since then has had fewer portability problems, even though each new release
has also had many new features.

Each release of the MySQL Server has been usable. Problems have occurred
only when users try code from the ``gray zones.''  Naturally, new users
don't know what the gray zones are; this section therefore attempts to
document those areas that are currently known.
The descriptions mostly deal with Version 3.23, 4.0 and 4.1 of MySQL Server.
All known and reported bugs are fixed in the latest version, with the
exception of those listed in the bugs section, which
are design-related.  @xref{Bugs}.

The MySQL Server design is multi-layered with independent modules.
Some of the newer modules are listed here with an indication of how
well-tested each of them is:

@cindex modules, list of

@table @asis
@item Replication (Stable)
Large groups of servers using replication are in production use, with
good results. Work on enhanced replication features is continuing
in MySQL 5.x.

@item @code{InnoDB} tables (Stable)
The @code{InnoDB} transactional storage engine has been declared
stable in the MySQL 3.23 tree, starting from version 3.23.49.
@code{InnoDB} is being used in large, heavy-load production systems.

@item @code{BDB} tables (Stable)
The @code{Berkeley DB} code is very stable, but we are still improving
the @code{BDB} transactional storage engine interface in MySQL Server.

@item Full-text searches (Stable)
Full-text searching is widely used.
Important feature enhancements were added in MySQL 4.0 and 4.1.

@item @code{MyODBC} 3.51 (Stable)
@code{MyODBC} 3.51 uses ODBC SDK 3.51 and is in wide production use.
Some issues brought up appear to be application-related and independent of
the ODBC driver or underlying database server.

@end table


@node Table size, Year 2000 compliance, Stability, What-is
@subsection How Big MySQL Tables Can Be

@c TODO: move to MyISAM storage engine section, replace with
@c more general "limits" section.

@cindex tables, maximum size
@cindex size of tables
@cindex operating systems, file-size limits
@cindex limits, file-size
@cindex files, size limits

MySQL 3.22 had a 4GB (4 gigabyte) limit on table size. With the
@code{MyISAM} storage engine in MySQL 3.23, the maximum table
size was increased to 8 million terabytes (2 ^ 63 bytes). With this larger
allowed table size, the maximum effective table size for MySQL
databases now usually is determined by operating system constraints
on file sizes, not by MySQL internal limits.

The @code{InnoDB} storage engine maintains @code{InnoDB} tables within a
tablespace that can be created from several files. This allows a
table to exceed the maximum individual file size. The tablespace can include
raw disk partitions, which allows extremely large tables. The maximum
tablespace size is 64TB.

The following table lists some examples of operating system file-size
limits. This is only a rough guide and is not intended to be definitive. 
For the most up-to-date information, be sure to check the documentation 
specific to your operating system.

@multitable @columnfractions .30 .50
@item @strong{Operating System} @tab @strong{File-size Limit}
@item Linux 2.2-Intel 32-bit    @tab 2GB (LFS: 4GB)
@item Linux 2.4                 @tab (using ext3 filesystem) 4TB
@item Solaris 9/10              @tab 16TB
@item NetWare w/NSS filesystem  @tab 8TB
@item win32 w/ FAT/FAT32        @tab 2GB/4GB
@item win32 w/ NTFS             @tab 2TB (possibly larger)
@item MacOS X w/ HFS+           @tab 2TB
@end multitable

On Linux 2.2, you can get @code{MyISAM} tables larger than 2GB in size by
using the Large File Support (LFS) patch for the ext2 filesystem. On Linux
2.4, patches also exist for ReiserFS to get support for big files (up to 2TB). Most
current Linux distributions are based on kernel 2.4 and already include all
the required LFS patches. With JFS and XFS, petabyte and larger files 
are possible on Linux. However, the maximum available file size still depends 
on several factors, one of them being the filesystem used to store MySQL tables.

For a detailed overview about LFS in Linux, have a look at Andreas
Jaeger's @cite{Large File Support in Linux} page at
@uref{http://www.suse.de/~aj/linux_lfs.html}.

Windows users please note: FAT and VFAT (FAT32) are @strong{not} considered suitable
for production use with MySQL. Use NTFS instead.

By default, MySQL creates @code{MyISAM} tables with an internal
structure that allows a maximum size of about 4GB.  You can
check the maximum table size for a table with the @code{SHOW TABLE STATUS}
statement or with @command{myisamchk -dv @var{tbl_name}}.
@xref{SHOW,  , @code{SHOW}}.

If you need a @code{MyISAM} table that will be larger than 4GB in size (and your
operating system supports large files), the @code{CREATE TABLE} statement
allows @code{AVG_ROW_LENGTH} and @code{MAX_ROWS} options.
@xref{CREATE TABLE,  , @code{CREATE TABLE}}.
You can also change these options with @code{ALTER TABLE} after the table has
been created, to increase the table's maximum allowable size.
@xref{ALTER TABLE,  , @code{ALTER TABLE}}.

Other ways to work around file-size limits for @code{MyISAM} tables are as
follows:

@itemize @bullet
@item
If your large table is read-only, you can use @command{myisampack} to
compress it.  @command{myisampack} usually compresses a table by at
least 50%, so you can have, in effect, much bigger tables.
@command{myisampack} also can merge multiple tables into a single table.
@xref{myisampack, , @command{myisampack}}.

@item
Another way to get around the operating system file limit for @code{MyISAM}
data files is by using the @code{RAID} options.
@xref{CREATE TABLE,  , @code{CREATE TABLE}}.

@item
MySQL includes a @code{MERGE} library that allows
you to handle a collection of @code{MyISAM} tables that have identical
structure as a single @code{MERGE} table.
@xref{MERGE storage engine, , @code{MERGE} storage engine}.

@end itemize


@node Year 2000 compliance,  , Table size, What-is
@subsection Year 2000 Compliance

@cindex Year 2000 compliance
@cindex compliance, Y2K
@cindex date functions, Y2K compliance

The MySQL Server itself has no problems with Year 2000 (Y2K)
compliance:

@itemize @bullet
@item
MySQL Server uses Unix time functions that handle dates into the year
@code{2037} for @code{TIMESTAMP} values. For @code{DATE} and @code{DATETIME}
values, dates through the year @code{9999} are accepted.

@item
All MySQL date functions are implemented in one source file,
@file{sql/time.cc}, and are coded very carefully to be year 2000-safe.

@item
In MySQL 3.22 and later, the @code{YEAR} column type
can store years @code{0} and @code{1901} to @code{2155} in one byte and
display them using two or four digits.
All two-digit years are considered to be in the range
@code{1970} to @code{2069}, which means that if you store @code{01} in a
@code{YEAR} column, MySQL Server treats it as @code{2001}.
@end itemize

The following simple demonstration illustrates that MySQL Server
has no problems with @code{DATE} or @code{DATETIME} values through the year
9999, and no problems with @code{TIMESTAMP} values until after the year 2030:

@example
mysql> DROP TABLE IF EXISTS y2k;
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE y2k (date DATE,
    ->                   date_time DATETIME,
    ->                   time_stamp TIMESTAMP);
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO y2k VALUES
    -> ('1998-12-31','1998-12-31 23:59:59',19981231235959),
    -> ('1999-01-01','1999-01-01 00:00:00',19990101000000),
    -> ('1999-09-09','1999-09-09 23:59:59',19990909235959),
    -> ('2000-01-01','2000-01-01 00:00:00',20000101000000),
    -> ('2000-02-28','2000-02-28 00:00:00',20000228000000),
    -> ('2000-02-29','2000-02-29 00:00:00',20000229000000),
    -> ('2000-03-01','2000-03-01 00:00:00',20000301000000),
    -> ('2000-12-31','2000-12-31 23:59:59',20001231235959),
    -> ('2001-01-01','2001-01-01 00:00:00',20010101000000),
    -> ('2004-12-31','2004-12-31 23:59:59',20041231235959),
    -> ('2005-01-01','2005-01-01 00:00:00',20050101000000),
    -> ('2030-01-01','2030-01-01 00:00:00',20300101000000),
    -> ('2040-01-01','2040-01-01 00:00:00',20400101000000),
    -> ('9999-12-31','9999-12-31 23:59:59',99991231235959);
Query OK, 14 rows affected (0.01 sec)
Records: 14  Duplicates: 0  Warnings: 2

mysql> SELECT * FROM y2k;
+------------+---------------------+----------------+
| date       | date_time           | time_stamp     |
+------------+---------------------+----------------+
| 1998-12-31 | 1998-12-31 23:59:59 | 19981231235959 |
| 1999-01-01 | 1999-01-01 00:00:00 | 19990101000000 |
| 1999-09-09 | 1999-09-09 23:59:59 | 19990909235959 |
| 2000-01-01 | 2000-01-01 00:00:00 | 20000101000000 |
| 2000-02-28 | 2000-02-28 00:00:00 | 20000228000000 |
| 2000-02-29 | 2000-02-29 00:00:00 | 20000229000000 |
| 2000-03-01 | 2000-03-01 00:00:00 | 20000301000000 |
| 2000-12-31 | 2000-12-31 23:59:59 | 20001231235959 |
| 2001-01-01 | 2001-01-01 00:00:00 | 20010101000000 |
| 2004-12-31 | 2004-12-31 23:59:59 | 20041231235959 |
| 2005-01-01 | 2005-01-01 00:00:00 | 20050101000000 |
| 2030-01-01 | 2030-01-01 00:00:00 | 20300101000000 |
| 2040-01-01 | 2040-01-01 00:00:00 | 00000000000000 |
| 9999-12-31 | 9999-12-31 23:59:59 | 00000000000000 |
+------------+---------------------+----------------+
14 rows in set (0.00 sec)
@end example

The final two @code{TIMESTAMP} column values are zero because the
year values (@code{2040}, @code{9999}) exceed the @code{TIMESTAMP} maximum.  The
@code{TIMESTAMP} data type, which is used to store the current time,
supports values that range from @code{19700101000000} to
@code{20300101000000} on 32-bit machines (signed value).  On 64-bit
machines, @code{TIMESTAMP} handles values up to @code{2106} (unsigned
value).

Although MySQL Server itself is Y2K-safe, you may run into
problems if you use it with applications that are not Y2K-safe.
For example, many old applications store or manipulate years using
two-digit values (which are ambiguous) rather than four-digit values.
This problem may be compounded by applications that use
values such as @code{00} or @code{99} as ``missing'' value indicators.
Unfortunately, these problems may be difficult to fix because different
applications may be written by different programmers, each of whom may
use a different set of conventions and date-handling functions.

Thus, even though MySQL Server has no Y2K problems, it is
the application's responsibility to provide unambiguous input.
See @ref{Y2K issues} for MySQL Server's rules for dealing
with ambiguous date input data that contains two-digit year values.

@node Roadmap, MySQL Information Sources, What-is, Introduction
@section MySQL Development Roadmap

This section provides a snapshot of the MySQL development roadmap, including
major features implemented or planned for MySQL 4.0, 4.1, 5.0, and 5.1.
The following sections provide information for each release series.

The current production release series is MySQL 4.1, which was declared
stable for production use as of Version 4.1.7, released in October 2004.  The
previous production release series is MySQL 4.0, which was declared stable
for production use as of Version 4.0.12, released in March 2003. Production
status means that future 4.1 and 4.0 development is limited only to bugfixes.
For the older MySQL 3.23 series, only critical bugfixes are made.

Active MySQL development currently is taking place in the MySQL 5.0
release series, this means that new features are being added there.
MySQL 5.0 is available in alpha status.

Before upgrading from one release series to the next, please see the notes
at @ref{Upgrade}.

Plans for some of the most requested features are summarized in the following
table.

@multitable @columnfractions .30 .60
@item @strong{Feature}                     @tab @strong{MySQL Series}
@item Unions                               @tab 4.0
@item Subqueries                           @tab 4.1
@item R-trees                              @tab 4.1 (for @code{MyISAM} tables)
@item Stored procedures                    @tab 5.0
@item Views                                @tab 5.0
@item Cursors                              @tab 5.0
@item Foreign keys                         @tab 5.1 (already implemented in 3.23 for @code{InnoDB})
@item Triggers                             @tab 5.0 and 5.1
@item Full outer join                      @tab 5.1
@item Constraints                          @tab 5.1
@end multitable

@menu
* MySQL 4.0 Nutshell::          MySQL 4.0 in a Nutshell
* MySQL 4.1 Nutshell::          MySQL 4.1 in a Nutshell
* MySQL 5.0 Nutshell::          MySQL 5.0: The Next Development Release
@end menu


@node MySQL 4.0 Nutshell, MySQL 4.1 Nutshell, Roadmap, Roadmap
@subsection MySQL 4.0 in a Nutshell

MySQL Server 4.0 is available in production status.

MySQL 4.0 is available for download at @uref{http://dev.mysql.com/}
and from our mirrors. MySQL 4.0 has been tested by a large number of users
and is in production use at many large sites.

The major new features of MySQL Server 4.0 are geared toward our existing
business and community users, enhancing the MySQL database software
as the solution for mission-critical, heavy-load database systems.
Other new features target the users of embedded databases.


@menu
* Nutshell 4.0 features::       Features Available in MySQL 4.0
* Nutshell Embedded MySQL::     The Embedded MySQL Server
@end menu


@node Nutshell 4.0 features, Nutshell Embedded MySQL, MySQL 4.0 Nutshell, MySQL 4.0 Nutshell
@subsubsection Features Available in MySQL 4.0

@table @asis
@item Speed enhancements
@itemize @bullet
@item
MySQL 4.0 has a query cache that can give a huge speed boost to
applications with repetitive queries. @xref{Query Cache}.

@item
Version 4.0 further increases the speed of MySQL Server
in a number of areas, such as bulk @code{INSERT} statements, searching on
packed indexes, full-text searching (using @code{FULLTEXT} indexes), and
@code{COUNT(DISTINCT)}.
@end itemize

@item Embedded MySQL Server introduced
@itemize @bullet
@item
The new Embedded Server library can easily be used to create standalone and
embedded applications.  The embedded server provides an alternative to using
MySQL in a client/server environment.
@xref{Nutshell Embedded MySQL}.
@end itemize

@item @code{InnoDB} storage engine as standard
@itemize @bullet
@item
The @code{InnoDB} storage engine is offered as a standard feature of the
MySQL server. This means full support for ACID transactions, foreign
keys with cascading @code{UPDATE} and @code{DELETE}, and row-level locking
are now standard features.
@xref{InnoDB,  , @code{InnoDB}}.
@end itemize

@item New functionality
@itemize @bullet
@item
The enhanced @code{FULLTEXT} search properties of MySQL Server 4.0 enables
@code{FULLTEXT} indexing of large text masses with both binary
and natural-language searching logic. You can customize minimal word
length and define your own stop word lists in any human language,
enabling a new set of applications to be built with MySQL Server.
@xref{Fulltext Search}.
@end itemize

@item Standards compliance, portability, and migration
@itemize @bullet
@item
Many users will also be happy to learn that MySQL Server now supports the
@code{UNION} statement, a long-awaited standard SQL feature.

@item
MySQL runs natively on the Novell NetWare platform beginning with NetWare
6.0.
@xref{NetWare installation}.

@item
Features to simplify migration from other database systems to MySQL
Server include @code{TRUNCATE TABLE} (as in Oracle).
@c commented out IDENTITY until someone explains what it means
@c and @code{IDENTITY}
@c as a synonym for automatically incremented keys (as in Sybase).
@end itemize

@item Internationalization
@itemize @bullet
@item
Our German, Austrian, and Swiss users will note that MySQL 4.0 now
supports a new character set, @code{latin1_de}, which ensures that the 
@emph{German sorting order} sorts words with umlauts in the same order 
as do German telephone books.
@end itemize

@item Usability enhancements
In the process of implementing features for new users, we have not forgotten
requests from our loyal community of existing users.

@itemize @bullet
@item
Most @command{mysqld} parameters (startup options) can be set without taking
down the server. This is a convenient feature for database administrators
(DBAs).
@xref{SET OPTION,  , @code{SET OPTION}}.

@item
Multiple-table @code{DELETE} and @code{UPDATE} statements have been added.

@item
On Windows, symbolic link handling at the database level is enabled by default.
On Unix, the @code{MyISAM} storage engine supports symbolic
linking at the table level (and not just the database level as before).

@item
@code{SQL_CALC_FOUND_ROWS} and @code{FOUND_ROWS()} are new functions that make it
possible to find out the number of rows a @code{SELECT} query that includes a
@code{LIMIT} clause would have returned without that clause.
@end itemize

@end table

The news section of this manual includes a more in-depth list of features.
@xref{News-4.0.x}.


@node Nutshell Embedded MySQL,  , Nutshell 4.0 features, MySQL 4.0 Nutshell
@subsubsection The Embedded MySQL Server

The @code{libmysqld} embedded server library makes MySQL Server suitable for
a vastly expanded realm of applications. By using this library, developers can
embed MySQL Server into various applications and electronics devices, where
the end user has no knowledge of there actually being an underlying
database. Embedded MySQL Server is ideal for use behind
the scenes in Internet appliances, public kiosks, turnkey
hardware/software combination units, high performance Internet
servers, self-contained databases distributed on CD-ROM, and so on.

Many users of @code{libmysqld} will benefit from the MySQL
Dual Licensing. For those not wishing to be bound by the GPL,
the software is also made available under a commercial license.
See @uref{http://www.mysql.com/company/legal/licensing/} for more information
on the licensing policy of MySQL AB.
The embedded MySQL library uses the same interface as the normal
client library, so it is convenient and easy to use.
@xref{libmysqld,  , @code{libmysqld}}.

On Windows there are two different libraries:

@multitable @columnfractions .30 .60
@item @code{libmysqld.lib} @tab Dynamic library for threaded applications.
@item @code{mysqldemb.lib} @tab Static library for not threaded applications.
@end multitable


@node MySQL 4.1 Nutshell, MySQL 5.0 Nutshell, MySQL 4.0 Nutshell, Roadmap
@subsection MySQL 4.1 in a Nutshell

MySQL Server 4.0 laid the foundation for new features implemented in MySQL
4.1, such as subqueries and Unicode support, and for the work on stored
procedures being done in version 5.0.  These features come at the top of the
wish list of many of our customers.  Already well-known for its stability,
speed, and ease of use, MySQL Server is now able to fulfill the requirement
checklists of very demanding buyers.

MySQL Server 4.1 is currently in production status, and binaries are available
for download at @uref{http://dev.mysql.com/downloads/mysql/4.1.html}.  All
binary releases pass our extensive test suite without any errors on the
platforms on which we test.
@xref{News-4.1.x}.

For those wishing to use the most recent development source for MySQL 4.1,
we also make our BitKeeper repositories publicly available.
@xref{Installing source tree}.


@menu
* Nutshell 4.1 features::       Features Available in MySQL 4.1
@end menu

@node Nutshell 4.1 features,  , MySQL 4.1 Nutshell, MySQL 4.1 Nutshell
@subsubsection Features Available in MySQL 4.1

This section lists features implemented in MySQL 4.1.  New features that
will be available in MySQL 5.0 are described in @ref{TODO MySQL 5.0}.

@table @asis
@item Support for subqueries and derived tables
@itemize @bullet
@item
A ``subquery'' is a @code{SELECT} statement nested within another statement.
A ``derived table'' (an unnamed view) is a subquery in the @code{FROM} clause
of another statement.
@xref{Subqueries}.
@end itemize

@item Speed enhancements
@itemize @bullet
@item
Faster binary client/server protocol with support for prepared statements
and parameter binding.
@xref{C API Prepared statements}.
@item
@code{BTREE} indexing is supported for @code{HEAP} tables,
significantly improving response time for non-exact searches.
@end itemize

@item New functionality
@itemize @bullet
@item
@code{CREATE TABLE @var{tbl_name2} LIKE @var{tbl_name1}} allows you to create, with
a single statement, a new table with a structure exactly like that of an
existing table.
@item
The @code{MyISAM} storage engine supports
OpenGIS spatial types for storing geographical data.
@xref{Spatial extensions in MySQL}.
@item
Replication can be done over SSL connections.
@end itemize

@item Standards compliance, portability, and migration
@itemize @bullet
@item
The new client/server protocol adds the ability to pass multiple warnings to
the client, rather than only a single result. This makes it much easier to
track problems that occur in operations such as bulk data loading.
@item
@code{SHOW WARNINGS} shows warnings for the last command.
@xref{SHOW WARNINGS,  , @code{SHOW WARNINGS}}.
@end itemize

@item Internationalization and Localization
@itemize @bullet
@item
To support applications that require the use of local languages,
the MySQL software offers extensive
Unicode support through the @code{utf8} and @code{ucs2} character sets.
@item
Character sets can be defined per column, table, and database.
This allows for a high degree of flexibility in application design,
particularly for multi-language Web sites.
@item
For documentation for this improved character set support,
see @ref{Charset}.
@item
Per-connection time zones are supported, allowing individual clients to select
their own time zone when necessary.
@end itemize

@item Usability enhancements
@itemize @bullet
@item
In response to popular demand, we have added a server-based
@code{HELP} command that can be used
to get help information for SQL statements.
The advantage of having this information on the server side is that the
information is always applicable to the particular server version that you
actually are using.
Because this information is available by issuing an SQL statement, any client
can be written to access it.
For example, the @code{help} command of the @command{mysql} command-line client
has been modified to have this capability.
@item
In the new client/server protocol, multiple statements can be issued with
a single call.
@xref{C API multiple queries}.
@item
The new client/server protocol also supports returning multiple result sets.
This might occur as a result of sending multiple statements, for example.
@item
A new @code{INSERT ... ON DUPLICATE KEY UPDATE ...} syntax has been
implemented. This allows you to @code{UPDATE} an existing row if the
@code{INSERT} would have caused a duplicate in a @code{PRIMARY} or
@code{UNIQUE} index.
@xref{INSERT,  , @code{INSERT}}.
@item
A new aggregate function, @code{GROUP_CONCAT()}
adds the extremely useful capability of concatenating column values from
grouped rows into a single result string.
@xref{Group by functions and modifiers}.
@end itemize

@end table

The news section of this manual includes a more in-depth list of features.
@xref{News-4.1.x}.


@node MySQL 5.0 Nutshell,  , MySQL 4.1 Nutshell, Roadmap
@subsection MySQL 5.0: The Next Development Release

New development for MySQL is focused on the 5.0 release, featuring
stored procedures, views (including updatable views), rudimentary triggers,
and other new features.
@xref{TODO MySQL 5.0}.

For those wishing to take a look at the bleeding edge of MySQL
development, we make our BitKeeper repository for
MySQL version 5.0 publicly available.
@xref{Installing source tree}.
As of December 2003, binary builds of version 5.0 have also been available.

@node MySQL Information Sources, Compatibility, Roadmap, Introduction
@section MySQL Information Sources

@menu
* Questions::                   MySQL Mailing Lists
* IRC::                         MySQL Community Support on IRC (Internet Relay Chat)
* Forums ::                     MySQL Community Support at the MySQL Forums
@end menu

@node Questions, IRC, MySQL Information Sources, MySQL Information Sources
@subsection MySQL Mailing Lists

@cindex reporting, errors
@cindex errors, reporting
@cindex MySQL mailing lists

@menu
* Mailing-list::                The MySQL Mailing Lists
* Asking questions::            Asking Questions or Reporting Bugs
* Bug reports::                 How to Report Bugs or Problems
* Answering questions::         Guidelines for Answering Questions on the Mailing List
@end menu

This section introduces the MySQL mailing lists and provides
guidelines as to how the lists should be used. When you subscribe to a mailing
list, you will receive all postings to the list as email messages. You can 
also send your own questions and answers to the list.


@node Mailing-list, Asking questions, Questions, Questions
@subsubsection The MySQL Mailing Lists

@cindex mailing lists
@cindex email lists

To subscribe to or unsubscribe from any of the mailing lists described in this
section, visit @uref{http://lists.mysql.com/}. For most of them, you can select
the regular version of the list where you get individual messages, or a digest
version where you get one large message per day.

Please @emph{do not} send messages about
subscribing or unsubscribing to any of the mailing lists, because such
messages are distributed automatically to thousands of other users.

Your local site may have many subscribers to a MySQL mailing list.
If so, the site may have a local mailing list, so that messages sent from
@code{lists.mysql.com} to your site are propagated to the local list.  In such
cases, please contact your system administrator to be added to or dropped
from the local MySQL list.

If you wish to have traffic for a mailing list go to a separate mailbox in
your mail program, set up a filter based on the message headers.  You can
use either the @code{List-ID:} or @code{Delivered-To:} headers to identify
list messages.

The MySQL mailing lists are as follows:

@table @code
@item announce
This list is for announcements of new versions of MySQL and related
programs.  This is a low-volume list to which all MySQL users should
subscribe.

@item mysql
This is the main list for general MySQL discussion.  Please note that some
topics are better discussed on the more-specialized lists.  If you post to the
wrong list, you may not get an answer.

@item bugs
This list will be of interest to you if you want to stay informed about
issues reported since the last release of MySQL or if you want to be
actively involved in the process of bug hunting and fixing.
@xref{Bug reports}.

@item internals
This list is for people who work on the MySQL code.  This is also the
forum for discussions on MySQL development and for posting patches.

@item mysqldoc
This list is for people who work on the MySQL documentation:
people from MySQL AB, translators, and other community members.

@item benchmarks
This list is for anyone interested in performance issues. Discussions
concentrate on database performance (not limited to MySQL), but also
include broader categories such as performance of the kernel,
filesystem, disk system, and so on.

@item packagers
This list is for discussions on packaging and distributing MySQL. This is the 
forum used by distribution maintainers to exchange ideas on packaging MySQL 
and on ensuring that MySQL looks and feels as similar as possible on all 
supported platforms and operating systems.

@item java
This list is for discussions about the MySQL server and Java. It is mostly 
used to discuss JDBC drivers, including MySQL Connector/J.

@item win32
This list is for all topics concerning the MySQL software on Microsoft 
operating systems, such as Windows 9x, Me, NT, 2000, XP, and 2003.

@item myodbc
This list is for all topics concerning connecting to the MySQL server with ODBC.

@item gui-tools
This list is for all topics concerning MySQL GUI tools, including @code{MySQL
Administrator} and the @code{MySQL Control Center} graphical client.

@item cluster
This list is for discussion of MySQL Cluster.

@item dotnet
This list is for discussion of the MySQL server and the .NET platform.
Mostly related to the MySQL Connector/Net provider.

@item plusplus
This list is for all topics concerning programming with the C++ API for MySQL.

@item perl
This list is for all topics concerning the Perl support for MySQL with
@code{DBD::mysql}.

@end table

If you're unable to get an answer to your questions from a MySQL mailing
list, one option is to purchase support from MySQL AB. This will put you
in direct contact with MySQL developers. 

The following table shows some MySQL mailing lists in languages other than
English.  These lists are not operated by MySQL AB.

@table @code

@item @email{mysql-france-subscribe@@yahoogroups.com}
A French mailing list.

@item @email{list@@tinc.net}
A Korean mailing list.
Email @code{subscribe mysql your@@email.address} to this list.

@item @email{mysql-de-request@@lists.4t2.com}
A German mailing list.
Email @code{subscribe mysql-de your@@email.address} to this list.
You can find information about this mailing list at
@uref{http://www.4t2.com/mysql/}.

@item @email{mysql-br-request@@listas.linkway.com.br}
A Portuguese mailing list.
Email @code{subscribe mysql-br your@@email.address} to this list.

@item @email{mysql-alta@@elistas.net}
A Spanish mailing list.
Email @code{subscribe mysql your@@email.address} to this list.

@end table


@node Asking questions, Bug reports, Mailing-list, Questions
@subsubsection Asking Questions or Reporting Bugs

@cindex net etiquette
@cindex mailing lists, archive location
@cindex searching, MySQL Web pages

Before posting a bug report or question, please do the following:

@itemize @bullet
@item
Start by searching the MySQL online manual at
@uref{http://dev.mysql.com/doc/}.
We try to keep the manual up to date by updating it frequently with
solutions to newly found problems. The change history
(@uref{http://dev.mysql.com/doc/mysql/en/News.html}) can be particularly
useful since it is quite possible that a newer version already
contains a solution to your problem.

@item
Search in the bugs database at @uref{http://bugs.mysql.com/} to see 
whether the bug has already been reported and fixed.

@item
Search the MySQL mailing list archives at
@uref{http://lists.mysql.com/}.
@item
You can also use @uref{http://www.mysql.com/search/} to search all the
Web pages (including the manual) that are located at the MySQL AB Web site.
@end itemize

If you can't find an answer in the manual or the archives, check with your
local MySQL expert.  If you still can't find an answer to your
question, please follow the guidelines on sending mail to a MySQL mailing list, 
outlined in the next section, before contacting us.



@node Bug reports, Answering questions, Asking questions, Questions
@subsubsection How to Report Bugs or Problems

@cindex bugs, reporting
@cindex reporting, bugs
@cindex problems, reporting
@cindex errors, reporting
@cindex @command{mysqlbug} script
@cindex creating, bug reports
@cindex scripts, @command{mysqlbug}
@cindex bugs.mysql.com
@cindex bugs database

The normal place to report bugs is @uref{http://bugs.mysql.com/}, which is the
address for our bugs database.
This database is public, and can be browsed and searched by anyone.
If you log in to the system, you will also be able to enter new reports.

Writing a good bug report takes patience, but doing it right the first
time saves time both for us and for yourself.  A good bug report, containing
a full test case for the bug, makes it very likely that we will fix the bug in
the next release.  This section will help you write your report correctly
so that you don't waste your time doing things that may not help us much
or at all.

We encourage everyone to use the @command{mysqlbug} script to generate a bug
report (or a report about any problem).  @command{mysqlbug} can be
found in the @file{scripts} directory (source distribution) and in the 
@file{bin} directory under your MySQL installation directory (binary distribution). 
If you are unable to use @command{mysqlbug} (for example, if you are running 
on Windows), it is still vital that you include all the necessary information 
noted in this section (most importantly, a description of the operating system 
and the MySQL version).

The @command{mysqlbug} script helps you generate a report by determining much
of the following information automatically, but if something important is
missing, please include it with your message.  Please read this section
carefully and make sure that all the information described here is included
in your report.

Preferably, you should test the problem using the latest production or
development version of MySQL Server before posting.  Anyone should be
able to repeat the bug by just using @code{mysql test < script_file} on the
included test case or by running the shell or Perl script that is included in the
bug report.

All bugs posted in the bugs database at @uref{http://bugs.mysql.com/}
will be corrected or documented in the
next MySQL release. If only minor code changes are needed to correct a
problem, we may also post a patch that fixes the problem.

If you have found a sensitive security bug in MySQL, you can send
email to @email{security@@mysql.com}.

If you have a repeatable bug report, please report it to the bugs
database at @uref{http://bugs.mysql.com/}.  Note that even in this case
it's good to run the @command{mysqlbug} script first to find information
about your system.  Any bug that we are able to repeat has a high chance
of being fixed in the next MySQL release.

To report other problems, you can use one of the MySQL mailing lists.

Remember that it is possible for us to respond to a message containing too much
information, but not to one containing too little.  People often omit facts
because they think they know the cause of a problem and assume that some
details don't matter.  A good principle is this: If you are in doubt about stating
something, state it.  It is faster and less troublesome to
write a couple more lines in your report than to wait longer for the answer
if we must ask you to provide information that was missing from the initial
report.

The most common errors made in bug reports are (a) not including the version number of
the MySQL distribution used, and (b) not fully describing the platform on which the MySQL server
is installed (including the platform type and version number).  This is highly
relevant information, and in 99 cases out of 100, the bug report is useless without it.  
Very often we get questions like,
``Why doesn't this work for me?'' Then we find that the feature
requested wasn't implemented in that MySQL version, or that a bug
described in a report has already been fixed in newer MySQL
versions.  Sometimes the error is platform-dependent; in such cases, it is
next to impossible for us to fix anything without knowing the operating system and
the version number of the platform.

If you compiled MySQL from source,
remember also to provide information about your compiler, if it is related to
the problem.  Often people find bugs in compilers and think the problem is
MySQL-related.  Most compilers are under development all the time and
become better version by version.  To determine whether your
problem depends on your compiler, we need to know what compiler you use.
Note that every compiling problem should be regarded as a bug and
reported accordingly.

It is most helpful when a good description of the problem is included in the
bug report.  That is, give a good example of everything you did that led to
the problem and describe, in exact detail, the problem itself.  The best reports are
those that include a full example showing how to reproduce the bug or
problem.  @xref{Reproduceable test case}.

If a program produces an error message, it is very important to include the
message in your report.  If we try to search for something from the archives
using programs, it is better that the error message reported exactly matches
the one that the program produces.  (Even the lettercase should be observed.)
You should never try to reproduce from memory what the error message was;
instead, copy and paste the entire message into your report.

If you have a problem with Connector/ODBC (MyODBC), please try to generate a
trace file and send it with your report.  @xref{MyODBC bug report}.

Please remember that many of the people who will read your report will
do so using an 80-column display.  When generating reports or examples
using the @command{mysql} command-line tool, you should therefore use
the @code{--vertical} option (or the @code{\G} statement terminator)
for output that would exceed the available width for such a display
(for example, with the @code{EXPLAIN SELECT} statement; see the
example later in this section).

@cindex bug reports, criteria for
Please include the following information in your report:

@itemize @bullet
@item
The version number of the MySQL distribution you are using (for
example, MySQL 4.0.12). You can find out which version you
are running by executing @command{mysqladmin version}.  The @command{mysqladmin}
program can be found in the @file{bin} directory under your MySQL
installation directory.

@item
The manufacturer and model of the machine on which you experience the 
problem.

@item
The operating system name and version.  If you work with Windows, you
can usually get the name and version number by double-clicking your
My Computer icon and pulling down the ``Help/About Windows'' menu.
For most Unix-like operating systems, you can get this information by
executing the command @code{uname -a}.

@item
Sometimes the amount of memory (real and virtual) is relevant. If in doubt,
include these values.

@item
If you are using a source distribution of the MySQL software, the name and
version number of the compiler used are needed.  If you have a binary
distribution, the distribution name is needed.

@item
If the problem occurs during compilation, include the exact error
messages and also a few lines of context around the offending code in the
file where the error occurs.

@item
If @command{mysqld} died, you should also report the query that crashed
@command{mysqld}.  You can usually find this out by running @command{mysqld} with
query logging enabled, and then looking in the log after @command{mysqld} crashes
@xref{Using log files}.

@item
If a database table is related to the problem, include the output from
@command{mysqldump --no-data @var{db_name} @var{tbl_name}}.  This is very easy
to do and is a powerful way to get information about any table in a database.
The information will help us create a situation matching the one you have.

@item
For speed-related bugs or problems with @code{SELECT} statements, you
should always include the output of @code{EXPLAIN SELECT ...}, and at
least the number of rows that the @code{SELECT} statement produces.  You
should also include the output from @code{SHOW CREATE TABLE @var{tbl_name}}
for each involved table. The more information you give about your
situation, the more likely it is that someone can help you.

The following is an example of a very good bug report. It should be posted
with the @command{mysqlbug} script.  The example uses the @command{mysql}
command-line tool. Note the use of the @code{\G} statement terminator for
statements whose output width would otherwise exceed that of an 80-column
display device.

@example
mysql> SHOW VARIABLES;
mysql> SHOW COLUMNS FROM ...\G
       <output from SHOW COLUMNS>
mysql> EXPLAIN SELECT ...\G
       <output from EXPLAIN>
mysql> FLUSH STATUS;
mysql> SELECT ...;
       <A short version of the output from SELECT,
       including the time taken to run the query>
mysql> SHOW STATUS;
       <output from SHOW STATUS>
@end example

@item
If a bug or problem occurs while running @command{mysqld}, try to provide an
input script that will reproduce the anomaly.  This script should include any
necessary source files.  The more closely the script can reproduce your
situation, the better.  If you can make a reproducible test case, you should
post it on @uref{http://bugs.mysql.com/} for high-priority treatment.

If you can't provide a script, you should at least include the output
from @command{mysqladmin variables extended-status processlist} in your mail to
provide some information on how your system is performing.

@item
If you can't produce a test case with only a few rows, or if the test table
is too big to be mailed to the mailing list (more than 10 rows), you should
dump your tables using @command{mysqldump} and create a @file{README} file
that describes your problem.

Create a compressed archive of your files using
@command{tar} and @command{gzip} or @command{zip}, and use FTP to transfer the
archive to @uref{ftp://ftp.mysql.com/pub/mysql/upload/}.  Then enter
the problem into our bugs database at @uref{http://bugs.mysql.com/}.

@item
If you think that the MySQL server produces a strange result from a query,
include not only the result, but also your opinion of what the result
should be, and an account describing the basis for your opinion.

@item
When giving an example of the problem, it's better to use the variable names,
table names, and so on that exist in your actual situation than to come up with
new names.  The problem could be related to the name of a variable or table.
These cases are rare, perhaps, but it is better to be safe than sorry.
After all, it should be easier for you to provide an example that uses your
actual situation, and it is by all means better for us.  In case you have data
that you don't want to show to others, you can use FTP to transfer it to
@uref{ftp://ftp.mysql.com/pub/mysql/upload/}.  If the information is
really top secret and you don't want to show it even to us, then go ahead
and provide an example using other names, but please regard this as the last
choice.

@item
Include all the options given to the relevant programs, if possible.  For
example, indicate the options that you use when you start the @command{mysqld}
server as well as the options that you use to run any MySQL client programs.
The options to programs such as @command{mysqld} and @command{mysql}, and to the
@command{configure} script, are often keys to answers and are very relevant.
It is never a bad idea to include them.  If you use any modules, such
as Perl or PHP, please include the version numbers of those as well.

@item
If your question is related to the privilege system, please include the
output of @command{mysqlaccess}, the output of @command{mysqladmin reload}, and all
the error messages you get when trying to connect.  When you test your
privileges, you should first run @command{mysqlaccess}.  After this, execute
@command{mysqladmin reload version} and try to connect with the program that
gives you trouble.  @command{mysqlaccess} can be found in the @file{bin}
directory under your MySQL installation directory.

@item
If you have a patch for a bug, do include it.  But don't assume that the patch is
all we need, or that we will use it, if you don't provide some necessary
information such as test cases showing the bug that your patch fixes.  We
might find problems with your patch or we might not understand it at all; if
so, we can't use it.

If we can't verify exactly what the purpose of the patch is, we won't use it.
Test cases will help us here.  Show that the patch will handle all the
situations that may occur.  If we find a borderline case (even a rare one)
where the patch won't work, it may be useless.

@item
Guesses about what the bug is, why it occurs, or what it depends on
are usually wrong.  Even the MySQL team can't guess such things
without first using a debugger to determine the real cause of a bug.

@item
Indicate in your bug report that you have checked the reference manual
and mail archive so that others know you have tried to solve the
problem yourself.

@item
If you get a @code{parse error}, please check your syntax closely.  If
you can't find something wrong with it, it's extremely likely that your
current version of MySQL Server doesn't support the syntax you are
using.  If you are using the current version and the manual at
@uref{http://dev.mysql.com/doc/} doesn't cover the
syntax you are using, MySQL Server doesn't support your query.  In this
case, your only options are to implement the syntax yourself or email
@email{licensing@@mysql.com} and ask for an offer to implement it.

If the manual covers the syntax you are using, but you have an older version
of MySQL Server, you should check the MySQL change history to see
when the syntax was implemented.  In this case, you have the option of
upgrading to a newer version of MySQL Server.  @xref{News}.

@item
If your problem is that your data appears corrupt or you get errors
when you access a particular table, you should first check and then try
to repair your tables with @code{CHECK TABLE} and @code{REPAIR TABLE}
or with @command{myisamchk}.
@xref{MySQL Database Administration}.

If you are running Windows, please verify that @code{lower_case_table_names}
is 1 or 2 with @code{SHOW VARIABLES LIKE 'lower_case_table_names'}.

@item
If you often get corrupted tables, you should try to find out when and why this
happens.  In this case, the error log in the MySQL data directory
may contain some information about what happened. (This is the file with the
@file{.err} suffix in the name.)  @xref{Error log}.  Please
include any relevant information from this file in your bug report.  Normally
@command{mysqld} should @emph{never} crash a table if nothing killed it in the
middle of an update.  If you can find the cause of @command{mysqld} dying,
it's much easier for us to provide you with a fix for the problem.
@xref{What is crashing}.

@item
If possible, download and install the most recent version of MySQL Server
and check whether it solves your problem.  All versions of
the MySQL software are thoroughly tested and should work without problems.
We believe in making everything as backward-compatible as possible,
and you should be able to switch MySQL versions without difficulty.
@xref{Which version}.
@end itemize

@cindex technical support, mailing address
@cindex support, mailing address
@cindex customer support, mailing address
@cindex mailing address, for customer support
If you are a support customer, please cross-post the bug report to
@email{mysql-support@@mysql.com} for higher-priority treatment, as well as to
the appropriate mailing list to see whether someone else has experienced (and
perhaps solved) the problem.

For information on reporting bugs in MyODBC, see @ref{MyODBC bug
report}.

For solutions to some common problems, see @ref{Problems}.

When answers are sent to you individually and not to the mailing list,
it is considered good etiquette to summarize the answers and send the
summary to the mailing list so that others may have the benefit of
responses you received that helped you solve your problem.


@node Answering questions,  , Bug reports, Questions
@subsubsection Guidelines for Answering Questions on the Mailing List

@cindex net etiquette
@cindex questions, answering
@cindex answering questions, etiquette
@cindex mailing lists, guidelines

If you consider your answer to have broad interest, you may want to post it
to the mailing list instead of replying directly to the individual who
asked.  Try to make your answer general enough that people other than the
original poster may benefit from it.  When you post to the list, please make
sure that your answer is not a duplication of a previous answer.

Try to summarize the essential part of the question in your reply; don't feel
obliged to quote the entire original message.

Please don't post mail messages from your browser with HTML mode turned on.
Many users don't read mail with a browser.

@node IRC, Forums , Questions, MySQL Information Sources
@subsection MySQL Community Support on IRC (Internet Relay Chat)

@cindex IRC
@cindex Internet Relay Chat

In addition to the various MySQL mailing lists, you can find experienced
community people on @code{IRC} (@code{Internet Relay Chat}).
These are the best networks/channels currently known to us:

@itemize @bullet
@item @strong{freenode} (see @uref{http://www.freenode.net/} for servers)
@itemize @bullet
@item @code{#mysql}
Primarily MySQL questions, but other database and general SQL questions are welcome.
Questions about PHP, Perl or C in combination with MySQL are also common.
@end itemize
@item @strong{EFnet} (see @uref{http://www.efnet.org/} for servers)
@itemize @bullet
@item @code{#mysql}
MySQL questions.
@end itemize
@end itemize

If you are looking for IRC client software to connect to an IRC network,
take a look at @code{X-Chat} (@uref{http://www.xchat.org/}).
X-Chat (GPL licensed) is available for Unix as well as for Windows platforms.

@node Forums ,  , IRC, MySQL Information Sources
@subsection MySQL Community Support at the MySQL Forums

@cindex Forums

The latest community support resource are the forums at @uref{http://forums.mysql.com}.

There are a variety of forums available, grouped in the following general categories:

@itemize @bullet
@item Migration
@item MySQL Usage
@item MySQL Connectors
@item MySQL Technology
@item Business
@end itemize

@node Compatibility,  , MySQL Information Sources, Introduction
@section MySQL Standards Compliance

@cindex compatibility, with standard SQL
@cindex standards compatibility
@cindex extensions, to standard SQL
@cindex SQL-92, extensions to
@cindex standard SQL, extensions to

This section describes how MySQL relates to the ANSI/ISO SQL standards.
MySQL Server has many extensions to the SQL standard, and here you
will find out what they are and how to use them.  You will also find
information about functionality missing from MySQL Server, and how to work
around some differences.

The SQL standard has been evolving since 1986 and several versions exist. In
this manual, ``SQL-92'' refers to the standard released in 1992,
``SQL:1999'' refers to the standard released in 1999, and ``SQL:2003''
refers to the current version of the standard.  We use the phrase ``the SQL
standard'' to mean the current version of the SQL Standard at any time.

Our goal is to not restrict MySQL Server usability for any usage without a
very good reason for doing so.  Even if we don't have the resources to perform
 development for every possible use, we are always willing to help and offer
suggestions to people who are trying to use MySQL Server in new territories.

One of our main goals with the product is to continue to work toward
compliance with the SQL standard, but without sacrificing speed or reliability.
We are not afraid to add extensions to SQL or support for non-SQL
features if this greatly increases the usability of MySQL Server for a large
segment of our user base.
The @code{HANDLER} interface in MySQL Server 4.0 is an example of this
strategy. @xref{HANDLER, , @code{HANDLER}}.

We will continue to support transactional and non-transactional
databases to satisfy both mission-critical 24/7 usage and
heavy Web or logging usage.

MySQL Server was originally designed to work with medium size databases
(10-100 million rows, or about 100MB per table) on small computer systems. 
Today MySQL Server handles terabyte-size databases, but the code can also be
compiled in a reduced version suitable for hand-held and embedded devices.
The compact design of the MySQL server makes development in both directions
possible without any conflicts in the source tree.

Currently, we are not targeting realtime support, although MySQL
replication capabilities already offer significant functionality.

Database cluster support now exists through third-party clustering
solutions as well as the integration of our acquired NDB Cluster
technology into a new storage engine, available from version 4.1.2.
@xref{NDBCluster}.

We are also looking at providing XML support in the database server.

@menu
* Standards::                   What Standards MySQL Follows
* SQL mode::                    Selecting SQL Modes
* ANSI mode::                   Running MySQL in ANSI Mode
* Extensions to ANSI::          MySQL Extensions to Standard SQL
* Differences from ANSI::       MySQL Differences from Standard SQL
* Constraints::                 How MySQL Deals with Constraints
* Bugs::                        Known Errors and Design Deficiencies in MySQL
@end menu


@node Standards, SQL mode, Compatibility, Compatibility
@subsection What Standards MySQL Follows

We are aiming toward supporting the full ANSI/ISO SQL standard,
but without making concessions to speed and quality of the code.

ODBC levels 0@minus{}3.51.


@node SQL mode, ANSI mode, Standards, Compatibility
@subsection Selecting SQL Modes

The MySQL server can operate in different SQL modes, and can apply these
modes differentially for different clients. This allows an application to
tailor server operation to its own requirements.

Modes define what SQL syntax MySQL should support and what kind of
validation checks it should perform on the data.  This makes it easier
to use MySQL in a lot of different environments and to use MySQL together
with other database servers.

You can set the default SQL mode by starting @command{mysqld} with the
@code{--sql-mode="modes"} option. Beginning with MySQL 4.1, you can also
change the mode after startup time by setting the @code{sql_mode} variable
with a @code{SET [SESSION|GLOBAL] sql_mode='modes'} statement.

For more information on setting the server mode, see @ref{Server SQL mode}.


@node ANSI mode, Extensions to ANSI, SQL mode, Compatibility
@subsection Running MySQL in ANSI Mode

@cindex running, ANSI mode
@cindex ANSI mode, running

You can tell @command{mysqld} to use the ANSI mode with the @code{--ansi}
startup option. @xref{Server options}.

Running the server in ANSI mode is the same as starting it with these options
(specify the @code{--sql_mode} value on a single line):

@example
--transaction-isolation=SERIALIZABLE
--sql-mode=REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,
IGNORE_SPACE,ONLY_FULL_GROUP_BY
@end example

In MySQL 4.1, you can achieve the same effect with these two statements
(specify the @code{sql_mode} value on a single line):

@example
SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET GLOBAL sql_mode = 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,
IGNORE_SPACE,ONLY_FULL_GROUP_BY';
@end example

@xref{SQL mode}.

In MySQL 4.1.1, the @code{sql_mode} options shown can be also be set with
this statement:

@example
SET GLOBAL sql_mode='ansi';
@end example

In this case, the value of the @code{sql_mode} variable will be set to all
options that are relevant for ANSI mode. You can check the result like this:

@example
mysql> SET GLOBAL sql_mode='ansi';
mysql> SELECT @@@@global.sql_mode;
        -> 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,
            IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI';
@end example


@node Extensions to ANSI, Differences from ANSI, ANSI mode, Compatibility
@subsection MySQL Extensions to Standard SQL

@cindex hints
MySQL Server includes some extensions that you probably will not find in
other SQL databases.  Be warned that if you use them, your code will not be
portable to other SQL servers.  In some cases, you can write code that
includes MySQL extensions, but is still portable, by using comments
of the form @code{/*! ... */}.  In this case, MySQL Server will parse and
execute the code within the comment as it would any other MySQL
statement, but other SQL servers will ignore the extensions.  For example:

@example
SELECT /*! STRAIGHT_JOIN */ col_name FROM table1,table2 WHERE ...
@end example

If you add a version number after the @samp{!} character, the syntax within
the comment will be
executed only if the MySQL version is equal to or newer than the specified
version number:

@example
CREATE /*!32302 TEMPORARY */ TABLE t (a INT);
@end example

This means that if you have Version 3.23.02 or newer, MySQL
Server will use the @code{TEMPORARY} keyword.

The following descriptions list MySQL extensions, organized by category.

@table @asis
@item Organization of data on disk

MySQL Server maps each database to a directory under the MySQL
data directory, and tables within a database to filenames in the database
directory.
This has a few implications:

@itemize @bullet

@item
@cindex database names, case-sensitivity
@cindex case-sensitivity, of database names
@cindex table names, case-sensitivity
@cindex case-sensitivity, of table names
Database names and table names are case sensitive in MySQL Server on
operating systems that have case-sensitive filenames (such as most Unix
systems). @xref{Name case sensitivity}.

@item
You can use standard system commands to back up, rename, move, delete, and copy
tables that are managed by the @code{MyISAM} or @code{ISAM} storage engines.
For example, to rename a @code{MyISAM} table, rename the @file{.MYD},
@file{.MYI}, and @file{.frm} files to which the table corresponds.
@end itemize

Database, table, index, column, or alias names may begin with a digit
(but may not consist solely of digits).

@item General language syntax

@itemize @bullet

@item
Strings may be enclosed by either @samp{"} or @samp{'}, not just by @samp{'}.

@item
Use of @samp{\} as an escape character in strings.

@item
In SQL statements, you can access tables from different databases
with the @var{db_name.tbl_name} syntax.  Some SQL servers provide
the same functionality but call this @code{User space}.
MySQL Server doesn't support tablespaces such as used in statements like this:
@code{CREATE TABLE ralph.my_table...IN my_tablespace}.

@end itemize

@item SQL statement syntax

@itemize @bullet

@item
The @code{ANALYZE TABLE}, @code{CHECK TABLE}, @code{OPTIMIZE TABLE}, and
@code{REPAIR TABLE} statements.

@item
The @code{CREATE DATABASE} and @code{DROP DATABASE} statements.
@xref{CREATE DATABASE, , @code{CREATE DATABASE}}.

@item
The @code{DO} statement.

@item
@code{EXPLAIN SELECT} to get a description of how tables are joined.

@item
The @code{FLUSH} and @code{RESET} statements.

@item
The @code{SET} statement. @xref{SET OPTION, , @code{SET}}.

@item
The @code{SHOW} statement.
@xref{SHOW, , @code{SHOW}}.

@cindex Oracle compatibility
@cindex compatibility, with Oracle
@item
Use of @code{LOAD DATA INFILE}. In many cases, this syntax is compatible with
Oracle's @code{LOAD DATA INFILE}. @xref{LOAD DATA, , @code{LOAD DATA}}.

@item
Use of @code{RENAME TABLE}. @xref{RENAME TABLE, , @code{RENAME TABLE}}.

@item
Use of @code{REPLACE} instead of @code{DELETE} + @code{INSERT}.
@xref{REPLACE, , @code{REPLACE}}.

@item
Use of @code{CHANGE col_name}, @code{DROP col_name}, or @code{DROP
INDEX}, @code{IGNORE} or @code{RENAME} in an @code{ALTER TABLE}
statement.
Use of multiple @code{ADD}, @code{ALTER}, @code{DROP}, or @code{CHANGE}
clauses in an @code{ALTER TABLE} statement.
@xref{ALTER TABLE, , @code{ALTER TABLE}}.

@item
Use of index names, indexes on a prefix of a field, and use of
@code{INDEX} or @code{KEY} in a @code{CREATE TABLE}
statement. @xref{CREATE TABLE, , @code{CREATE TABLE}}.

@item
Use of @code{TEMPORARY} or @code{IF NOT EXISTS} with @code{CREATE TABLE}.

@item
Use of @code{IF EXISTS} with @code{DROP TABLE}.

@item
You can drop multiple tables with a single @code{DROP TABLE} statement.

@item
The @code{ORDER BY} and @code{LIMIT} clauses of the @code{UPDATE} and
@code{DELETE} statements.

@item
@code{INSERT INTO ... SET col_name = ...} syntax.

@item
The @code{DELAYED} clause of the @code{INSERT} and @code{REPLACE}
statements.

@item
The @code{LOW_PRIORITY} clause of the @code{INSERT}, @code{REPLACE},
@code{DELETE}, and @code{UPDATE} statements.

@item
Use of @code{INTO OUTFILE} and @code{STRAIGHT_JOIN} in a @code{SELECT}
statement. @xref{SELECT, , @code{SELECT}}.

@item
The @code{SQL_SMALL_RESULT} option in a @code{SELECT} statement.

@item
You don't need to name all selected columns in the @code{GROUP BY} part.
This gives better performance for some very specific, but quite normal
queries.
@xref{Group by functions and modifiers}.

@item
You can specify @code{ASC} and @code{DESC} with @code{GROUP BY}.

@item
The ability to set variables in a statement with the @code{:=} assignment
operator:
@example
mysql> SELECT @@a:=SUM(total),@@b=COUNT(*),@@a/@@b AS avg
    -> FROM test_table;
mysql> SELECT @@t1:=(@@t2:=1)+@@t3:=4,@@t1,@@t2,@@t3;
@end example

@end itemize

@item Column types

@itemize @bullet
@item
The column types @code{MEDIUMINT}, @code{SET}, @code{ENUM}, and the
different @code{BLOB} and @code{TEXT} types.

@item
The column attributes @code{AUTO_INCREMENT}, @code{BINARY}, @code{NULL},
@code{UNSIGNED}, and @code{ZEROFILL}.
@end itemize

@item Functions and operators

@itemize @bullet

@item
To make it easier for users who come from other SQL environments,
MySQL Server supports aliases for many functions. For example, all
string functions support both standard SQL syntax and ODBC syntax.

@item
MySQL Server understands the @code{||} and @code{&&} operators to mean
logical OR and AND, as in the C programming language.  In MySQL Server,
@code{||} and @code{OR} are synonyms, as are @code{&&} and @code{AND}.
Because of this nice syntax, MySQL Server doesn't support
the standard SQL @code{||} operator for string concatenation; use
@code{CONCAT()} instead. Because @code{CONCAT()} takes any number
of arguments, it's easy to convert use of the @code{||} operator to
MySQL Server.

@item
Use of @code{COUNT(DISTINCT list)} where @code{list} has more than one element.

@item
All string comparisons are case-insensitive by default, with sort
ordering determined by the current character set (ISO-8859-1 Latin1 by
default).  If you don't like this, you should declare your columns with
the @code{BINARY} attribute or use the @code{BINARY} cast, which causes
comparisons to be done using the underlying character code values rather
then a lexical ordering.

@cindex PostgreSQL compatibility
@cindex compatibility, with PostgreSQL
@item
The @code{%} operator is a synonym for @code{MOD()}.  That is,
@code{N % M} is equivalent to @code{MOD(N,M)}.  @code{%} is supported
for C programmers and for compatibility with PostgreSQL.

@item
The @code{=}, @code{<>}, @code{<=} ,@code{<}, @code{>=},@code{>},
@code{<<}, @code{>>}, @code{<=>}, @code{AND}, @code{OR}, or @code{LIKE}
operators may be used in column comparisons to the left of the
@code{FROM} in @code{SELECT} statements.  For example:

@example
mysql> SELECT col1=1 AND col2=2 FROM @var{tbl_name};
@end example

@item
The @code{LAST_INSERT_ID()} function that returns the most recent
@code{AUTO_INCREMENT} value.
@xref{Information functions}.

@item
@code{LIKE} is allowed on numeric columns.

@item
The @code{REGEXP} and @code{NOT REGEXP} extended regular expression
operators.

@item
@code{CONCAT()} or @code{CHAR()} with one argument or more than two
arguments.  (In MySQL Server, these functions can take any number of
arguments.)

@item The @code{BIT_COUNT()}, @code{CASE}, @code{ELT()},
@code{FROM_DAYS()}, @code{FORMAT()}, @code{IF()}, @code{PASSWORD()},
@code{ENCRYPT()}, @code{MD5()}, @code{ENCODE()}, @code{DECODE()},
@code{PERIOD_ADD()}, @code{PERIOD_DIFF()}, @code{TO_DAYS()}, and
@code{WEEKDAY()} functions.

@item
Use of @code{TRIM()} to trim substrings.  Standard SQL supports removal
of single characters only.

@item
The @code{GROUP BY} functions @code{STD()}, @code{BIT_OR()},
@code{BIT_AND()}, @code{BIT_XOR()}, and @code{GROUP_CONCAT()}.
@xref{Group by functions and modifiers}.
@end itemize

@end table

For a prioritized list indicating when new extensions will be added to
MySQL Server, you should consult the online MySQL TODO list at
@uref{http://dev.mysql.com/doc/mysql/en/TODO.html}.
That is the latest version of the TODO list in this manual. @xref{TODO}.


@node Differences from ANSI, Constraints, Extensions to ANSI, Compatibility
@subsection MySQL Differences from Standard SQL

We try to make MySQL Server follow the ANSI SQL standard and the
ODBC SQL standard, but MySQL Server performs operations differently in some
cases:

@itemize @bullet
@item
For @code{VARCHAR} columns, trailing spaces are removed when the value is
stored. @xref{Bugs}.

@item
In some cases, @code{CHAR} columns are silently converted to @code{VARCHAR}
columns when you define a table or alter its structure.
@xref{Silent column changes}.

@item
Privileges for a table are not automatically revoked when you delete a
table. You must explicitly issue a @code{REVOKE} statement to revoke
privileges for a table. @xref{GRANT, , @code{GRANT}}.
@end itemize

@menu
* ANSI diff Subqueries::        Subqueries
* ANSI diff SELECT INTO TABLE::  @code{SELECT INTO TABLE}
* ANSI diff Transactions::      Transactions and Atomic Operations
* ANSI diff Triggers::          Stored Procedures and Triggers
* ANSI diff Foreign Keys::      Foreign Keys
* ANSI diff Views::             Views
* ANSI diff comments::          @samp{--} as the Start of a Comment
@end menu


@node ANSI diff Subqueries, ANSI diff SELECT INTO TABLE, Differences from ANSI, Differences from ANSI
@subsubsection Subqueries

MySQL 4.1 supports subqueries and derived tables.
A ``subquery'' is a @code{SELECT} statement nested within another statement.
A ``derived table'' (an unnamed view) is a subquery in the @code{FROM} clause
of another statement.
@xref{Subqueries}.

For MySQL versions older than 4.1, most subqueries can be
rewritten using joins or other methods.
See @ref{Rewriting subqueries} for examples that show how to do this.


@node ANSI diff SELECT INTO TABLE, ANSI diff Transactions, ANSI diff Subqueries, Differences from ANSI
@subsubsection @code{SELECT INTO TABLE}

@findex SELECT INTO TABLE

MySQL Server doesn't support the Sybase SQL extension:
@code{SELECT ... INTO TABLE ...}.  Instead, MySQL Server supports the
standard SQL syntax @code{INSERT INTO ... SELECT ...}, which is basically
the same thing. @xref{INSERT SELECT,  , @code{INSERT SELECT}}.

@example
INSERT INTO tbl_temp2 (fld_id)
    SELECT tbl_temp1.fld_order_id
    FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;
@end example

Alternatively, you can use @code{SELECT INTO OUTFILE ...} or
@code{CREATE TABLE ... SELECT}.

From version 5.0, MySQL supports @code{SELECT ... INTO} with user
variables. The same syntax may also be used inside stored procedures using
cursors and local variables.
@xref{SELECT INTO Statement}.


@node ANSI diff Transactions, ANSI diff Triggers, ANSI diff SELECT INTO TABLE, Differences from ANSI
@subsubsection Transactions and Atomic Operations

@findex COMMIT
@findex ROLLBACK
@cindex transactions, support
@cindex transaction-safe tables
@cindex tables, updating
@cindex updating, tables
@cindex @code{InnoDB} tables
@cindex @code{BDB} tables
@cindex @code{ACID}

MySQL Server (version 3.23-max and all versions 4.0 and above) supports
transactions with the @code{InnoDB} and @code{BDB}
transactional storage engines.
@code{InnoDB} provides @emph{full} @code{ACID} compliance.
@xref{Storage engines}.

The other non-transactional storage engines in MySQL Server (such as
@code{MyISAM}) follow a different paradigm for data integrity called
``atomic operations.'' In transactional terms, @code{MyISAM}
tables effectively always operate in @code{AUTOCOMMIT=1} mode.
Atomic operations often offer comparable integrity with higher performance.

With MySQL Server supporting both paradigms, you can decide whether your
applications are best served by the speed of atomic operations or the use of
transactional features. This choice can be made on a per-table basis.

As noted, the trade-off for transactional versus non-transactional table
types lies mostly in performance. Transactional tables have significantly
higher memory and diskspace requirements, and more CPU overhead.
On the other hand, transactional table types such as @code{InnoDB} also
offer many significant features. MySQL Server's modular design allows the
concurrent use of different storage engines to suit different
requirements and deliver optimum performance in all situations.

But how do you use the features of MySQL Server to maintain rigorous
integrity even with the non-transactional @code{MyISAM} tables, and how
do these features compare with the transactional table types?

@enumerate
@item
If your applications are written in a way that is dependent on being able
to call @code{ROLLBACK} rather than
@code{COMMIT} in critical situations, transactions are more
convenient. Transactions also ensure that unfinished updates or
corrupting activities are not committed to the database; the server is
given the opportunity to do an automatic rollback and your database is
saved.

If you use non-transactional tables,
MySQL Server in almost all cases allows you to resolve potential problems
by including simple checks before updates and by running simple scripts
that check the databases for inconsistencies and automatically repair
or warn if such an inconsistency occurs. Note that just by using the
MySQL log or even adding one extra log, you can normally fix tables
perfectly with no data integrity loss.

@item
More often than not, critical transactional updates can be rewritten to be
atomic. Generally speaking, all integrity problems that transactions
solve can be done with @code{LOCK TABLES} or atomic updates, ensuring
that you never will get an automatic abort from the server, which is
a common problem with transactional database systems.

@item
Even a transactional system can lose data if the server goes down.
The difference between different systems lies in just how small the
time-lag is where they could lose data. No system is 100% secure, only
``secure enough.'' Even Oracle, reputed to be the safest of
transactional database systems, is reported to sometimes lose data in such
situations.

To be safe with MySQL Server, whether or not using transactional tables, you
only need to have backups and have binary logging turned on. With
this you can recover from any situation that you could with any
other transactional database system.  It is always good to have
backups, regardless of which database system you use.
@end enumerate

The transactional paradigm has its benefits and its drawbacks. Many
users and application developers depend on the ease with which they
can code around problems where an abort appears to be, or is necessary.
However, even if you are new to the atomic operations paradigm, or more
familiar with transactions, do consider the speed benefit that
non-transactional tables can offer on the order of three to five times
the speed of the fastest and most optimally tuned transactional tables.

In situations where integrity is of highest importance, MySQL Server offers
transaction-level reliability and integrity even for non-transactional tables.
If you lock tables with @code{LOCK TABLES}, all updates will stall
until any integrity checks are made. If you obtain a @code{READ LOCAL} lock
(as opposed to a write lock) for a table that allows concurrent inserts at the
end of the table, reads are allowed, as are inserts by other clients.
The new inserted records will not be seen by the
client that has the read lock until it releases the lock.
With @code{INSERT DELAYED}, you can queue inserts into a local
queue, until the locks are released, without having the client wait
for the insert to complete. @xref{INSERT DELAYED}.

``Atomic,'' in the sense that we mean it, is nothing magical. It only
means that you can be sure that while each specific update is running,
no other user can interfere with it, and there will never be an
automatic rollback (which can happen with transactional tables if you
are not very careful).  MySQL Server also guarantees that there will not be
any dirty reads.

Following are some techniques for working with non-transactional tables:

@itemize @bullet
@item
Loops that need transactions normally can be coded with the help of
@code{LOCK TABLES}, and you don't need cursors to update
records on the fly.

@item
To avoid using @code{ROLLBACK}, you can use the following strategy:

@enumerate
@item
Use @code{LOCK TABLES} to lock all the tables you want to access.
@item
Test the conditions that must be true before performing the update.
@item
Update if everything is okay.
@item
Use @code{UNLOCK TABLES} to release your locks.
@end enumerate

This is usually a much faster method than using transactions with
possible rollbacks, although not always. The only situation
this solution doesn't handle is when someone kills the threads in the
middle of an update. In this case, all locks will be released but some
of the updates may not have been executed.

@item
You can also use functions to update records in a single operation.
You can get a very efficient application by using the following
techniques:

@itemize @bullet
@item Modify columns relative to their current value.
@item Update only those columns that actually have changed.
@end itemize

For example, when we are doing updates to some customer information, we
update only the customer data that has changed and test only that none of
the changed data, or data that depends on the changed data, has changed
compared to the original row. The test for changed data is done with the
@code{WHERE} clause in the @code{UPDATE} statement. If the record wasn't
updated, we give the client a message: ``Some of the data you have changed
has been changed by another user.'' Then we show the old row versus the new
row in a window so that the user can decide which version of the customer
record to use.

This gives us something that is similar to column locking but is actually
even better because we only update some of the columns, using values that
are relative to their current values.  This means that typical @code{UPDATE}
statements look something like these:

@example
UPDATE tablename SET pay_back=pay_back+125;

UPDATE customer
  SET
    customer_date='current_date',
    address='new address',
    phone='new phone',
    money_owed_to_us=money_owed_to_us-125
  WHERE
    customer_id=id AND address='old address' AND phone='old phone';
@end example

This is very efficient and works even if another client
has changed the values in the @code{pay_back} or @code{money_owed_to_us}
columns.

@item
@findex mysql_insert_id()
@findex LAST_INSERT_ID()
In many cases, users have wanted @code{LOCK TABLES} and/or @code{ROLLBACK}
for the purpose of managing unique identifiers.  This can be handled much
more efficiently without locking or rolling back by using an
@code{AUTO_INCREMENT} column and either the
@code{LAST_INSERT_ID()} SQL function or the @code{mysql_insert_id()} C API function.
@xref{Information functions}.
@xref{mysql_insert_id, , @code{mysql_insert_id()}}.

@cindex rows, locking
@cindex locking, row-level
You can generally code around the need for row-level locking. Some situations
really do need it, and @code{InnoDB} tables support row-level locking. With
@code{MyISAM} tables, you can use a flag column in the table and do something
like the following:

@example
UPDATE @var{tbl_name} SET row_flag=1 WHERE id=ID;
@end example

MySQL returns 1 for the number of affected rows if the row was
found and @code{row_flag} wasn't already 1 in the original row.

You can think of it as though MySQL Server changed the preceding query to:

@example
UPDATE @var{tbl_name} SET row_flag=1 WHERE id=ID AND row_flag <> 1;
@end example
@end itemize


@node ANSI diff Triggers, ANSI diff Foreign Keys, ANSI diff Transactions, Differences from ANSI
@subsubsection Stored Procedures and Triggers

@cindex stored procedures and triggers, defined
@cindex procedures, stored
@cindex triggers

Stored procedures are implemented in MySQL version 5.0.
@xref{Stored Procedures}.

Triggers are currently being implemented, with basic functionality in
MySQL 5.0, with further development planned for MySQL 5.1.


@node ANSI diff Foreign Keys, ANSI diff Views, ANSI diff Triggers, Differences from ANSI
@subsubsection Foreign Keys

@cindex foreign keys
@cindex keys, foreign

In MySQL Server 3.23.44 and up, the @code{InnoDB} storage engine supports
checking of foreign key constraints, including @code{CASCADE}, @code{ON
DELETE}, and @code{ON UPDATE}. @xref{InnoDB foreign key constraints}.

For storage engines other than @code{InnoDB}, MySQL Server parses the
@code{FOREIGN KEY} syntax in @code{CREATE TABLE} statements, but does not
use or store it. In the future, the implementation will be
extended to store this information in the table specification file so that it
may be retrieved by @command{mysqldump} and ODBC.  At a later stage,
foreign key constraints will be implemented for @code{MyISAM} tables as well.

Foreign key enforcement offers several benefits to database developers:

@itemize @bullet
@item
Assuming proper design of the relationships, foreign key constraints
make it more difficult for a programmer to introduce an inconsistency
into the database.

@item
Centralized checking of constraints by the database server makes it
unnecessary to perform these checks on the application side. This
eliminates the possibility that different applications may not all check the
constraints in the same way.

@item
Using cascading updates and deletes can simplify the application code.

@item
Properly designed foreign key rules aid in documenting relationships
between tables.
@end itemize

Do keep in mind that these benefits come at the cost of additional overhead
for the database server to perform the necessary checks. Additional checking
by the server affects performance, which for some applications may be
sufficiently undesirable as to be avoided if possible.
(Some major commercial applications have coded the foreign-key logic at the
application level for this reason.)

MySQL gives database developers the choice of which approach to use. If you
don't need foreign keys and want to avoid the overhead associated with
enforcing referential integrity, you can choose another table type instead,
such as @code{MyISAM}. (For example, the @code{MyISAM} storage engine offers
very fast performance for applications that perform only @code{INSERT} and
@code{SELECT} operations, because the inserts can be performed concurrently
with retrievals.  @xref{Table locking}.)

If you choose not to take advantage of referential integrity checks,
keep the following considerations in mind:

@itemize @bullet
@item
In the absence of server-side foreign key relationship checking, the
application itself must handle relationship issues.  For example, it must
take care to insert rows into tables in the proper
order, and to avoid creating orphaned child records. It must also be able to
recover from errors that occur in the middle of multiple-record insert
operations.

@item
If @code{ON DELETE} is the only referential integrity capability an
application needs, note that as of MySQL Server 4.0, you can use
multiple-table @code{DELETE} statements to delete rows from many
tables with a single statement. @xref{DELETE,  , @code{DELETE}}.

@item
A workaround for the lack of @code{ON DELETE} is to add
the appropriate @code{DELETE} statement to your application when you
delete records from a table that has a foreign key. In practice, this is often
as quick as using foreign keys, and is more portable.

@end itemize

Be aware that the use of foreign keys can in some instances lead
to problems:

@itemize @bullet
@item
Foreign key support addresses many referential integrity
issues, but it is still necessary to design key relationships carefully to avoid
circular rules or incorrect combinations of cascading deletes.

@item
It is not uncommon for a DBA to create a topology of relationships that
makes it difficult to restore individual tables from a backup.
(MySQL alleviates this difficulty by allowing you to temporarily disable
foreign key checks when reloading a table that depends on other tables.
@xref{InnoDB foreign key constraints}.
As of MySQL 4.1.1,
@command{mysqldump} generates dump files that take advantage of this
capability automatically when reloaded.)
@end itemize

Note that foreign keys in SQL are used to check and enforce referential
integrity, not to join tables.  If you want to get results from multiple
tables from a @code{SELECT} statement, you do this by performing a join
between them:

@example
SELECT * FROM t1, t2 WHERE t1.id = t2.id;
@end example

@xref{JOIN, , @code{JOIN}}. @xref{example-Foreign keys}.

The @code{FOREIGN KEY} syntax without @code{ON DELETE ...} is often used
by ODBC applications to produce automatic @code{WHERE} clauses.


@node ANSI diff Views, ANSI diff comments, ANSI diff Foreign Keys, Differences from ANSI
@subsubsection Views

@cindex views
@cindex views, updatable

Views (including updatable views) are being implemented in the 5.0 version
of MySQL Server.  They are already available in binary releases from 5.0.1
and up.
@xref{CREATE VIEW,  , @code{CREATE VIEW}}.

Views are useful for allowing users to access a set of relations (tables)
as if it were a single table, and limiting their access to just that.
Views can also be used to restrict access to rows (a subset of a
particular table).
For access control to columns, you can also use the sophisticated
privilege system in MySQL Server.
@xref{Privilege system}.

In designing an implementation of views, our ambitious goal, as much as
is possible within the confines of SQL, has been full compliance with
``Codd's Rule #6'' for relational database systems: ``All views
that are theoretically updatable, should in practice also be updatable.''


@node ANSI diff comments,  , ANSI diff Views, Differences from ANSI
@subsubsection @samp{--} as the Start of a Comment

@cindex comments, starting
@cindex starting, comments

Some other SQL databases use @samp{--} to start comments.
MySQL Server uses @samp{#} as the start comment character. You can also use
the C comment style @code{/* this is a comment */} with MySQL Server.
@xref{Comments}.

MySQL Server 3.23.3 and above support the @samp{--} comment style,
provided the comment is followed by a space (or by a control character such
as a newline). The requirement for a space is to prevent problems with
automatically generated SQL queries that have used something like the following code, where we automatically insert the value of the payment for
@code{!payment!}:

@example
UPDATE account SET credit=credit-!payment!
@end example

Think about what happens if the value of @code{payment} is a negative value
such as @code{-1}:

@example
UPDATE account SET credit=credit--1
@end example

@code{credit--1} is a legal expression in SQL, but if @code{--} is interpreted
as the start of a comment, part of the expression is discarded. The result is a
statement that has a completely different meaning than intended:

@example
UPDATE account SET credit=credit
@end example

The statement produces no change in value at all!  This illustrates that
allowing comments to start with @samp{--} can have serious consequences.

Using our implementation of this method of commenting in MySQL Server
3.23.3 and up, @code{credit--1} is actually safe.

Another safe feature is that the @command{mysql} command-line client
removes all lines that start with @samp{--}.


The following information is relevant only if you are running a
MySQL version earlier than 3.23.3:

If you have an SQL program in a text file that contains @samp{--}
comments, you should use the @command{replace} utility as follows to convert the
comments to use @samp{#} characters:

@example
shell> replace " --" " #" < text-file-with-funny-comments.sql \
         | mysql @var{db_name}
@end example

instead of the usual:

@example
shell> mysql @var{db_name} < text-file-with-funny-comments.sql
@end example

You can also edit the command file ``in place'' to change the @samp{--}
comments to @samp{#} comments:

@example
shell> replace " --" " #" -- text-file-with-funny-comments.sql
@end example

Change them back with this command:

@example
shell> replace " #" " --" -- text-file-with-funny-comments.sql
@end example


@node Constraints, Bugs, Differences from ANSI, Compatibility
@subsection How MySQL Deals with Constraints

@findex constraints

MySQL allows you to work both with transactional tables that allow
rollback and with non-transactional tables that do not. Because of this,
constraint handling is a bit different in MySQL than in other databases.
We must handle the case when you have inserted or updated a lot of rows
in a non-transactional table for which changes cannot be rolled back when
an error occurs.

The basic philosophy is that MySQL Server tries to produce an error for
anything that it can detect while parsing a statement to be executed, and
tries to recover from any errors that occur while executing the statement.
We do this in most cases, but not yet for all. @xref{TODO future}.

The options MySQL has when an error occurs are to stop the statement in the
middle or to recover as well as possible from the problem and continue.
By default, the server follows the latter course. This means, for example,
that the server may coerce illegal values to the closest legal values.

Beginning with MySQL 5.0.2, several SQL mode options are available to provide
greater control over how accepting to be of bad data values and whether to
continue executing a statement or abort it when errors occur. Using these
options, you can configure MySQL Server to act in a more traditional fashion
that is like other DBMSs that reject improper input. The SQL mode can be set
at runtime, which enables individual clients to select the behavior most
appropriate for their requirements.
@xref{Server SQL mode}.

The following sections describe what happens for the different types of
constraints.

@menu
* constraint primary key::      @code{PRIMARY KEY} and @code{UNIQUE} Index Constraints
* constraint invalid data::     Constraints on Invalid Data
* constraint enum::             @code{ENUM} and @code{SET} Constraints
@end menu

@node constraint primary key, constraint invalid data, Constraints, Constraints
@subsubsection @code{PRIMARY KEY} and @code{UNIQUE} Index Constraints

@cindex PRIMARY KEY, constraint
@cindex foreign key, constraint
@cindex UNIQUE, constraint

Normally, an error occurs when you try to @code{INSERT} or @code{UPDATE}
a row that causes a primary key, unique key, or foreign key violation.
If you are using a transactional storage engine such as @code{InnoDB}, MySQL
automatically rolls back the statement.  If you are using a non-transactional
storage engine, MySQL stops processing the statement at the row for which
the error occurred and leaves any remaining rows unprocessed.

If you wish to ignore such key violations, MySQL supports an @code{IGNORE}
keyword for @code{INSERT} and @code{UPDATE}. In this case, MySQL ignores
any key violations and continues processing with the next row.
@xref{INSERT,  , @code{INSERT}}.
@xref{UPDATE,  , @code{UPDATE}}.

You can get information about the number of rows actually inserted or
updated with the @code{mysql_info()} C API function.
@xref{mysql_info,  , @code{mysql_info()}}.
In MySQL 4.1 and up, you also can use the @code{SHOW WARNINGS} statement.
@xref{SHOW WARNINGS,  , @code{SHOW WARNINGS}}.

For the moment, only @code{InnoDB} tables support foreign keys.
@xref{InnoDB foreign key constraints}.
Foreign key support in @code{MyISAM} tables is scheduled for implementation
in MySQL 5.1.


@node constraint invalid data, constraint enum, constraint primary key, Constraints
@subsubsection Constraints on Invalid Data

@cindex NOT NULL, constraint
@cindex DEFAULT, constraint
@cindex default values, suppression
@cindex suppression, default values
@cindex invalid data, constraint

Before MySQL 5.0.2, MySQL is forgiving of illegal or improper data values
and coerces them to legal values for data entry. In MySQL 5.0.2 and up,
that remains the default behavior, but you can select more traditional
treatment of bad values such that the server rejects them and aborts the
the statement in which they occur.  This section describes the default
(forgiving) behavior of MySQL, as well as the newer strict SQL mode and
how it differs.

The following holds true when you are not using strict mode.
If you insert an ``incorrect'' value into a column, such as a @code{NULL}
into a @code{NOT NULL} column or a too-large numeric value into a
numeric column, MySQL sets the column to the ``best possible value''
instead of producing an error:

@itemize @bullet
@item
If you try to store an out of range value in a numeric column, MySQL
Server instead stores zero, the smallest possible value, or the largest
possible value in the column.

@item
For strings, MySQL stores either the empty string or the longest
possible string that can be in the column.

@item
If you try to store a string that doesn't start with a number into a
numeric column, MySQL Server stores 0.

@item
If you try to store @code{NULL} into a column that doesn't take @code{NULL}
values, MySQL Server stores 0 or @code{''} (the empty string) instead.

@item
MySQL allows you to store certain incorrect date values into @code{DATE} and
@code{DATETIME} columns (such as @code{'2000-02-31'} or @code{'2000-02-00'}).
The idea is that it's not the job of the SQL server to validate dates. If
MySQL can store a date value and retrieve exactly the same value, MySQL
stores it as given.  If the date is totally wrong (outside the server's
ability to store it), the special date value @code{'0000-00-00'} is stored
in the column instead.

@item
If an @code{INSERT} statement specifies no value for a column, MySQL inserts
its default value if the column definition includes an explicit @code{DEFAULT}
clause. If the definition has no such @code{DEFAULT} clause, MySQL inserts
the implicit default value for the column data type.  In general,
this is the empty string for string columns, 0 for numeric columns,
and @code{'0000-00-00'} for date columns.  Implicit default values are
discussed in @ref{CREATE TABLE,  , @code{CREATE TABLE}}.

@end itemize

The reason for the preceding rules is that we can't check these conditions
until the statement has begun executing.  We can't just roll back if we
encounter a problem after updating a few rows, because the storage engine may
not support rollback.  The option of terminating the statement is not that
good; in this case, the update would be ``half done,'' which is probably the
worst possible scenario.  In this case, it's better to ``do the best you
can'' and then continue as if nothing happened.

In MySQL 5.0.2 and up, you can select stricter treatment of input values by
using the @code{STRICT_TRANS_TABLES} or @code{STRICT_ALL_TABLES} SQL modes.
@xref{Server SQL mode}.

@code{STRICT_TRANS_TABLES} works like this: For transactional storage
engines, bad data values occurring anywhere in the statement causes
the to abort and roll back.  For non-transactional storage engines,
the statement aborts if the error occurs in the first row to be inserted
or updated.  (In this case, the statement can be regarded to leave the
table unchanged, just as for a transactional table.)  Errors in rows
after the first do not abort the statement. Instead, bad data values
are adjusted and result in warnings rather than errors.  In other words,
with @code{STRICT_TRANS_TABLES}, a wrong value causes MySQL to roll back,
if it can, all updates done so far.

For stricter checking, enable @code{STRICT_ALL_TABLES}. This is the same as
@code{STRICT_TRANS_TABLES} except that for non-transactional storage engines,
errors abort the statement even for bad data in rows following the first row.
This means that if an error occurs partway through a multiple-row insert or
update for a non-transactional table, a partial update results.  Earlier rows
are inserted or updated, but those from the point of the error on are not.
To avoid this for non-transactional tables, either use single-row statements
or else use @code{STRICT_TRANS_TABLES} if conversion warnings rather than
errors are acceptable.  To avoid problems in the first place, do not use
MySQL to check column content. It is safest (and often faster) to let the
application ensure that it passes only legal values to the database.

With either of the strict mode options, you can cause errors to be treated
as warnings by using @code{INSERT IGNORE} or @code{UPDATE IGNORE}.


@node constraint enum,  , constraint invalid data, Constraints
@subsubsection @code{ENUM} and @code{SET} Constraints

@code{ENUM} and @code{SET} columns provide an efficient way to define columns
that can contain only a given set of values.  However, before MySQL 5.0.2,
@code{ENUM} and @code{SET} are not real constraints.  This is for the same
reasons that @code{NOT NULL} is not honored.
@xref{constraint invalid data}.

@code{ENUM} columns always have a default value. If you don't specify
a default value, then it will be @code{NULL} for columns that can have
@code{NULL}, otherwise the first enumeration value is used as the default
value.

If you insert an incorrect value into an @code{ENUM} column or if you
force a value into an @code{ENUM} column with @code{IGNORE}, it is set
to the reserved enumeration value of @code{0}, which is displayed as an
empty string in string context. @xref{ENUM,  , @code{ENUM}}.

If you insert an incorrect value into a @code{SET} column, the incorrect value
is ignored. For example, if the column can contain the values
@code{'a'}, @code{'b'}, and @code{'c'}, an attempt to assign @code{'a,x,b,y'}
results in a value of @code{'a,b'}.
@xref{SET,  , @code{SET}}.

As of MySQL 5.0.2, you can configure the server to use strict SQL mode.
@xref{Server SQL mode}.
When strict mode is not enabled, values entered into @code{ENUM} and @code{SET}
columns are handled as just described for MySQL 4.x.  However, if strict
mode is enabled, the definition of a @code{ENUM} or @code{SET} column does
act as a constraint on values entered into the column. An error occurs
for values that do not satisify these conditions:

@itemize @bullet

@item
An @code{ENUM} value must be one of those listed in the column definition, or
the internal numeric equivalent thereof. The value cannot be the error value
(that is, 0 or the empty string).
For a column defined as @code{ENUM('a','b','c')}, values such as @code{''},
@code{'d'}, and @code{'ax'} are illegal and are rejected.

@item
A @code{SET} value must be the empty string or a value consisting of one or
more of the values listed in the column definition separated by commas.
For a column defined as @code{SET('a','b','c')}, values such as
@code{'d'}, and @code{'a,b,c,d'} are illegal and are rejected.

@end itemize

Errors for invalid values can be suppressed in strict mode if you use
@code{INSERT IGNORE} or @code{UPDATE IGNORE}.  In this case, a warning is
generated rather than an error. For @code{ENUM}, the value is inserted as the
error member (@code{0}). For @code{SET}, the value is inserted as given except that
that any invalid substrings are deleted. For example, @code{'a,x,b,y'}
results in a value of @code{'a,b'}, as described earlier.


@node Bugs,  , Constraints, Compatibility
@subsection Known Errors and Design Deficiencies in MySQL

@cindex bugs, known
@cindex errors, known
@cindex design, issues
@cindex known errors

@menu
* Errors in 3.23::              Errors in 3.23 Fixed in a Later MySQL Version
* Errors in 4.0::               Errors in 4.0 Fixed in a Later MySQL Version
* Open bugs::                   Open Bugs and Design Deficiencies in MySQL
@end menu

@node Errors in 3.23, Errors in 4.0, Bugs, Bugs
@subsubsection Errors in 3.23 Fixed in a Later MySQL Version

The following known errors or bugs are not fixed in MySQL 3.23 because fixing
them would involve changing a lot of code that could introduce other
even worse bugs. The bugs are also classified as ``not fatal'' or
``bearable.''

@itemize @bullet
@item
You should avoid using spaces at the end of column names because this can
cause weird behavior. (Fixed in MySQL 4.0.) (Bug #4196)
@item
You can get a deadlock (hung thread) if you use @code{LOCK TABLE} to lock
multiple tables and then in the same connection use @code{DROP TABLE} to
drop one of them while another thread is trying to lock it.  (To break the
deadlock, you can use @code{KILL} to terminate any of the threads involved.)
This issue is resolved as of MySQL 4.0.12.
@item
@code{SELECT MAX(key_column) FROM t1,t2,t3...} where one of the tables are
empty doesn't return @code{NULL} but instead returns the maximum value for the
column.  This issue is resolved as of MySQL 4.0.11.
@item
@code{DELETE FROM heap_table} without a @code{WHERE} clause doesn't work on
a locked @code{HEAP} table.
@end itemize

@node Errors in 4.0, Open bugs, Errors in 3.23, Bugs
@subsubsection Errors in 4.0 Fixed in a Later MySQL Version

The following known errors or bugs are not fixed in MySQL 4.0 because fixing
them would involve changing a lot of code that could introduce other
even worse bugs. The bugs are also classified as ``not fatal'' or
``bearable.''

@itemize @bullet
@item
In a @code{UNION}, the first @code{SELECT} determines the type,
@code{max_length}, and @code{NULL} properties for the resulting
columns.  This issue is resolved as of MySQL 4.1.1; the property values are
based on the rows from all @code{UNION} parts.
@item
In @code{DELETE} with many tables, you can't refer to tables to be
deleted through an alias. This is fixed as of MySQL 4.1.
@item
You cannot mix @code{UNION ALL} and @code{UNION DISTINCT} in the same query.
If you use @code{ALL} for one @code{UNION}, it is used for all
of them.  This is fixed as of MySQL 4.1.2. The rules for mixed @code{UNION}
types are given in @ref{UNION,  , @code{UNION}}.
@item
@code{FLUSH TABLES WITH READ LOCK} does not block @code{CREATE TABLE}, which
may cause a problem with the binary log position when
doing a full backup of tables and the binary log.
@item
@code{mysqldump --single-transaction --master-data} behaved like
@code{mysqldump --master-data}, so the dump was a blocking one. This is fixed
starting from MySQL 4.1.8.
@end itemize

@node Open bugs,  , Errors in 4.0, Bugs
@subsubsection Open Bugs and Design Deficiencies in MySQL

The following problems are known and fixing them is a high priority:

@itemize @bullet
@item
Even if you are using @code{lower_case_table_names=2} (which enables
MySQL to remember the used case for databases and table names) MySQL
will not on case insensitive systems remember the used case for database
names for the function @code{DATABASE()} or in various logs.

@item
Dropping a @code{FOREIGN KEY} constraint doesn't work in replication because
the constraint may have another name on the slave.

@item
@code{REPLACE} (and @code{LOAD DATA} with the @code{REPLACE} option) does not
trigger @code{ON DELETE CASCADE}.

@item
@code{DISTINCT} with @code{ORDER BY} doesn't work inside @code{GROUP_CONCAT()}
if you don't use all and only those columns that are in the
@code{DISTINCT} list.

@item
If one user has a long-running transaction and another user drops a
table that is updated in the transaction, there is small chance that the
binary log may contain the @code{DROP TABLE} command before the table is
used in the transaction itself.  We plan to fix this in 5.0 by
having the @code{DROP TABLE} wait until the table is not used in any
transaction.

@item
When inserting a big integer value (between 2^63 and 2^64@minus{}1) into a
decimal/string column, it is inserted as a negative value because
the number is evaluated in a signed integer context. We plan to fix this in
MySQL 4.1.

@item
@code{FLUSH TABLES WITH READ LOCK} does not block @code{COMMIT} if the server
is running without binary logging, which may cause a problem (of consistency
between tables) when doing a full backup.

@item
@code{ANALYZE TABLE} on a @code{BDB} table may in some cases make the table
unusable until you restart @command{mysqld}.  If this happens, you will
see errors of the following form in the MySQL error file:

@example
001207 22:07:56  bdb:  log_flush: LSN past current end-of-log
@end example

@item
MySQL accepts parentheses in the @code{FROM} clause of a @code{SELECT}
statement, but silently
ignores them.  The reason for not giving an error is that many clients
that automatically generate queries add parentheses in the @code{FROM}
clause even where they are not needed.

@item
Concatenating many @code{RIGHT JOINS} or combining @code{LEFT} and
@code{RIGHT} join in the same query may not give a correct answer because
MySQL only generates @code{NULL} rows for the table preceding a @code{LEFT} or
before a @code{RIGHT} join.  This will be fixed in 5.0 at the same time
we add support for parentheses in the @code{FROM} clause.

@item
Don't execute @code{ALTER TABLE} on a @code{BDB} table on which you are
running multiple-statement transactions until all those transactions complete.
(The transaction will probably be ignored.)

@item
@code{ANALYZE TABLE}, @code{OPTIMIZE TABLE}, and @code{REPAIR TABLE} may
cause problems on tables for which you are using @code{INSERT DELAYED}.

@item
Doing a @code{LOCK TABLE ...} and @code{FLUSH TABLES ...} doesn't
guarantee that there isn't a half-finished transaction in progress on the
table.

@item
@code{BDB} tables are a bit slow to open. If you have many @code{BDB} tables
in a database, it will take a long time to use the @command{mysql} client on
the database if you are not using the @code{-A} option or if you are using
@code{rehash}. This is especially notable when you have a large table cache.

@item
Replication uses query-level 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.
Although we have never heard of it actually occurring, it is theoretically
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
non-deterministic; that is, left to the will of the query optimizer. (That
generally is not a good practice anyway, even outside of replication!)
For example: 

@itemize @minus
@item
@code{CREATE ... SELECT} or
@code{INSERT ... SELECT}  statements that
insert zero or @code{NULL} values into an @code{AUTO_INCREMENT} column.
@item
@code{DELETE} if you are
deleting rows from a table that has foreign keys with @code{ON DELETE
CASCADE} properties.
@item
@code{REPLACE ... SELECT}, 
@code{INSERT IGNORE ... SELECT} if you have
duplicate key values in the inserted data.
@end itemize
@strong{If and only if all these queries have no @code{ORDER BY}
clause guaranteeing a deterministic order}.

For example, for @code{INSERT ... SELECT} with no @code{ORDER
BY}, the @code{SELECT} may return rows in a different order
(which will result in a row having different ranks, hence getting a
different number in the @code{AUTO_INCREMENT} column),
depending on the choices made by the optimizers on the master and
slave. A query will be optimized differently on the master and slave only if:

@itemize @minus
@item
The files used by the two queries are not exactly the same; for
example, @code{OPTIMIZE TABLE} was run on the master tables and not on
the slave tables. (To fix this, @code{OPTIMIZE TABLE}, @code{ANALYZE TABLE},
and @code{REPAIR TABLE} are written to the binary log as of MySQL 4.1.1).
@item
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 @code{InnoDB} on the master,
but @code{MyISAM} on the slave if the slave has less available disk
space.)
@item
MySQL buffer sizes (@code{key_buffer_size}, and so on) are different on
the master and slave. 
@item
The master and slave run different MySQL versions, and the optimizer
code differs between these versions.
@end itemize

This problem may also affect database restoration using
@command{mysqlbinlog|mysql}.

The easiest way to avoid this problem in all cases is to add an
@code{ORDER BY} clause to 
such non-deterministic queries to ensure that the rows are always
stored or modified in the same order. 
In future MySQL versions, we will automatically add an @code{ORDER BY}
clause when needed.

@end itemize

The following problems are known and will be fixed in due time:

@itemize @bullet

@item
Log filenames are based on the server hostname (if you don't specify a
filename with the startup option). For now you have to use options like
@code{--log-bin=@var{old_host_name}-bin} if you change your hostname to something
else. Another option is to just rename the old files to reflect your
hostname change. @xref{Server options}.

@item
@command{mysqlbinlog} will not delete temporary files left after a
@code{LOAD DATA INFILE} command. @xref{mysqlbinlog,  , @command{mysqlbinlog}}.

@item
@code{RENAME} doesn't work with @code{TEMPORARY} tables or tables used in a
@code{MERGE} table.

@item
When using the @code{RPAD()} function in a query that has to be
resolved by using a temporary table, all resulting strings will
have rightmost spaces removed. This is an example of such a query:

@example
SELECT RPAD(t1.column1, 50, ' ') AS f2, RPAD(t2.column2, 50, ' ') AS f1
FROM table1 as t1 LEFT JOIN table2 AS t2 ON t1.record=t2.joinID
ORDER BY t2.record;
@end example

The final result of this bug is that you will not be able to get spaces on
the right side of the resulting values. The problem also occurs for any other
string function that adds spaces to the right.

The reason for this is due to the fact that @code{HEAP} tables, which are used
first for temporary tables, are not capable of handling @code{VARCHAR} columns.

This behavior exists in all versions of MySQL. 
It will be fixed in one of the 4.1 series releases.

@item
Due to the way table definition files are stored, you cannot use
character 255 (@code{CHAR(255)}) in table names, column names, or enumerations.
This is scheduled to be fixed in version 5.1 when we have new table
definition format files.

@item
When using @code{SET CHARACTER SET}, you can't use translated
characters in database, table, and column names.

@item
You can't use @samp{_} or @samp{%} with @code{ESCAPE} in @code{LIKE
... ESCAPE}.

@item
If you have a @code{DECIMAL} column in which the same number is stored in
different formats (for example, @code{+01.00}, @code{1.00}, @code{01.00}),
@code{GROUP BY} may regard each value as a different value.

@item
You cannot build the server in another directory when using
MIT-pthreads. Because this requires changes to MIT-pthreads, we are not
likely to fix this. @xref{MIT-pthreads}.

@item
@code{BLOB} and @code{TEXT}values can't ``reliably'' be used in @code{GROUP
BY} or @code{ORDER BY} or @code{DISTINCT}. Only the first
@code{max_sort_length} bytes are used when comparing @code{BLOB} values in
these cases.  The default value of @code{max_sort_length} value is 1024. It
can be changed at server startup time.  As of MySQL 4.0.3, it can also be
changed at runtime. For older versions, a workaround for most cases is to
use a substring.  For example:

@example
SELECT DISTINCT LEFT(@var{blob_col},2048) FROM @var{tbl_name};
@end example

@item
Numeric
calculations are done with @code{BIGINT} or @code{DOUBLE} (both are
normally 64 bits long). Which precision you get depends on the function.
The general rule is that bit functions are done with @code{BIGINT}
precision, @code{IF} and @code{ELT()} with @code{BIGINT} or @code{DOUBLE}
precision, and the rest with @code{DOUBLE} precision.  You should try to
avoid using unsigned long long values if they resolve to be bigger than
63 bits (9223372036854775807) for anything other than bit fields.
MySQL Server 4.0 has better @code{BIGINT} handling than 3.23.

@item
All string columns, except @code{BLOB} and @code{TEXT} columns, automatically
have all trailing spaces removed when retrieved. For @code{CHAR} types, this
is okay. The bug is
that in MySQL Server, @code{VARCHAR} columns are treated the same way.

@item
You can have only up to 255 @code{ENUM} and @code{SET} columns in one table.

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

@item
@command{mysqld_safe} redirects all messages from @command{mysqld} to the
@command{mysqld} log.  One problem with this is that if you execute
@command{mysqladmin refresh} to close and reopen the log,
@code{stdout} and @code{stderr} are still redirected to the old log.
If you use @code{--log} extensively, you should edit @command{mysqld_safe} to
log to @file{@var{host_name}.err} instead of @file{@var{host_name}.log} so that you can
easily reclaim the space for the old log by deleting the old one and
executing @command{mysqladmin refresh}.

@item
In the @code{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 @code{KEY}
by @code{2}, not @code{1}:

@example
mysql> UPDATE @var{tbl_name} SET KEY=KEY+1,KEY=KEY+1;
@end example

@item
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 doesn't work:

@example
mysql> SELECT * FROM temp_table, temp_table AS t2;
ERROR 1137: Can't reopen table: 'temp_table'
@end example

@item
The optimizer may handle @code{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 don't participate in the
@code{DISTINCT} comparison.  We will probably change this in the future to
never compare the hidden columns when executing @code{DISTINCT}.

An example of this is:

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

and

@example
SELECT DISTINCT band_downloads.mp3id
       FROM band_downloads,band_mp3
       WHERE band_downloads.userid = 9
       AND band_mp3.id = band_downloads.mp3id
       ORDER BY band_downloads.id DESC;
@end example

In the second case, you might in MySQL Server 3.23.x get two identical rows in
the result set (because the values in the hidden @code{id} column may differ).

Note that this happens only for queries where you don't have the
@code{ORDER BY} columns in the result.

@item
Because MySQL Server allows you to work with table types that don't
support transactions, and thus can't roll back data, some things
behave a little differently in MySQL Server than in other SQL servers.
This is just to ensure that MySQL Server never needs to do a rollback
for an SQL statement.  This may be a little awkward at times because column
values must be checked in the application, but this will actually give
you a nice speed increase because it allows MySQL Server to do some
optimizations that otherwise would be very hard to do.

If you set a column to an incorrect value, MySQL Server will, instead of
doing a rollback, store the ``best possible value'' in the column. For
information about how this occurs, see @ref{Constraints}.

@item
If you execute a @code{PROCEDURE} on a query that returns an empty set,
in some cases the @code{PROCEDURE} will not transform the columns.

@item
Creation of a table of type @code{MERGE} doesn't check whether the underlying
tables are of compatible types.

@item
If you use @code{ALTER TABLE} first to add a @code{UNIQUE} index to a
table used in a @code{MERGE} table and then to
add a normal index on the @code{MERGE} table, the key order will be
different for the tables if there was an old key that was not unique in the
table. This is because @code{ALTER TABLE} puts @code{UNIQUE} indexes before
normal indexes to be able to detect duplicate keys as early as possible.
@end itemize

The following are known bugs in earlier versions of MySQL:

@itemize @bullet
@item
In the following case you can get a core dump:

@itemize @minus
@item
Delayed insert handler has pending inserts to a table.

@item
@code{LOCK TABLE} with @code{WRITE}.

@item
@code{FLUSH TABLES}.
@end itemize

@item
Before MySQL Server 3.23.2, an @code{UPDATE} that updated a key with
a @code{WHERE} on the same key may have failed because the key was used to
search for records and the same row may have been found multiple times:

@example
UPDATE @var{tbl_name} SET KEY=KEY+1 WHERE KEY > 100;
@end example

A workaround is to use:

@example
UPDATE @var{tbl_name} SET KEY=KEY+1 WHERE KEY+0 > 100;
@end example

This will work because MySQL Server will not use an index on expressions in
the @code{WHERE} clause.

@item
Before MySQL Server 3.23, all numeric types were treated as
fixed-point fields. That means that you had to specify how many decimals
a floating-point field should have. All results were returned with the
correct number of decimals.
@end itemize

For information about platform-specific bugs, see the installation and
porting instructions in @ref{Operating System Specific Notes} and
@ref{Porting}.


@node Installing, Tutorial, Introduction, Top
@chapter Installing MySQL

@c TODO: each major section needs intro about what's in section.

@cindex installing, overview

@menu
* General Installation Issues::  General Installation Issues
* Quick Standard Installation::  Standard MySQL Installation Using a Binary Distribution
* Windows installation::        Installing MySQL on Windows
* Linux-RPM::                   Installing MySQL on Linux
* Mac OS X installation::       Installing MySQL on Mac OS X
* NetWare installation::        Installing MySQL on NetWare
* Installing binary::           Installing MySQL on Other Unix-Like Systems
* Installing source::           MySQL Installation Using a Source Distribution
* Post-installation::           Post-Installation Setup and Testing
* Upgrade::                     Upgrading MySQL
* Downgrading::                 Downgrading MySQL
* Operating System Specific Notes::  Operating System-Specific Notes
* Perl support::                Perl Installation Notes
@end menu

This chapter describes how to obtain and install MySQL:

@enumerate

@item
@strong{Determine whether your platform is supported.}  Please note that
not all supported systems are equally good for running MySQL on them.
On some it is much more robust and efficient than others.
See @ref{Which OS} for details.

@item
@strong{Choose which distribution to install.}  Several versions of MySQL are available,
and most are available in several distribution formats.  You can choose
from pre-packaged distributions containing binary (precompiled) programs or
source code.  When in doubt, use a binary distribution.  We also provide
public access to our current source tree for those who want to see our most
recent developments and help us test new code.  To determine which version
and type of distribution you should use, see @ref{Which version}.

@item
@strong{Download the distribution that you want to install.}
For a list of sites from which you can obtain MySQL, see
@ref{Getting MySQL, , Getting MySQL}.
You can verify the integrity of the distribution using the instructions in
@ref{Verifying Package Integrity}.

@item
@strong{Install the distribution.}  To install MySQL from a binary
distribution, use the instructions in @ref{Quick Standard Installation}.
To install MySQL from a source distribution or from the current development
source tree, use the instructions in @ref{Installing source}.

@strong{Note}:
If you plan to upgrade an existing version of MySQL to a newer version
rather than installing MySQL for the first time, see @ref{Upgrade} for
information about upgrade procedures and about issues that you should
consider before upgrading.

If you encounter installation difficulties, see @ref{Operating System
Specific Notes} for information on solving problems for particular
platforms.

@item
@strong{Perform any necessary post-installation setup.} After installing
MySQL, read @ref{Post-installation}.  This section contains important
information about making sure the MySQL server is working properly. It also
describes how to secure the initial MySQL user accounts, @emph{which have no
passwords} until you assign passwords.  The section applies whether you
install MySQL using a binary or source distribution.

@item
If you want to run the MySQL benchmark scripts, Perl support for MySQL
must be available.
@xref{Perl support}.

@end enumerate


@node General Installation Issues, Quick Standard Installation, Installing, Installing
@section General Installation Issues

@c @node Methods of Installation, , ,
@c @subsection Methods of Installation

Before installing MySQL, you should do the following:

@enumerate
@item
Determine whether or not MySQL runs on your platform.

@item
Choose a distribution to install.

@item
Download the distribution and verify its integrity.

@end enumerate

This section contains the information necessary to carry out these steps.
After doing so, you can use the instructions in later sections of the chapter
to install the distribution that you choose.

@menu
* Which OS::                    Operating Systems Supported by MySQL
* Which version::               Choosing Which MySQL Distribution to Install
* Getting MySQL::               How to Get MySQL
* Verifying Package Integrity::   Verifying Package Integrity Using MD5 Checksums or @code{GnuPG}
* Installation layouts::        Installation Layouts
@end menu



@node Which OS, Which version, General Installation Issues, General Installation Issues
@subsection Operating Systems Supported by MySQL

@cindex operating systems, supported
@cindex native thread support
@cindex thread support
@cindex process support
@cindex support, for operating systems

This section lists the operating systems on which you can expect to be able to
run MySQL.

We use GNU Autoconf, so it is possible to port MySQL to all modern systems
that have a C++ compiler and a working implementation of POSIX threads.
(Thread support is needed for the server. To compile only the client code,
the only requirement is a C++ compiler.) We use and develop the software
ourselves primarily on Linux (SuSE and Red Hat), FreeBSD, and Sun Solaris
(Versions 8 and 9).

MySQL has been reported to compile successfully on the following
combinations of operating system and thread package.  Note that for many
operating systems, native thread support works only in the latest versions.

@itemize @bullet
@item
AIX 4.x, 5.x with native threads.  @xref{IBM-AIX}.
@item
Amiga.
@item
BSDI 2.x with the MIT-pthreads package.  @xref{BSDI}.
@item
BSDI 3.0, 3.1 and 4.x with native threads.  @xref{BSDI}.
@item
Digital Unix 4.x with native threads.  @xref{Alpha-DEC-UNIX}.
@item
FreeBSD 2.x with the MIT-pthreads package.  @xref{FreeBSD}.
@item
FreeBSD 3.x and 4.x with native threads.  @xref{FreeBSD}.
@item
FreeBSD 4.x with LinuxThreads.  @xref{FreeBSD}.
@item
HP-UX 10.20 with the DCE threads or the MIT-pthreads package.
@xref{HP-UX 10.20}.
@item
HP-UX 11.x with the native threads.  @xref{HP-UX 11.x}.
@item
Linux 2.0+ with LinuxThreads 0.7.1+ or @code{glibc} 2.0.7+ for various
CPU architectures.  @xref{Linux}.
@item
Mac OS X.  @xref{Mac OS X}.
@item
NetBSD 1.3/1.4 Intel and NetBSD 1.3 Alpha (requires GNU make).  @xref{NetBSD}.
@item
Novell NetWare 6.0.  @xref{NetWare installation}.
@item
OpenBSD > 2.5 with native threads. OpenBSD < 2.5 with the
MIT-pthreads package.  @xref{OpenBSD}.
@item
OS/2 Warp 3, FixPack 29 and OS/2 Warp 4, FixPack 4.  @xref{OS/2}.
@item
SCO OpenServer with a recent port of the FSU Pthreads package. 
@xref{SCO}.
@item
SCO UnixWare 7.1.x.  @xref{SCO UnixWare}.
@item
SGI Irix 6.x with native threads.  @xref{SGI-Irix}.
@item
Solaris 2.5 and above with native threads on SPARC and x86.  @xref{Solaris}.
@item
SunOS 4.x with the MIT-pthreads package.  @xref{Solaris}.
@item
Tru64 Unix.  @xref{Alpha-DEC-UNIX}.
@item
Windows 9x, Me, NT, 2000, XP, and 2003.  @xref{Windows installation}.
@end itemize

Not all platforms are equally well-suited for running
MySQL. How well a certain platform is suited for a high-load
mission-critical MySQL server is determined by the following
factors:

@itemize @bullet
@item
General stability of the thread library. A platform may have an excellent
reputation otherwise, but MySQL will be only as stable as the thread library
if that library is unstable in the code that is called by MySQL, even if
everything else is perfect.

@item
The capability of the kernel and the thread library to take advantage of
symmetric multi-processor (SMP) systems. In other words, when a process
creates a thread, it should be possible for that thread to run on a different
CPU than the original process.

@item
The capability of the kernel and the thread library to run many threads that
acquire and release a mutex over a short critical region frequently without
excessive context switches. If the implementation of
@code{pthread_mutex_lock()} is too anxious to yield CPU time, this will hurt
MySQL tremendously. If this issue is not taken care of, adding extra CPUs
will actually make MySQL slower.

@item
General filesystem stability and performance.

@item
If your tables are big, the ability of the filesystem to deal with large
files at all and to deal with them efficiently.

@item
Our level of expertise here at MySQL AB with the platform. If we know
a platform well, we enable platform-specific optimizations and fixes at
compile time. We can also provide advice on configuring your system optimally
for MySQL.

@item
The amount of testing we have done internally for similar configurations.

@item
The number of users that have successfully run MySQL on the
platform in similar configurations. If this number is high, the chances of
encountering platform-specific surprises are much smaller.
@end itemize

Based on the preceding criteria, the best platforms for running
MySQL at this point are x86 with SuSE Linux using a 2.4 kernel, and
ReiserFS (or any similar Linux distribution) and SPARC with Solaris
(2.7-9). FreeBSD comes third, but we really hope it will join the top
club once the thread library is improved. We also hope that at some
point we will be able to include into the top category all other platforms
on which MySQL currently compiles and runs okay, but not quite with the
same level of stability and performance.  This will require some
effort on our part in cooperation with the developers of the operating system
and library components that MySQL depends on. If you are interested in
improving one of those components, are in a position to influence its
development, and need more detailed instructions on what MySQL
needs to run better, send an email message to the MySQL @code{internals}
mailing list.
@xref{Mailing-list}.

Please note that the purpose of the preceding comparison is not to say that
one operating system is better or worse than another in general. We are
talking only about choosing an OS for the specific purpose of running MySQL.
With this in mind, the result of this comparison would be different if we
considered more factors. In some cases, the reason one OS is better than the
other could simply be that we have been able to put more effort into testing
and optimizing for a particular platform.  We are just stating our
observations to help you decide which platform to use for running MySQL.


@node Which version, Getting MySQL, Which OS, General Installation Issues
@subsection Choosing Which MySQL Distribution to Install

@c TODO: We need to define what a "release" is, i.e., when we assign a new
@c version number a produce distributions that users can grab and install.
@c Also, define "release series", and "distribution" (an installable package).
@c TODO: This needs to describe the Standard/Max/Pro/Classic breakdown
@c TODO: This needs to describe distribution formats as well
@c (.tar.gz, RPM, PKG, .msi)

When preparing to install MySQL, you should decide which version
to use.  MySQL development occurs in several release series, and
you can pick the one that best fits your needs.  After deciding
which version to install, you can choose a distribution format.
Releases are available in binary or source format.


@menu
* Choosing version::            Choosing Which Version of MySQL to Install
* Choosing distribution format::  Choosing a Distribution Format
* Many versions::               How and When Updates Are Released
* Release philosophy::          Release Philosophy---No Known Bugs in Releases
* MySQL binaries::              MySQL Binaries Compiled by MySQL AB
@end menu

@cindex MySQL binary distribution
@cindex MySQL source distribution
@cindex release numbers
@cindex version, choosing
@cindex choosing, a MySQL version

@node Choosing version, Choosing distribution format, Which version, Which version
@subsubsection Choosing Which Version of MySQL to Install

The first decision to make is whether you want to use a production (stable)
release or a development release.  In the MySQL development process,
multiple release series co-exist, each at a different stage of maturity:

@itemize @bullet

@item
MySQL 5.0 is the newest development release series and is under very active
development for new features. Alpha releases have been issued to allow more
widespread testing.

@item
MySQL 4.1 is the current stable (production-quality) release series.
New releases are issued for bugfixes. No new features are added
that could diminish the code stability.

@item
MySQL 4.0 is the previous stable (production-quality) release series.
New releases are issued for bugfixes. No new features are added
that could diminish the code stability.

@item
MySQL 3.23 is the old stable (production-quality) release series.
This series is retired, so new releases are issued only to fix
critical bugs.

@end itemize

We don't believe in a complete freeze, as this also leaves out bugfixes and
things that ``must be done.''  ``Somewhat frozen'' means that we may add
small things that ``almost surely will not affect anything that's already
working.'' Naturally, relevant bugfixes from an earlier series propagate to
later series.

Normally, if you are beginning to use MySQL for the first time or trying
to port it to some system for which there is no binary distribution, we
recommend going with the production release series. Currently this is MySQL
4.1.  All MySQL releases, even those from development series, are
checked with the MySQL benchmarks and an extensive test suite before being
issued.

If you are running an old system and want to upgrade, but
don't want to take the chance of having a non-seamless upgrade, you should
upgrade to the latest version in the same release series you are using (where
only the last part of the version number is newer than yours).  We have tried
to fix only fatal bugs and make small, relatively safe changes to that version.

If you want to use new features not present in the production release
series, you can use a version from a development series. Note that
development releases are not as stable as production releases.

If you want to use the very latest sources containing all current patches and
bugfixes, you can use one of our BitKeeper repositories.
These are not ``releases'' as such, but are available as previews of the
code on which future releases will be based.

@cindex naming, releases of MySQL
@cindex releases, naming scheme

The MySQL naming scheme uses release names that consist of three
numbers and a suffix; for example, @code{mysql-4.1.2-alpha}.
The numbers within the release name are interpreted like this:

@itemize @bullet
@item
The first number (@code{4}) is the major version and also describes the
file format.  All Version 4 releases have the same file format.

@item
The second number (@code{1}) is the release level.
Taken together, the major version and release level constitute the release
series number.

@item
The third number (@code{2}) is the version number within the
release series.  This is incremented for each new release.  Usually you
want the latest version for the series you have chosen.

@end itemize

For each minor update, the last number in the version string is incremented.
When there are major new features or minor incompatibilities with previous
versions, the second number in the version string is incremented.  When the
file format changes, the first number is increased.

Release names also include a suffix to indicates the stability level of the
release.  Releases within a series progress through a set of suffixes to
indicate how the stability level improves.
The possible suffixes are:

@itemize @bullet
@item
@code{alpha} indicates that the release contains some large section of
new code that hasn't been 100% tested.  Known bugs (usually there are none)
should be documented in the News section.  @xref{News}.  There are also new
commands and extensions in most alpha releases.  Active development that
may involve major code changes can occur in an alpha release, but everything
will be tested before issuing a release.  For this reason, there should be
no known bugs in any MySQL release.

@item
@code{beta} means that all new code has been tested.  No major new
features that could cause corruption in old code are added.  There should
be no known bugs.  A version changes from alpha to beta when there
haven't been any reported fatal bugs within an alpha version for at least
a month and we have no plans to add any features that could make any old
command unreliable.

@item
@code{gamma} is a beta that has been around a while and seems to work fine.
Only minor fixes are added.  This is what many other companies call a release.

@item
If there is no suffix, it means that the version has been run for a
while at many different sites with no reports of bugs other than
platform-specific bugs.  Only critical bugfixes are applied to the
release. This is what we call a production (stable) or `General Availability' (GA) release.
@end itemize

MySQL uses a naming scheme that is slightly different from most other products.
In general, it's relatively safe to use any version that has been out for
a couple of weeks without being replaced with a new version within the release
series.

All releases of MySQL are run through our standard tests and
benchmarks to ensure that they are relatively safe to use.  Because the
standard tests are extended over time to check for all previously found bugs,
the test suite keeps getting better.

@cindex releases, testing
@cindex testing, of MySQL releases

All releases have been tested at least with:

@table @asis

@c TODO: remove "virtually" when Cygwin becomes unnecessary for Windows
@item An internal test suite
The @file{mysql-test} directory contains an extensive set of test cases.
We run these tests for virtually every server binary.
See @ref{MySQL test suite} for more information about this test suite.

@item The MySQL benchmark suite
This suite runs a range of common queries.  It is also a test to see whether the
latest batch of optimizations actually made the code faster.
@xref{MySQL Benchmarks}.

@item The @code{crash-me} test
This test tries to determine what features the database supports and what its
capabilities and limitations are.  @xref{MySQL Benchmarks}.
@end table

Another test is that we use the newest MySQL version in our internal
production environment, on at least one machine.  We have more than 100GB
of data to work with.


@node Choosing distribution format, Many versions, Choosing version, Which version
@subsubsection Choosing a Distribution Format

After choosing which version of MySQL to install, you should decide
whether to use a binary distribution or a source distribution.  In
most cases, you should probably use a binary distribution, if one
exists for your platform. Binary distributions are available in native format
for many platforms, such as RPM files for Linux or DMG package installers for
Mac OS X. Distributions also are available as Zip archives or compressed
@command{tar} files. 

Reasons to choose a binary distribution include the following:

@itemize @bullet
@item
Binary distributions generally are easier to install than source distributions.

@c TODO: This makes a false characterization of max vs. non-max as
@c transactional vs. non-transactional.  Replace this with descriptions
@c of Standard/Max/Pro/Classic?

@item
To satisfy different user requirements, we provide two
different binary versions: one compiled with the non-transactional storage
engines (a small, fast binary), and one configured with the most
important extended options like transaction-safe tables.  Both versions
are compiled from the same source distribution.  All native MySQL
clients can connect to servers from either MySQL version.

The extended MySQL binary distribution is marked with the
@code{-max} suffix and is configured with the same options as
@command{mysqld-max}. @xref{mysqld-max, , @command{mysqld-max}}.

If you want to use the @code{MySQL-Max} RPM, you must first
install the standard @code{MySQL-server} RPM.

@end itemize

Under some circumstances, you probably will be better off installing MySQL
from a source distribution:

@itemize @bullet
@item
You want to install MySQL at some explicit location.  The standard
binary distributions are ``ready to run'' at any place, but you may want
to have even more flexibility to place MySQL components where you want.

@item
You want to configure @command{mysqld} with some extra features that are not
included in the standard binary distributions.  Here is a list of the most
common extra options that you may want to use:

@itemize @bullet
@item @code{--with-innodb} (default for MySQL 4.0 and up)
@item @code{--with-berkeley-db} (not available on all platforms)
@item @code{--with-raid}
@item @code{--with-libwrap}
@item @code{--with-named-z-libs} (this is done for some of the binaries)
@item @code{--with-debug[=@var{full}]}
@end itemize

@item
You want to configure @command{mysqld} without some features that are
included in the standard binary distributions. For example,
distributions normally are compiled with support for all character
sets. If you want a smaller MySQL server, you can recompile it with support
for only the character sets you need.

@item
You have a special compiler (such as @code{pgcc}) or want to use compiler
options that are better optimized for your processor.  Binary distributions
are compiled with options that should work on a variety of processors from
the same processor family.

@item
You want to use the latest sources from one of the BitKeeper
repositories to have access to all current bugfixes. For example,
if you have found a bug and reported it to the MySQL development
team, the bugfix will be committed to the source repository and you
can access it there.  The bugfix will not appear in a release until
a release actually is issued.

@item
You want to read (or modify) the C and C++ code that makes up MySQL. For
this purpose, you should get a source distribution, because the source code
is always the ultimate manual.

@item
Source distributions contain more tests and examples than binary
distributions.

@end itemize


@node Many versions, Release philosophy, Choosing distribution format, Which version
@subsubsection How and When Updates Are Released

@cindex releases, updating
@cindex updating, releases of MySQL

MySQL is evolving quite rapidly here at MySQL AB and we want to share
new developments with other MySQL users.  We try to make a release
when we have very useful features that others seem to have a need for.

We also try to help out users who request features that are easy to
implement.  We take note of what our licensed users want to have, and
we especially take note of what our support customers
want and try to help them out.

No one has to download a new release.  The News section will tell you if
the new release has something you really want.  @xref{News}.

We use the following policy when updating MySQL:

@itemize @bullet
@item
Releases are issued within each series. For each release, the last
number in the version is one more than the previous release within the same
series.

@item
Production (stable) releases are meant to appear about 1-2 times a year.
However, if small bugs are found, a release with only bugfixes will be issued.

@item
Working releases/bugfixes to old releases are meant to appear about
every 4-8 weeks.

@item
Binary distributions for some platforms are made by us for major releases.
Other people may make binary distributions for other systems, but probably
less frequently.

@item
We make fixes available as soon as we have identified and corrected
small or non-critical but annoying bugs. The fixes
are available immediately from our public BitKeeper repositories, and will
be included in the next release.

@item
If by any chance a fatal bug is found in a release, we will make a new
release as soon as possible.  (We would like other companies to do this,
too!)
@end itemize


@node Release philosophy, MySQL binaries, Many versions, Which version
@subsubsection Release Philosophy---No Known Bugs in Releases

We put a lot of time and effort into making our releases bug-free.
To our knowledge, we have not released a single MySQL version with any
@emph{known} ``fatal'' repeatable bugs.
(A ``fatal'' bug is something that crashes MySQL under normal usage,
produces incorrect answers for normal queries, or has a security problem.)

We have documented all open problems, bugs, and issues that are
dependent on design decisions.
@xref{Bugs}.

Our aim is to fix everything that is fixable without risk of
making a stable MySQL version less stable. In certain cases, this
means we can fix an issue in the development versions, but not
in the stable (production) version. Naturally, we document such
issues so that users are aware of them.

Here is a description of how our build process works:
@itemize @bullet
@item
We monitor bugs from our customer support list, the bugs database at
@uref{http://bugs.mysql.com/}, and the MySQL external mailing lists.
@item
All reported bugs for live versions are entered into the bugs database.
@item
When we fix a bug, we always try to make a test case for it and
include it into our test system to ensure that the bug will never
recur without being detected. (About 90% of all fixed bugs have a test case.)
@item
We create test cases for all new features we add to MySQL.
@item
Before we start to build a new MySQL release, we ensure that all
reported repeatable bugs for the MySQL version (3.23.x, 4.0.x, etc)
are fixed.  If something is impossible to fix (due to some internal
design decision in MySQL), we document this in the manual.
@xref{Bugs}.
@item
We do a build on all platforms for which we support binaries (15+
platforms) and run our test suite and benchmark suite on all of them.
@item
We will not publish a binary for a platform for which the test or benchmark
suite fails.  If the problem is due to a general error in the source, we fix
it and do the build plus tests on all systems again from scratch.
@item
The build and test process takes 2-3 days.  If we receive a report regarding
a fatal bug during this process (for example, one that causes
a core dump), we fix the problem and restart the build process.
@item
After publishing the binaries on @uref{http://dev.mysql.com/}, we send
out an announcement message to the @code{mysql} and @code{announce} mailing
lists.
@xref{Mailing-list}.
The announcement message contains a list
of all changes to the release and any known problems with the release.
The Known Problems section in the release notes has been needed
for only a handful of releases.
@item
To quickly give our users access to the latest MySQL features, we do
a new MySQL release every 4-8 weeks.
Source code snapshots are built daily and are available at
@uref{http://downloads.mysql.com/snapshots.php}.
@item
If, despite our best efforts, we get any bug reports after the release is done
that there was something critically wrong with the build on a specific
platform, we will fix it at once and build a new @code{'a'} release for that
platform. Thanks to our large user base, problems are found quickly.
@item
Our track record for making good releases is quite good.  In the last
150 releases, we had to do a new build for fewer than 10 releases. In three
of these cases, the bug was a faulty @code{glibc} library on one of our build
machines that took us a long time to track down.
@end itemize


@node MySQL binaries,  , Release philosophy, Which version
@subsubsection MySQL Binaries Compiled by MySQL AB

@cindex binary distributions

As a service of MySQL AB, we provide a set of binary distributions
of MySQL that are compiled on systems at our site or on systems where
supporters of MySQL kindly have given us access to their machines. 

In addition to the binaries provided in platform-specific package formats,
we offer binary distributions for a number of platforms in the form of
compressed @command{tar} files (@code{.tar.gz} files).
@xref{Quick Standard Installation}.

For Windows distributions, see @ref{Windows installation}.

These distributions are generated using the script
@code{Build-tools/Do-compile}, which compiles the source code and creates
the binary @code{tar.gz} archive using
@command{scripts/make_binary_distribution}.

These binaries are configured and built with the following compilers and
options. This information can also be obtained by looking at the variables
@code{COMP_ENV_INFO} and @code{CONFIGURE_LINE} inside the script
@command{bin/mysqlbug} of every binary @command{tar} file distribution.

The following binaries are built on MySQL AB development systems:

@table @asis

@item Linux 2.4.xx x86 with @command{gcc} 2.95.3:
@code{CFLAGS="-O2 -mcpu=pentiumpro" CXX=gcc CXXFLAGS="-O2 -mcpu=pentiumpro -felide-constructors" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --enable-assembler --disable-shared --with-client-ldflags=-all-static --with-mysqld-ldflags=-all-static}

@item Linux 2.4.x x86 with @command{icc} (Intel C++ Compiler 8.0):
@code{CC=icc CXX=icc CFLAGS="-O3 -unroll2 -ip -mp -no-gcc -restrict" CXXFLAGS="-O3 -unroll2 -ip -mp -no-gcc -restrict" ./configure --prefix=/usr/local/mysql --localstatedir=/usr/local/mysql/data --libexecdir=/usr/local/mysql/bin --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --enable-assembler --disable-shared --with-client-ldflags=-all-static --with-mysqld-ldflags=-all-static --with-embedded-server --with-innodb}

@item Linux 2.4.xx Intel Itanium 2 with @command{ecc} (Intel C++ Itanium Compiler 7.0):
@code{CC=ecc CFLAGS="-O2 -tpp2 -ip -nolib_inline" CXX=ecc CXXFLAGS="-O2 -tpp2 -ip -nolib_inline" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile}

@item Linux 2.4.xx Intel Itanium with @command{ecc} (Intel C++ Itanium Compiler 7.0):
@code{CC=ecc CFLAGS=-tpp1 CXX=ecc CXXFLAGS=-tpp1 ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile}

@item Linux 2.4.xx alpha with @code{ccc} (Compaq C V6.2-505 / Compaq C++ V6.3-006):
@code{CC=ccc CFLAGS="-fast -arch generic" CXX=cxx CXXFLAGS="-fast -arch generic -noexceptions -nortti" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared --disable-shared}

@item Linux 2.x.xx ppc with @command{gcc} 2.95.4:
@code{CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --localstatedir=/usr/local/mysql/data --libexecdir=/usr/local/mysql/bin --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile  --disable-shared --with-embedded-server --with-innodb}

@item Linux 2.4.xx s390 with @command{gcc} 2.95.3:
@code{CFLAGS="-O2" CXX=gcc CXXFLAGS="-O2 -felide-constructors" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --disable-shared --with-client-ldflags=-all-static --with-mysqld-ldflags=-all-static}

@item Linux 2.4.xx x86_64 (AMD64) with @command{gcc} 3.2.1:
@code{CXX=gcc ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile  --disable-shared}

@item Sun Solaris 8 x86 with @command{gcc} 3.2.3:
@code{CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --localstatedir=/usr/local/mysql/data --libexecdir=/usr/local/mysql/bin --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile  --disable-shared --with-innodb}

@item Sun Solaris 8 SPARC with @command{gcc} 3.2:
@code{CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --enable-assembler --with-named-z-libs=no --with-named-curses-libs=-lcurses --disable-shared}

@item Sun Solaris 8 SPARC 64-bit with @command{gcc} 3.2:
@code{CC=gcc CFLAGS="-O3 -m64 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -m64 -fno-omit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --with-named-z-libs=no --with-named-curses-libs=-lcurses --disable-shared}

@item Sun Solaris 9 SPARC with @command{gcc} 2.95.3:
@code{CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --enable-assembler --with-named-curses-libs=-lcurses --disable-shared}

@item Sun Solaris 9 SPARC with @code{cc-5.0} (Sun Forte 5.0):
@code{CC=cc-5.0 CXX=CC ASFLAGS="-xarch=v9" CFLAGS="-Xa -xstrconst -mt -D_FORTEC_ -xarch=v9" CXXFLAGS="-noex -mt -D_FORTEC_ -xarch=v9" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --enable-assembler --with-named-z-libs=no --enable-thread-safe-client --disable-shared}

@item IBM AIX 4.3.2 ppc with @command{gcc} 3.2.3:
@code{CFLAGS="-O2 -mcpu=powerpc -Wa,-many " CXX=gcc CXXFLAGS="-O2 -mcpu=powerpc -Wa,-many  -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --with-named-z-libs=no --disable-shared}

@item IBM AIX 4.3.3 ppc with @code{xlC_r} (IBM Visual Age C/C++ 6.0):
@code{CC=xlc_r CFLAGS="-ma -O2 -qstrict -qoptimize=2 -qmaxmem=8192" CXX=xlC_r CXXFLAGS ="-ma -O2 -qstrict -qoptimize=2 -qmaxmem=8192" ./configure --prefix=/usr/local/mysql --localstatedir=/usr/local/mysql/data --libexecdir=/usr/local/mysql/bin --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --with-named-z-libs=no --disable-shared --with-innodb}

@item IBM AIX 5.1.0 ppc with @command{gcc} 3.3:
@code{CFLAGS="-O2 -mcpu=powerpc -Wa,-many" CXX=gcc CXXFLAGS="-O2 -mcpu=powerpc -Wa,-many  -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --with-named-z-libs=no --disable-shared}

@item IBM AIX 5.2.0 ppc with @code{xlC_r} (IBM Visual Age C/C++ 6.0):
@code{CC=xlc_r CFLAGS="-ma -O2 -qstrict -qoptimize=2 -qmaxmem=8192" CXX=xlC_r CXXFLAGS="-ma -O2 -qstrict -qoptimize=2 -qmaxmem=8192" ./configure --prefix=/usr/local/mysql --localstatedir=/usr/local/mysql/data --libexecdir=/usr/local/mysql/bin --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --with-named-z-libs=no --disable-shared --with-embedded-server --with-innodb}

@item HP-UX 10.20 pa-risc1.1 with @command{gcc} 3.1:
@code{CFLAGS="-DHPUX -I/opt/dce/include -O3 -fPIC" CXX=gcc CXXFLAGS="-DHPUX -I/opt/dce /include -felide-constructors -fno-exceptions -fno-rtti -O3 -fPIC" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile  --with-pthread --with-named-thread-libs=-ldce --with-lib-ccflags=-fPIC --disable-shared}

@item HP-UX 11.00 pa-risc with @code{aCC} (HP ANSI C++ B3910B A.03.50):
@code{CC=cc CXX=aCC CFLAGS=+DAportable CXXFLAGS=+DAportable ./configure --prefix=/usr/local/mysql --localstatedir=/usr/local/mysql/data --libexecdir=/usr/local/mysql/bin --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --disable-shared --with-embedded-server --with-innodb}

@item HP-UX 11.11 pa-risc2.0 64bit with @code{aCC} (HP ANSI C++ B3910B A.03.33):
@code{CC=cc CXX=aCC CFLAGS=+DD64 CXXFLAGS=+DD64 ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --disable-shared}

@item HP-UX 11.11 pa-risc2.0 32bit with @code{aCC} (HP ANSI C++ B3910B A.03.33):
@code{CC=cc CXX=aCC CFLAGS="+DAportable" CXXFLAGS="+DAportable" ./configure --prefix=/usr/local/mysql --localstatedir=/usr/local/mysql/data --libexecdir=/usr/local/mysql/bin --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile  --disable-shared --with-innodb}

@item HP-UX 11.22 ia64 64bit with @code{aCC} (HP aC++/ANSI C B3910B A.05.50):
@code{CC=cc CXX=aCC CFLAGS="+DD64 +DSitanium2" CXXFLAGS="+DD64 +DSitanium2" ./configure --prefix=/usr/local/mysql --localstatedir=/usr/local/mysql/data --libexecdir=/usr/local/mysql/bin --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile  --disable-shared --with-embedded-server --with-innodb} 

@item Apple Mac OS X 10.2 powerpc with @command{gcc} 3.1:
@code{CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile  --disable-shared}

@item FreeBSD 4.7 i386 with @command{gcc} 2.95.4:
@code{CFLAGS=-DHAVE_BROKEN_REALPATH ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --enable-assembler --with-named-z-libs=not-used --disable-shared}

@item FreeBSD 4.7 i386 using LinuxThreads with @command{gcc} 2.95.4:
@code{CFLAGS="-DHAVE_BROKEN_REALPATH -D__USE_UNIX98 -D_REENTRANT -D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads" CXXFLAGS="-DHAVE_BROKEN_REALPATH -D__USE_UNIX98 -D_REENTRANT -D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads" ./configure --prefix=/usr/local/mysql --localstatedir=/usr/local/mysql/data --libexecdir=/usr/local/mysql/bin --enable-thread-safe-client --enable-local-infile --enable-assembler --with-named-thread-libs="-DHAVE_GLIBC2_STYLE_GETHOSTBYNAME_R -D_THREAD_SAFE -I /usr/local/include/pthread/linuxthreads -L/usr/local/lib -llthread -llgcc_r" --disable-shared --with-embedded-server --with-innodb}

@item QNX Neutrino 6.2.1 i386 with @command{gcc} 2.95.3qnx-nto 20010315:
@code{CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile  --disable-shared}

@end table

The following binaries are built on third-party systems kindly provided to
MySQL AB by other users. These are provided only as a courtesy; MySQL AB
does not have full control over these systems, so we can provide only
limited support for the binaries built on them.

@table @asis
@item SCO Unix 3.2v5.0.6 i386 with @command{gcc} 2.95.3:
@code{CFLAGS="-O3 -mpentium" LDFLAGS=-static CXX=gcc CXXFLAGS="-O3 -mpentium -felide-constructors" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --with-named-z-libs=no --enable-thread-safe-client --disable-shared}

@item SCO OpenUnix 8.0.0 i386 with @command{CC} 3.2:
@code{CC=cc CFLAGS="-O" CXX=CC ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --with-named-z-libs=no --enable-thread-safe-client --disable-shared}

@item Compaq Tru64 OSF/1 V5.1 732 alpha with @code{cc/cxx} (Compaq C V6.3-029i / DIGITAL C++ V6.1-027):
@code{CC="cc -pthread" CFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed -speculate all" CXX="cxx -pthread" CXXFLAGS="-O4 -ansi_alias -fast -inline speed -speculate all -noexceptions -nortti" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --with-named-thread-libs="-lpthread -lmach -lexc -lc" --disable-shared --with-mysqld-ldflags=-all-static}

@item SGI Irix 6.5 IP32 with @command{gcc} 3.0.1:
@code{CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile  --disable-shared}

@item FreeBSD/sparc64 5.0 with @command{gcc} 3.2.1:
@code{CFLAGS=-DHAVE_BROKEN_REALPATH ./configure --prefix=/usr/local/mysql --localstatedir=/usr/local/mysql/data --libexecdir=/usr/local/mysql/bin --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --disable-shared --with-innodb}
@end table

The following compile options have been used for binary packages that MySQL
AB provided in the past. These binaries no longer are being updated, but the
compile options are listed here for reference purposes.

@table @asis
@item Linux 2.2.xx SPARC with @command{egcs} 1.1.2:
@code{CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex --enable-thread-safe-client --enable-local-infile --enable-assembler --disable-shared}

@item Linux 2.2.x with x686 with @command{gcc} 2.95.2:
@code{CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --disable-shared --with-extra-charsets=complex}

@item SunOS 4.1.4 2 sun4c with @command{gcc} 2.7.2.1:
@code{CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors" ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-assembler}

@item SunOS 5.5.1 (and above) sun4u with @command{egcs} 1.0.3a or 2.90.27 or
@command{gcc} 2.95.2 and newer:
@code{CC=gcc CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-low-memory --with-extra-charsets=complex --enable-assembler}

@item SunOS 5.6 i86pc with @command{gcc} 2.8.1:
@code{CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-low-memory --with-extra-charsets=complex}

@item BSDI BSD/OS 3.1 i386 with @command{gcc} 2.7.2.1:
@code{CC=gcc CXX=gcc CXXFLAGS=-O ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex}

@item BSDI BSD/OS 2.1 i386 with @command{gcc} 2.7.2:
@code{CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex}

@item AIX 4.2 with @command{gcc} 2.7.2.2:
@code{CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex}
@end table

Anyone who has more optimal options for any of the preceding configurations
listed can always mail them to the MySQL @code{internals} mailing list.
@xref{Mailing-list}.

RPM distributions prior to MySQL 3.22 are user-contributed.
Beginning with MySQL 3.22, RPM distributions are generated by MySQL AB.

If you want to compile a debug version of MySQL, you should add
@code{--with-debug} or @code{--with-debug=full} to the preceding
@command{configure} commands and remove any @code{-fomit-frame-pointer} options.


@node Getting MySQL, Verifying Package Integrity, Which version, General Installation Issues
@subsection How to Get MySQL

@cindex downloading
@cindex MySQL version
@cindex version, latest
@cindex getting MySQL
@cindex mirror sites
@cindex URLs for downloading MySQL

Check the MySQL downloads page (@uref{http://dev.mysql.com/downloads/}) for
information about the current version and for downloading instructions.
For a complete up-to-date list of MySQL download mirror sites, see
@uref{http://dev.mysql.com/downloads/mirrors.html}.
There you will also find information about becoming a MySQL mirror
site and how to report a bad or out-of-date mirror.

Our main mirror is located at @uref{http://mirrors.sunsite.dk/mysql/}.


@node Verifying Package Integrity, Installation layouts, Getting MySQL, General Installation Issues
@subsection  Verifying Package Integrity Using MD5 Checksums or @code{GnuPG}

After you have downloaded the MySQL package that suits your needs and before
you attempt to install it, you should make sure that it is intact and has not
been tampered with. MySQL AB offers three means of integrity checking:

@itemize @bullet

@item
MD5 checksums

@item
Cryptographic signatures using @code{GnuPG}, the GNU Privacy Guard

@item
For RPM packages, the built-in RPM integrity verification mechanism

@end itemize

The following sections describe how to use these methods.

If you notice that the MD5 checksum or GPG signatures
do not match, first try to download the respective package one more time,
perhaps from another mirror site. If you repeatedly cannot successfully
verify the integrity of the package, please notify us about such incidents,
including the full package name and the download site you have been using,
at @email{webmaster@@mysql.com} or @email{build@@mysql.com}.
Do not report downloading problems using the bug-reporting system.

@menu
* Verifying MD5 Checksum::      Verifying the MD5 Checksum
* Checking GPG Signature::      Signature Checking Using @code{GnuPG}
* Checking RPM Signature::      Signature Checking Using @code{RPM}
@end menu

@node Verifying MD5 Checksum, Checking GPG Signature, Verifying Package Integrity, Verifying Package Integrity
@subsubsection Verifying the MD5 Checksum

After you have downloaded a MySQL package, you should make sure that its MD5
checksum matches the one provided on the MySQL download pages. Each package
has an individual checksum that you can verify with the following command,
where @code{package_name} is the name of the package you downloaded:

@example
shell> md5sum package_name
@end example

Example:
@example
shell> md5sum mysql-standard-4.0.17-pc-linux-i686.tar.gz
60f5fe969d61c8f82e4f7f62657e1f06  mysql-standard-4.0.17-pc-linux-i686.tar.gz
@end example

You should verify that the resulting checksum (the string of hexadecimal
digits) matches the one displayed on
the download page immediately below the respective package.

Note that not all operating systems support the @code{md5sum} command. On
some, it is simply called @code{md5} and others do not ship it at all. On
Linux, it is part of the @code{GNU Text Utilities} package, which is
available for a wide range of platforms. You can download the source code
from @uref{http://www.gnu.org/software/textutils/} as well. If you have
@code{OpenSSL} installed, you can also use the command @code{openssl md5
package_name} instead. A DOS/Windows implementation of the @code{md5}
command is available from @uref{http://www.fourmilab.ch/md5/}.


@node Checking GPG Signature, Checking RPM Signature, Verifying MD5 Checksum, Verifying Package Integrity
@subsubsection Signature Checking Using @code{GnuPG}

Another method of verifying the integrity and authenticity of a package
is to use cryptographic signatures. This is more reliable than using MD5
checksums, but requires more work.

Beginning with MySQL 4.0.10 (February 2003), MySQL AB started signing
downloadable packages with @code{GnuPG} (@code{GNU Privacy Guard}).
@code{GnuPG} is an Open Source alternative to the very well-known
@code{Pretty Good Privacy} (@code{PGP}) by Phil Zimmermann.
See @uref{http://www.gnupg.org/} for more information about @code{GnuPG}
and how to obtain and install it on your system. Most Linux distributions
already ship with @code{GnuPG} installed by default.  For more information
about @code{OpenPGP}, see @uref{http://www.openpgp.org/}.


@c Do not use @email with the key name, that comes out as <...> in
@c some output formats, which are not part of the key name.

To verify the signature for a specific package, you first need to obtain a
copy of MySQL AB's public GPG build key. You can download the key from
@uref{http://www.keyserver.net/}.  The key that you want to obtain is named
@code{build@@mysql.com}.  Alternatively, you can cut and paste the key
directly from the following text:

@example
Key ID:
pub  1024D/5072E1F5 2003-02-03
     MySQL Package signing key (www.mysql.com) <build@@mysql.com>
Fingerprint: A4A9 4068 76FC BD3C 4567  70C8 8C71 8D3B 5072 E1F5

Public Key (ASCII-armored):

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

mQGiBD4+owwRBAC14GIfUfCyEDSIePvEW3SAFUdJBtoQHH/nJKZyQT7h9bPlUWC3
RODjQReyCITRrdwyrKUGku2FmeVGwn2u2WmDMNABLnpprWPkBdCk96+OmSLN9brZ
fw2vOUgCmYv2hW0hyDHuvYlQA/BThQoADgj8AW6/0Lo7V1W9/8VuHP0gQwCgvzV3
BqOxRznNCRCRxAuAuVztHRcEAJooQK1+iSiunZMYD1WufeXfshc57S/+yeJkegNW
hxwR9pRWVArNYJdDRT+rf2RUe3vpquKNQU/hnEIUHJRQqYHo8gTxvxXNQc7fJYLV
K2HtkrPbP72vwsEKMYhhr0eKCbtLGfls9krjJ6sBgACyP/Vb7hiPwxh6rDZ7ITnE
kYpXBACmWpP8NJTkamEnPCia2ZoOHODANwpUkP43I7jsDmgtobZX9qnrAXw+uNDI
QJEXM6FSbi0LLtZciNlYsafwAPEOMDKpMqAK6IyisNtPvaLd8lH0bPAnWqcyefep
rv0sxxqUEMcM3o7wwgfN83POkDasDbs3pjwPhxvhz6//62zQJ7Q7TXlTUUwgUGFj
a2FnZSBzaWduaW5nIGtleSAod3d3Lm15c3FsLmNvbSkgPGJ1aWxkQG15c3FsLmNv
bT6IXQQTEQIAHQUCPj6jDAUJCWYBgAULBwoDBAMVAwIDFgIBAheAAAoJEIxxjTtQ
cuH1cY4AnilUwTXn8MatQOiG0a/bPxrvK/gCAJ4oinSNZRYTnblChwFaazt7PF3q
zIhMBBMRAgAMBQI+PqPRBYMJZgC7AAoJEElQ4SqycpHyJOEAn1mxHijft00bKXvu
cSo/pECUmppiAJ41M9MRVj5VcdH/KN/KjRtW6tHFPYhMBBMRAgAMBQI+QoIDBYMJ
YiKJAAoJELb1zU3GuiQ/lpEAoIhpp6BozKI8p6eaabzF5MlJH58pAKCu/ROofK8J
Eg2aLos+5zEYrB/LsrkCDQQ+PqMdEAgA7+GJfxbMdY4wslPnjH9rF4N2qfWsEN/l
xaZoJYc3a6M02WCnHl6ahT2/tBK2w1QI4YFteR47gCvtgb6O1JHffOo2HfLmRDRi
Rjd1DTCHqeyX7CHhcghj/dNRlW2Z0l5QFEcmV9U0Vhp3aFfWC4Ujfs3LU+hkAWzE
7zaD5cH9J7yv/6xuZVw411x0h4UqsTcWMu0iM1BzELqX1DY7LwoPEb/O9Rkbf4fm
Le11EzIaCa4PqARXQZc4dhSinMt6K3X4BrRsKTfozBu74F47D8Ilbf5vSYHbuE5p
/1oIDznkg/p8kW+3FxuWrycciqFTcNz215yyX39LXFnlLzKUb/F5GwADBQf+Lwqq
a8CGrRfsOAJxim63CHfty5mUc5rUSnTslGYEIOCR1BeQauyPZbPDsDD9MZ1ZaSaf
anFvwFG6Llx9xkU7tzq+vKLoWkm4u5xf3vn55VjnSd1aQ9eQnUcXiL4cnBGoTbOW
I39EcyzgslzBdC++MPjcQTcA7p6JUVsP6oAB3FQWg54tuUo0Ec8bsM8b3Ev42Lmu
QT5NdKHGwHsXTPtl0klk4bQk4OajHsiy1BMahpT27jWjJlMiJc+IWJ0mghkKHt92
6s/ymfdf5HkdQ1cyvsz5tryVI3Fx78XeSYfQvuuwqp2H139pXGEkg0n6KdUOetdZ
Whe70YGNPw1yjWJT1IhMBBgRAgAMBQI+PqMdBQkJZgGAAAoJEIxxjTtQcuH17p4A
n3r1QpVC9yhnW2cSAjq+kr72GX0eAJ4295kl6NxYEuFApmr1+0uUq/SlsQ==
=YJkx
-----END PGP PUBLIC KEY BLOCK-----
@end example

You can import the build key into your personal public GPG keyring by using
@code{gpg --import}. For example, if you save the key in a file named
@file{mysql_pubkey.asc}, the import command looks like this:

@example
shell> gpg --import mysql_pubkey.asc
@end example

See the GPG documentation for more information on how to work with public keys.

After you have downloaded and imported the public build key,
download your desired MySQL package and the corresponding
signature, which also is available from the download page.
The signature file has the same name as the distribution file with an
@file{.asc} extension. For example:

@multitable @columnfractions .30 .60
@item Distribution file @tab @code{mysql-standard-4.0.17-pc-linux-i686.tar.gz}
@item Signature file @tab @code{mysql-standard-4.0.17-pc-linux-i686.tar.gz.asc}
@end multitable

Make sure that both files are stored in the same directory and then run
the following command to verify the signature for the distribution file:

@example
shell> gpg --verify package_name.asc
@end example

Example:

@example
shell> gpg --verify mysql-standard-4.0.17-pc-linux-i686.tar.gz.asc
gpg: Warning: using insecure memory!
gpg: Signature made Mon 03 Feb 2003 08:50:39 PM MET
using DSA key ID 5072E1F5
gpg: Good signature from
     "MySQL Package signing key (www.mysql.com) <build@@mysql.com>"
@end example

The @code{Good signature} message indicates that everything is all right.
You can ignore the @code{insecure memory} warning.

@node Checking RPM Signature,  , Checking GPG Signature, Verifying Package Integrity
@subsubsection Signature Checking Using @code{RPM}

For RPM packages, there is no separate signature. RPM packages have a
built-in GPG signature and MD5 checksum. You can verify a package by running
the following command:

@example
shell> rpm --checksig package_name.rpm
@end example

Example:

@example
shell> rpm --checksig MySQL-server-4.0.10-0.i386.rpm
MySQL-server-4.0.10-0.i386.rpm: md5 gpg OK
@end example

@strong{Note}: If you are using RPM 4.1 and it complains about @code{(GPG)
NOT OK (MISSING KEYS: GPG#5072e1f5)}, even though you have imported the
MySQL public build key into your own GPG keyring, you need to import the
key into the RPM keyring first. RPM 4.1 no longer uses your personal GPG
keyring (or GPG itself). Rather, it maintains its own keyring because it is
a system-wide application and a user's GPG public keyring is a user-specific
file. To import the MySQL public key into the RPM keyring, first obtain the
key as described in the previous section. Then use @command{rpm --import}
to import the key.  For example, if you have the public key stored in a file
named @file{mysql_pubkey.asc}, import it using this command:

@example
shell> rpm --import mysql_pubkey.asc
@end example

If you need to obtain the MySQL public key, see @ref{Checking GPG Signature}.


@node Installation layouts,  , Verifying Package Integrity, General Installation Issues
@subsection Installation Layouts

@cindex installation layouts
@cindex layout of installation
@cindex directory structure, default
@cindex default installation location

This section describes the default layout of the directories created by
installing binary or source distributions provided by MySQL AB. If you
install a distribution provided by another vendor, some other layout might
be used.

On Windows, the default installation directory is @file{C:\mysql}. With MySQL version
4.1.5 and higher, this has changed to @file{C:\Program Files\MySQL\MySQL Server 4.1}, 
where 4.1 will be the major version of the installation. The folder has
the following subdirectories:

@multitable @columnfractions .35 .45
@item @strong{Directory} @tab @strong{Contents of Directory}
@item @file{bin}         @tab Client programs and the @command{mysqld} server
@item @file{data}        @tab Log files, databases
@item @file{Docs}        @tab Documentation
@item @file{examples}    @tab Example programs and scripts
@item @file{include}     @tab Include (header) files
@item @file{lib}         @tab Libraries
@item @file{scripts}     @tab Utility scripts
@item @file{share}       @tab Error message files
@end multitable

Installations created from Linux RPM distributions result in files under
the following system directories:

@multitable @columnfractions .35 .45
@item @strong{Directory}             @tab @strong{Contents of Directory}
@item @file{/usr/bin}                @tab Client programs and scripts
@item @file{/usr/sbin}               @tab The @command{mysqld} server
@item @file{/var/lib/mysql}          @tab Log files, databases
@item @file{/usr/share/doc/packages} @tab Documentation
@item @file{/usr/include/mysql}      @tab Include (header) files
@item @file{/usr/lib/mysql}          @tab Libraries
@item @file{/usr/share/mysql}        @tab Error message and character set files
@item @file{/usr/share/sql-bench}    @tab Benchmarks
@end multitable

On Unix, a @command{tar} file
binary distribution is installed by unpacking it at the installation
location you choose (typically @file{/usr/local/mysql}) and creates the
following directories in that location:

@multitable @columnfractions .35 .45
@item @strong{Directory} @tab @strong{Contents of Directory}
@item @file{bin}         @tab Client programs and the @command{mysqld} server
@item @file{data}        @tab Log files, databases
@item @file{docs}        @tab Documentation, ChangeLog
@item @file{include}     @tab Include (header) files
@item @file{lib}         @tab Libraries
@item @file{scripts}     @tab @command{mysql_install_db}
@item @file{share/mysql} @tab Error message files
@item @file{sql-bench}   @tab Benchmarks
@end multitable

A source distribution is installed after you configure and compile it.  By
default, the installation step installs files under @file{/usr/local}, in the
following subdirectories:

@multitable @columnfractions .35 .45
@item @strong{Directory} @tab @strong{Contents of Directory}
@item @file{bin}         @tab Client programs and scripts
@item @file{include/mysql}  @tab Include (header) files
@item @file{info}        @tab Documentation in Info format
@item @file{lib/mysql}   @tab Libraries
@item @file{libexec}     @tab The @command{mysqld} server
@item @file{share/mysql} @tab Error message files
@item @file{sql-bench}   @tab Benchmarks and @code{crash-me} test
@item @file{var}         @tab Databases and log files
@end multitable

Within an installation directory, the layout of a source installation differs
from that of a binary installation in the following ways:

@itemize @bullet
@item
The @command{mysqld} server is installed in the @file{libexec}
directory rather than in the @file{bin} directory.

@item
The data directory is @file{var} rather than @file{data}.

@item
@command{mysql_install_db} is installed in the @file{bin} directory
rather than in the @file{scripts} directory.

@item
The header file and library directories are @file{include/mysql} and
@file{lib/mysql} rather than @file{include} and @file{lib}.
@end itemize

You can create your own binary installation from a compiled source
distribution by executing the @file{scripts/make_binary_distribution} script
from the top directory of the source distribution.

@node Quick Standard Installation, Windows installation, General Installation Issues, Installing
@section Standard MySQL Installation Using a Binary Distribution

The next several sections cover the installation of MySQL on platforms where
we offer packages using the native packaging format of the respective
platform. (This is also known as performing a ``binary install.'') However,
binary distributions of MySQL are available for many other platforms as
well. See @ref{Installing binary} for generic installation instructions for
these packages that apply to all platforms.

See @ref{General Installation Issues} for more information on what other binary
distributions are available and how to obtain them.


@node Windows installation, Linux-RPM, Quick Standard Installation, Installing
@section Installing MySQL on Windows

@c TODO: The prompt is inconsistent in the Windows sections. Sometimes
@c begins with C:, sometimes it's shell>.

A native Windows version of MySQL has been available from MySQL AB since
version 3.21 and has grown in popularity until it now represents a sizable
percentage of the daily downloads of MySQL. This section describes the
process for installing MySQL on Windows.

With the release of MySQL 4.1.5, MySQL AB has introduced a new installer for
the Windows version of MySQL, combined with a new GUI Configuration Wizard.
This combination automatically installs MySQL, creates an option file,
starts the server, and secures the default user accounts.

If you have already installed a version of MySQL prior to version 4.1.5,
you must perform the following steps:

@enumerate
@item
Obtain and install the distribution.

@item
Set up an option file if necessary.

@item
Select the server that you want to use.

@item
Start the server.

@item
Assign passwords to the initial MySQL accounts.

@end enumerate

This process also must be followed with newer MySQL installations where the
installation package does not include an installer.

MySQL for Windows is available in two distribution formats:

@itemize @bullet

@item
The binary distribution contains a setup program that installs
everything you need so that you can start the server immediately.

@item
The source distribution contains all the code and support files
for building the executables using the VC++ 6.0 compiler.

@end itemize

Generally speaking, you should use the binary distribution. It's simpler, and
you need no additional tools to get MySQL up and running.

This section describes how to install MySQL on Windows using a binary
distribution.  To install using a source distribution, see
@ref{Windows source build}.

@menu
* Windows system requirements::  Windows System Requirements
* Windows choosing package::    Choosing An Installation Package
* Windows using installer::     Installing MySQL with the Automated Installer
* Windows install wizard::      Using the MySQL Installation Wizard
* Windows config wizard::       Using the Configuration Wizard
* Windows install archive::     Installing MySQL from a noinstall Zip Archive
* Windows extract archive::     Extracting the Install Archive
* Windows create option file::  Creating an Option File
* Windows select server::       Selecting a MySQL Server type
* Windows server first start::  Starting the Server for the First Time
* Windows start command line::  Starting MySQL from the Windows Command Line
* Windows start service::       Starting MySQL as a Windows Service
* Windows testing::             Testing The MySQL Installation
* Windows troubleshooting::     Troubleshooting a MySQL Installation Under Windows
* Windows upgrading::           Upgrading MySQL on Windows
* Windows vs Unix::             MySQL on Windows Compared to MySQL on Unix
@end menu

@node Windows system requirements, Windows choosing package, Windows installation, Windows installation
@subsection Windows System Requirements

To run MySQL on Windows, you need the following:

@itemize @bullet

@item
A 32-bit Windows operating system such as 9x, Me, NT, 2000, XP, or Windows
Server 2003.

A Windows NT based operating system (NT, 2000, XP, 2003)  permits you to run
the MySQL server as a service. The use of a Windows NT based operating
system is strongly recommended. @xref{Windows start service}.

@item
TCP/IP protocol support.

@item
A copy of the MySQL binary distribution for Windows, which
can be downloaded from @uref{http://dev.mysql.com/downloads/}.
@xref{Getting MySQL}.

Note: If you download the distribution via FTP, we recommend the use of an
adequate FTP client with a resume feature to avoid corruption of files
during the download process.

@item
A tool that can read @file{.zip} files, to unpack the distribution file.

@item
Enough space on the hard drive to unpack, install, and create the
databases in accordance with your requirements (generally a minimum of 200 megabytes is recommended.)

@end itemize

You may also have the following optional requirements:

@itemize @bullet

@item
If you plan to connect to the MySQL server via ODBC, you
also need a Connector/ODBC driver. @xref{ODBC Connector}.

@item
If you need tables with a size larger than 4GB, install MySQL
on an NTFS or newer filesystem. Don't forget to use @code{MAX_ROWS} and
@code{AVG_ROW_LENGTH} when you create tables.
@xref{CREATE TABLE, , @code{CREATE TABLE}}.

@end itemize

@node Windows choosing package, Windows using installer, Windows system requirements, Windows installation
@subsection Choosing An Installation Package

Starting with MySQL version 4.1.5, there are three install packages to choose from
when installing MySQL on Windows. The Packages are as follows:

@itemize @bullet
@item
@strong{The Essentials Package}: This package has a filename similar to
@file{mysql-4.1.7-essential-win.msi} and contains the minimum files needed 
to install MySQL on Windows, including the Configuration Wizard. This package does not include optional components such as
the embedded server and benchmark suite.

@item
@strong{The Complete Package}: This package has a filename similar to
@file{mysql-4.1.7-win.zip} and contains all files needed for a complete Windows 
installation, including the Configuration Wizard. This package includes optional components such as
the embedded server and benchmark suite.

@item
@strong{The Noinstall Archive}: This package has a filename similar to
@file{mysql-4.1.7-win-noinstall.zip} and contains all the files found in 
the Complete install package, with the exception of the Configuration Wizard. This
package does not include an automated installer, and must be manually installed and configured.

@end itemize

The Essentials package is recommended for most users.

Your choice of install package affects the installation process you must follow. 
If you choose to install either the Essentials or Complete install
packages, see @ref{Windows using installer}. If you choose to install
MySQL from the Noinstall archive, see @ref{Windows install archive}.

@node Windows using installer, Windows install wizard, Windows choosing package, Windows installation
@subsection Installing MySQL with the Automated Installer

Starting with MySQL 4.1.5, users can use the new MySQL Installation Wizard and 
MySQL Configuration Wizard to install MySQL on Windows. The MySQL Installation 
Wizard and MySQL Configuration Wizard are designed to install and configure 
MySQL in such a way that new users can immediately get started using MySQL. 

The MySQL Installation Wizard and MySQL Configuration Wizard are available
in the Essentials and Complete install packages, and are recommended for
most standard MySQL installations. Exceptions include users who need to
install multiple instances of MySQL on a single server and advanced users
who want complete control of server configuration.

If you are installing a version of MySQL prior to MySQL 4.1.5, please follow
the instructions for installing MySQL from the Noinstall installation
package. @xref{Windows install archive}.



@node Windows install wizard, Windows config wizard, Windows using installer, Windows installation
@subsection Using the MySQL Installation Wizard

@menu
* mysql-install-wizard-introduction::  Introduction
* mysql-install-wizard-starting::  Downloading and Starting the MySQL Installation Wizard
* mysql-install-wizard-install-type::  Choosing an Install Type
* mysql-install-wizard-custom-install::  The Custom Install Dialog
* mysql-install-wizard-confirmation-dialog::  The Confirmation Dialog
* mysql-install-wizard-changes::  Changes Made by MySQL Installation Wizard
* mysql-install-wizard-upgrading::  Upgrading MySQL
@end menu

@node mysql-install-wizard-introduction, mysql-install-wizard-starting, Windows install wizard, Windows install wizard
@subsubsection Introduction

MySQL Installation Wizard is a new installer for the MySQL server that uses
the latest installer technologies for Microsoft Windows. The MySQL
Installation Wizard, in combination with the MySQL Configuration Wizard,
allows a user to install and configure a MySQL server that is ready for use
immediately after installation.

The MySQL Installation Wizard is the standard installer for all MySQL server
distributions, version 4.1.5 and higher. Users of previous versions of MySQL
need to manually shut down and remove their existing MySQL installations
before installing MySQL with the MySQL Installation Wizard. See
@ref{mysql-install-wizard-upgrading} for more information on upgrading from
a previous version.

Microsoft has included an improved version of their Microsoft Windows
Installer (MSI) in the recent versions of Windows. Using the MSI has
become the de-facto standard for application installations on Windows
2000, Windows XP, and Windows Server 2003. The MySQL Installation Wizard makes
use of this technology to provide a smoother and more flexible
installation progress.

The Microsoft Windows Installer Engine was updated with the release
of Windows XP; those using a previous version of Windows can reference
@uref{http://support.microsoft.com/default.aspx?scid=kb;EN-US;292539,this
Microsoft Knowledge Base article} for information on upgrading
to the latest version of the Windows Installer Engine.

Further, Microsoft has introduced the WiX (Windows Installer XML)
tool set recently. It is the first highly acknowledged Open Source
project from Microsoft. We switched to WiX because it is an Open
Source project and it allows us to handle the complete Windows
installation process in a flexible way with scripts.

Improving the MySQL Installation Wizard depends on the support and feedback of
users like you. If you find that the MySQL Installation Wizard is lacking some
feature important to you, or if you discover a bug, please use our
@uref{http://bugs.mysql.com,MySQL Bug System} to
request features or report problems.


@c END INTRODUCTION


@c @node mysql-install-wizard-versions, mysql-install-wizard-starting, mysql-install-wizard-introduction, Windows install wizard
@c @subsubsection Choosing an Install Package
@c 
@c There are three different packages available that you can use to
@c install the MySQL server under Windows, each targeted at different
@c user requirements:
@c 
@c [MH] Looks like the GUI team will change these to Minimal and Full,
@c and will eventually drop the Zip archives around the .MSI installers.
@c Let's watch and change this when they do.
@c 
@c @itemize @bullet
@c 
@c @item
@c @code{mysql-@var{version}-win-noinstall.zip}:
@c This package is a simple Zip archive of all the files found in a
@c full installation. It must be manually extracted and configured to
@c be fully operational. If you are using this package, the rest of
@c this document will not apply to you.
@c 
@c @item
@c @code{mysql-@var{version}-win.zip}:
@c This package contains the MySQL Installation Wizard with all components of
@c MySQL and is intended for a full installation with all optional
@c packages. This is recommended for users who need additional
@c components such as the embedded server, benchmark suite, and
@c additional support scripts.
@c 
@c @item
@c @code{mysql-@var{version}-essential-win.msi}:
@c This package contains the MySQL Installation Wizard with the minimum
@c components required to install a working MySQL server, without any
@c optional packages. This is recommended for typical users who do not
@c need any optional packages such as the embedded server or the
@c benchmark suite. Omitted packages can be added later.
@c 
@c @end itemize
@c 
@c For most users, the
@c @code{mysql-@var{version}-essential-win.msi}
@c package is recommended because of its smaller size and decreased
@c download time.
@c 
@c END CHOOSE PACKAGES

@node mysql-install-wizard-starting, mysql-install-wizard-install-type, mysql-install-wizard-introduction, Windows install wizard
@subsubsection Downloading and Starting the MySQL Installation Wizard

The MySQL server install packages can be downloaded from
@uref{http://dev.mysql.com/downloads/,http://dev.mysql.com/downloads/}.
If the package you download is contained within a Zip archive, you
need to extract the archive first.

The process for starting the wizard depends on the contents of the
install package you download. If there is a
@code{setup.exe} file present, double-click it to start
the install process. If there is a @code{.msi} file
present, double-click it to start the install process.

@c END STARTING


@node mysql-install-wizard-install-type, mysql-install-wizard-custom-install, mysql-install-wizard-starting, Windows install wizard
@subsubsection Choosing an Install Type

There are up three installation types available:
@code{Typical}, @code{Complete}, and
@code{Custom}.

The @code{Typical} installation type installs the MySQL
server, the @code{mysql} command-line client, and the
command-line utilities. The command-line clients and utilities
include @code{mysqldump}, @code{myisamchk},
and several other tools to help you manage the MySQL server.

The @code{Complete} installation type installs all
components included in the installation package. The full
installation package includes components such as the embedded server
library, the benchmark suite, support scripts, and documentation.

The @code{Custom} installation type gives you complete
control over which packages you wish to install and the installation
path that will be used. See
@ref{mysql-install-wizard-custom-install}
for more information on performing a custom install.

If you choose the @code{Typical} or
@code{Complete} installation types and click the
Next button, you advance to the confirmation
screen to confirm your choices and begin the installation. If you
choose the @code{Custom} installation type and click the
Next button, you advance to the custom install
dialog, described in
@ref{mysql-install-wizard-custom-install}

@c END INSTALL TYPES


@node mysql-install-wizard-custom-install, mysql-install-wizard-confirmation-dialog, mysql-install-wizard-install-type, Windows install wizard
@subsubsection The Custom Install Dialog

If you wish to change the installation path or the specific
components that are installed by the MySQL Installation Wizard, you should
choose the @code{Custom} installation type.

All available components are listed in a tree view on the left side
of the custom install dialog. Components that will not be installed
have a red @code{X} icon, components that will be
installed have a gray icon. To change whether a component is
installed, click on the component's icon and choose an new option
from the drop-down list that appears.

You can change the default installation path by clicking the
Change... button to the right of the displayed
installation path.

After choosing your install components and installation path, click
the Next button to advance to the confirmation
dialog.

@c END CUSTOM INSTALL


@node mysql-install-wizard-confirmation-dialog, mysql-install-wizard-changes, mysql-install-wizard-custom-install, Windows install wizard
@subsubsection The Confirmation Dialog

Once you choose an installation type and optionally choose your
installation components, you advance to the confirmation dialog. Your
installation type and installation path are displayed for you to
review.

To install MySQL if you are satisfied with your settings, click the
Install button. To change your settings, click
the Back button. To exit the MySQL
Installation Wizard without installing MySQL, click the
Cancel button.

After installation is complete, you will be given the option of
registering with the MySQL web site. Registration will give you
access to post in the MySQL forums at
@uref{http://forums.mysql.com,forums.mysql.com}, along
with the ability to report bugs at
@uref{http://bugs.mysql.com,bugs.mysql.com} and
subscribe to the newsletter. The final screen of the installer
provides a summary of the installation and gives you the option to
launch the MySQL Configuration Wizard, which you can use to create a
configuration file, install the MySQL service, and configure
security.

@c END CONFIRMATION DIALOG


@node mysql-install-wizard-changes, mysql-install-wizard-upgrading, mysql-install-wizard-confirmation-dialog, Windows install wizard
@subsubsection Changes Made by MySQL Installation Wizard


Once you click the Install button, the
MySQL Installation Wizard begins the installation process and makes certain
changes to your system which are described in the sections that
follow.

@strong{Changes to the Registry}

The MySQL Installation Wizard creates one Windows registry key in a typical
install situation, located in
@code{HKEY_LOCAL_MACHINE\SOFTWARE\MySQL AB}.

The MySQL Installation Wizard creates a key named after the major version of
the server that is being installed, such as @code{MySQL Server
4.1}. It contains two string values,
@code{Location} and @code{Version}. The
@code{Location} string contains the path to the
installation directory. In a default installation it contains
@code{C:\Program Files\MySQL\MySQL Server 4.1\}. The
@code{Version} string contains the release number. For
example, for an installation of MySQL Server 4.1.5 the key contains
a value of @code{4.1.5}.

These registry keys are used to help external tools identify the
installed location of the MySQL server, preventing a complete scan
of the hard-disk to determine the installation path of the MySQL
server. The registry keys are not required to run the server and
when using the @code{noinstall} Zip archive the registry
keys are not created.

@c END REGISTRY

@strong{Changes to the Start Menu}

The MySQL Installation Wizard creates a new entry in the Windows Start menu
under a common MySQL menu heading named after the
major version of MySQL that you have installed. For example, if you
install MySQL 4.1, the MySQL Installation Wizard creates a MySQL
Server 4.1 section in the start menu.

The following entries are created within the new Start menu section:

@itemize @bullet

@item
@code{MySQL Command Line Client}: This is a shortcut to
the @code{mysql} command-line client and is configured
to connect as the root user. The shortcut prompts for a root user
password when connecting.

@item
@code{MySQL Server Instance Config Wizard}: This is a
shortcut to the MySQL Configuration Wizard. Use this shortcut to configure a
newly installed server, or to re-configure an existing server.

@item
@code{MySQL Documentation}: This is a link to the MySQL
server documentation that is stored locally in the MySQL server
installation directory. This option is not available when the MySQL
server is installed from the @code{essential}
installation package.

@end itemize

@c [MH] Once again, if the package names change update this!

@c END START MENU

@strong{Changes to the File System}

The MySQL Installation Wizard by default installs the MySQL server to
@code{C:\@var{Program Files}\MySQL\MySQL
Server @var{4.1}}, where
@var{Program Files} is the default location for
applications in your system, and @var{4.1} is
the major version of your MySQL server. This is the new recommended
location for the MySQL server, replacing the previous default
location of @file{c:\mysql}.

By default, all MySQL applications are stored in a common directory
at @code{C:\@var{Program
Files}\MySQL}, where @var{Program
Files} is the default location for applications in your
Windows installation. A typical MySQL installation on a developer
machine may look like this:

@example
C:\Program Files\MySQL\MySQL Server 4.1
C:\Program Files\MySQL\MySQL Server 5.0
C:\Program Files\MySQL\MySQL Administrator 1.0
C:\Program Files\MySQL\MySQL Query Browser 1.0
@end example

This approach makes it easier to manage and maintain all MySQL
applications installed on a particular system.

@c END FILE SYSTEM CHANGES

@c END CHANGES


@node mysql-install-wizard-upgrading,  , mysql-install-wizard-changes, Windows install wizard
@subsubsection Upgrading MySQL

From MySQL version 4.1.5, the new MySQL Installation Wizard can perform server
upgrades automatically using the upgrade capabilities of MSI. That
means you do not need to remove a previous installation manually
before installing a new release. The installer automatically shuts
down and removes the previous MySQL service before installing the new
version.

Automatic upgrades are only available when upgrading between
installations that have the same major and minor version numbers. For
example, you can upgrade automatically from MySQL 4.1.5 to MySQL
4.1.6, but not from MySQL 4.1 to MySQL 5.0.

@emph{If you are upgrading MySQL version 4.1.4 or earlier to
version 4.1.5 or later, you must first manually shut down and remove
the older installation before upgrading. Be sure to back up your
databases before performing such an upgrade, so that you can restore
the databases after the upgrade is completed. @emph{It is always
recommended that you back up your data before performing any
upgrades}.}

@xref{Windows upgrading}.

@c END UPGRADING


@node Windows config wizard, Windows install archive, Windows install wizard, Windows installation
@subsection Using the Configuration Wizard


@menu
* mysql-config-wizard-introduction::  Introduction
* mysql-config-wizard-starting::  Starting the MySQL Configuration Wizard
* mysql-config-wizard-maintenance::  Choosing a Maintenance Option
* mysql-config-wizard-configuration-type::  Choosing a Configuration Type
* mysql-config-wizard-server-type::  The Server Type Dialog
* mysql-config-wizard-database-usage::  The Database Usage Dialog
* mysql-config-wizard-tablespace::  The InnoDB Tablespace Dialog
* mysql-config-wizard-connections::  The Concurrent Connections Dialog
* mysql-config-wizard-networking::  The Networking Options Dialog
* mysql-config-wizard-character-set::  The Character Set Dialog
* mysql-config-wizard-service::  The Service Options Dialog
* mysql-config-wizard-security::  The Security Options Dialog
* mysql-config-wizard-confirmation::  The Confirmation Dialog
* mysql-config-wizard-file-location::  The Location of the my.ini File
* mysql-config-wizard-editing::  Editing The my.ini File
@end menu


@node mysql-config-wizard-introduction, mysql-config-wizard-starting, Windows config wizard, Windows config wizard
@subsubsection Introduction

The MySQL Configuration Wizard helps automate the processs of configuring your
server under Windows. The MySQL Configuration Wizard creates a custom
@file{my.ini} file by asking you a series of questions
and then applying your responses to a template to generate a
@file{my.ini} file that is tuned to your installation.

The MySQL Configuration Wizard is included with the MySQL server starting with
MySQL version 4.1.5, but is designed to work with MySQL servers
versions 4.0 and higher. The MySQL Configuration Wizard is currently available
for Windows users only.

MySQL Configuration Wizard is to a large extent the result of feedback MySQL AB
has received from many users over a period of several years. However,
if you find it's lacking some feature important to you, or if you
discover a bug, please use our
@uref{http://bugs.mysql.com,MySQL Bug System} to
request features or report problems.

@c END INTRODUCTION


@node mysql-config-wizard-starting, mysql-config-wizard-maintenance, mysql-config-wizard-introduction, Windows config wizard
@subsubsection Starting the MySQL Configuration Wizard

The MySQL Configuration Wizard is typically launched from the MySQL Installation Wizard,
as the MySQL Installation Wizard exits. You can also launch the
MySQL Configuration Wizard by clicking the MySQL Server Instance Config
Wizard entry in the MySQL section of the
@code{Start} menu.

In addition, you can navigate to the @code{bin} directory
of your MySQL installation and launch the
@file{MySQLInstanceConfig.exe} file directly.

@c END STARTING


@node mysql-config-wizard-maintenance, mysql-config-wizard-configuration-type, mysql-config-wizard-starting, Windows config wizard
@subsubsection Choosing a Maintenance Option

If the MySQL Configuration Wizard detects an existing
@file{my.ini} file, you will have the option of either
re-configuring your existing server, or removing the server instance
by deleting the @file{my.ini} file and stopping and
removing the MySQL service.

To reconfigure an existing server, choose the @code{Re-configure
Instance} option and click the Next
button. Your existing @file{my.ini} file will be
renamed to @code{my
@var{timestamp}.ini.bak}, where
@var{timestamp} is the date and time the
existing @file{my.ini} file was created. To remove the
existing server instance, choose the @code{Remove
Instance} option and click the Next
button.

If you choose the @code{Remove Instance} option, you
advance to a confirmation window. Click the
Execute button and the MySQL Configuration Wizard will
stop and remove the MySQL service and delete the
@file{my.ini} file. The server installation and its
@code{data} folder will not be removed.

If you choose the @code{Re-configure Instance} option,
you advance to the @code{Configuration Type} dialog where
you can choose the type of installation you wish to configure.

@c END MAINTENANCE


@node mysql-config-wizard-configuration-type, mysql-config-wizard-server-type, mysql-config-wizard-maintenance, Windows config wizard
@subsubsection Choosing a Configuration Type

When you start the MySQL Configuration Wizard for a new MySQL installation, or
choose the @code{Re-configure Instance} option for an
existing installation, you advance to the @code{Configuration
Type} dialog.

There are two configuration types available: @code{Detailed
Configuration} and @code{Standard
Configuration}. The @code{Standard
Configuration} option is intended for new users who want to
get started with MySQL quickly without having to make a lot of
decisions in regards to server configuration. The @code{Detailed
Configuration} option is intended for advanced users who
want more fine-grained control of server configuration.

If you are new to MySQL and need a server configured as a
single-user developer machine the @code{Standard
Configuration} will suit your needs. Choosing the
@code{Standard Configuration} option causes the
MySQL Configuration Wizard to automatically set all configuration options with
the exception of the @code{Service Options} and
@code{Security Options}.


The @code{Standard Configuration} sets options that may
be incompatible with systems where there are existing MySQL
installations. If you have an existing MySQL installation on your
system in addition to the installation you wish to configure, the
@code{Detailed Configuration} option is recommended.

To complete the @code{Standard Configuration}, please refer to the sections
on @code{Service Options} and @code{Security Options}, located at
@ref{mysql-config-wizard-service} and @ref{mysql-config-wizard-security}
respectively.

@c END STANDARD CONFIGURATION

@c END CHOOSING TYPE


@node mysql-config-wizard-server-type, mysql-config-wizard-database-usage, mysql-config-wizard-configuration-type, Windows config wizard
@subsubsection The Server Type Dialog

There are three different server types available to choose from, and
the server type you choose will affect the decisions the
MySQL Configuration Wizard makes with regards to memory, disk, and processor
usage.

@itemize @bullet

@item
@code{Developer Machine}: Choose this option for a
typical desktop workstation where MySQL is intended only for
personal use. It is assumed that many other desktop applications
will be running. The MySQL server will be configured to use minimal
system resources.

@item
@code{Server Machine}: Choose this option for a server
machine where the MySQL server will be running alongside other
server applications such as FTP, email, and web servers. The MySQL
server will be configured to use a medium portion of the system
resources.

@item
@code{Dedicated MySQL Server Machine}: Choose this
option for a server machine that is intended to run only the MySQL
server. It is assumed that no other applications will be running.
The MySQL server will be configured to use all available system
resources.

@end itemize

@c END SERVER TYPE


@node mysql-config-wizard-database-usage, mysql-config-wizard-tablespace, mysql-config-wizard-server-type, Windows config wizard
@subsubsection The Database Usage Dialog

The @code{Database Usage} dialog allows you to indicate
the table handlers you expect to use when creating MySQL tables. The
option you choose will determine whether the InnoDB table handler is
available and what percentage of the server resources are available
to InnoDB.

@itemize @bullet

@item
@code{Multifunctional Database}: This option enables
both the InnoDB and MyISAM table handlers and divides resources
evenly between the two. This option is recommended for users that
will use both table handlers on a regular basis.

@item
@code{Transactional Database Only}: This option enables
both the InnoDB and MyISAM table handlers but dedicates most server
resources toward the InnoDB table handler. This option is
recommended for users that will use InnoDB almost exclusively and
will make only minimal use of MyISAM.

@item
@code{Non-Transactional Database Only}: This option
disables the InnoDB table handler completely and dedicates all
server resources to the MyISAM table handler. This option is
recommended for users who will not be using InnoDB.

@end itemize

@c END DATABASE USAGE


@node mysql-config-wizard-tablespace, mysql-config-wizard-connections, mysql-config-wizard-database-usage, Windows config wizard
@subsubsection The InnoDB Tablespace Dialog

Some users may want to locate the InnoDB tablespace files in a
different location than the MySQL server data directory. Placing the
tablespace files in a seperate location can be desireable if your
system has a higher capacity or higher performance storage device
available, such as a RAID storage system.

To change the default location for the InnoDB tablespace files,
choose a new drive from the drop-down list of drive letters and
choose a new path from the drop-down list of paths. To create a
custom path, click the ... button.

If you are modifying the configuration of an existing server, you
must click the Modify button before you change
the path. In this situation you will have to manually move the
existing tablespace files to the new location before starting the
server.

@c END TABLESPACE DIALOG


@node mysql-config-wizard-connections, mysql-config-wizard-networking, mysql-config-wizard-tablespace, Windows config wizard
@subsubsection The Concurrent Connections Dialog

It is important to set a limit to the number of concurrent
connections to the MySQL server that can be established to prevent
the server from running out of resources. The @code{Concurrent
Connections} dialog allows you to choose the expected usage
of your server, and will set the limit for concurrent connections
accordingly. It is also possible to manually set the concurrent
connection limit.

@itemize @bullet

@item
@code{Decision Support (DSS)/OLAP}: Choose this option
if your server will not require a large number of concurrent
connections. The maximum number of connections will be set at 100.

@item
@code{Online Transaction Processing (OLTP)}: Choose this
option if your server will require a large number of concurrent
connections. The maximum number of connections will be set at 500.

@item
@code{Manual Setting}: Choose this option to manually
set the maximum number of concurrent connections to the server.
Choose the number of concurrent connections from the drop-down box
provided, or type the maximum number of connections into the
drop-down box if the number you desire is not listed.

@end itemize

@c END CONCURRENT CONNECTIONS


@node mysql-config-wizard-networking, mysql-config-wizard-character-set, mysql-config-wizard-connections, Windows config wizard
@subsubsection The Networking Options Dialog

Use the @code{Networking Options} dialog to enable or
disable TCP/IP networking and to configure the port number that is
used to connect to the MySQL server.

TCP/IP networking is enabled by default. To disable TCP/IP
networking, uncheck the box next to the @code{Enable TCP/IP
Networking} option.

Port 3306 is used by default. To change the port used to access
MySQL, choose a new port number from the drop-down box or type a new
port number directly into the drop-down box. If the port number you
choose is already in use you will be prompted to confirm your choice
of port number.

@c END NETWORKING OPTIONS


@node mysql-config-wizard-character-set, mysql-config-wizard-service, mysql-config-wizard-networking, Windows config wizard
@subsubsection The Character Set Dialog

The MySQL server supports multiple character sets and it is possible
to set a default server character set that will be applied to all
tables, columns, and databases unless overridden. Use the
@code{Character Set} dialog to change the default
character set of the MySQL server.

@itemize @bullet

@item
@code{Standard Character Set}: Choose this option if you
want to use @code{Latin1} as the default server
character set. @code{Latin1} is used for English and
many Western European languages.

@item
@code{Best Support For Multilingualism}: Choose this
option if you want to use @code{UTF8} as the default
server character set. @code{UTF8} can store characters
from many different languages in a single character set.

@item
@code{Manual Selected Default Character Set /
Collation}: Choose this option if you want to pick the
server's default character set manually. Choose the desired
character set from the provided drop-down list.

@end itemize

@c END CHARACTER SET


@node mysql-config-wizard-service, mysql-config-wizard-security, mysql-config-wizard-character-set, Windows config wizard
@subsubsection The Service Options Dialog

On Windows NT based platforms, the MySQL server can be installed as a
service. When installed as a service, the MySQL server can be started
automatically during system startup, and even restarted automatically
by Windows in the event of a service failure.

The MySQL Configuration Wizard will install the MySQL server as a service by
default, using the service name @code{MySQL}. If you do
not wish to install the service, un-check the box next to the
@code{Install As Windows Service} option. You can changed
the service name by picking a new service name from the drop-down box
provided or by typing a new service name into the drop-down box.

To install the MySQL server as a service but not have it started
automatically at startup, un-check the box next to the
@code{Launch the MySQL Server automatically} option.

@c END SERVICE OPTIONS


@node mysql-config-wizard-security, mysql-config-wizard-confirmation, mysql-config-wizard-service, Windows config wizard
@subsubsection The Security Options Dialog

It is strongly recommended that you set a root password for your
MySQL server, and the MySQL Configuration Wizard requires you set a root
password by default. If you do not wish to set a root password,
un-check the box next to the @code{Modify Security
Settings} option.

To set the root password, type the desired password into both the
@code{New root password} and @code{Confirm}
boxes. If you are re-configuring an existing server, you will also
need to enter the existing root password into the @code{Current
root password} box.

To prevent root logins from across the network, check the box next to
the @code{Root may only connect from localhost} option.
This will increase the security of your root account.

To create an anonymous user account, check the box next to the
@code{Create An Anonymous Account} option. Creating an
anonymous account can decrease server security and cause login and
permission difficulties and is not recommended.

@c END SECURITY OPTIONS


@node mysql-config-wizard-confirmation, mysql-config-wizard-file-location, mysql-config-wizard-security, Windows config wizard
@subsubsection The Confirmation Dialog

The final dialog in the MySQL Configuration Wizard is the @code{Confirmation
Dialog}. To start the configuration process, click the
Execute button. To return to a previous
dialog, click the Back button. To exit the
MySQL Configuration Wizard without configuring the server, click the
Cancel button.

After you click the Execute button, the
MySQL Configuration Wizard will perform a series of tasks with progress
displayed onscreen as the tasks are performed.

The MySQL Configuration Wizard will first determine various configuration file
options based on your choices using a template prepared by MySQL AB
developers and engineers. This template is named
@file{my-template.ini} and is located in your server
installation directory.

The MySQL Configuration Wizard will then write these options to a
@file{my.ini} file. The final location of the
@file{my.ini} file will be displayed next to the
@code{Write configuration file} task.

If you chose to create a service for the MySQL server the
MySQL Configuration Wizard will create the service and start it. If you are
re-configuring an existing service, the MySQL Configuration Wizard will restart
the service to apply your configuration changes.

If you chose to set a root password the MySQL Configuration Wizard will connect
to the server and set your new root password and apply any other
security setting you may have selected.

After the MySQL Configuration Wizard has completed its tasks, a summary will be
shown. Click the Finish button to exit the
MySQL Configuration Wizard.

@c END CONFIRMATION DIALOG


@node mysql-config-wizard-file-location, mysql-config-wizard-editing, mysql-config-wizard-confirmation, Windows config wizard
@subsubsection The Location of the my.ini File

In MySQL installations prior to version 4.1.5 it was customary to
name the server configuration file @file{my.cnf} or
@file{my.ini} and locate the file either at
@file{c:\my.cnf} or @file{c:\Windows\my.ini}.

The new MySQL Configuration Wizard places the @file{my.ini} file
in the installation directory of the MySQL server. This helps
associate configuration files with particular server instances.

To ensure that the MySQL server knows where to look for the
@file{my.ini} file, an argument similar to this is
passed to the MySQL server as part of the service installation:
@code{--defaults-file="@var{C:\Program Files\MySQL\MySQL
Server 4.1}\my.ini"}, where
@var{C:\Program Files\MySQL\MySQL Server 4.1} is
replaced with the installation path to the MySQL Server.

The @code{--defaults-file} instructs the MySQL server to
read the specified file for configuration options.

@c END INI FILE LOCTAION


@node mysql-config-wizard-editing,  , mysql-config-wizard-file-location, Windows config wizard
@subsubsection Editing The my.ini File

To modify the @file{my.ini} file, open it with a text
editor and make any necessary changes. You can also modify the server
configuration with the
@uref{http://www.mysql.com/products/administrator/,MySQL
Administrator} utility.

MySQL clients and utilities such as the @code{mysql}
command-line client and @code{mysqldump} will not locate
the @file{my.ini} file located in the server
installation directory. To configure the client and utility
applications, create a new @file{my.ini} file in the
@file{c:\Windows} directory.

@node Windows install archive, Windows extract archive, Windows config wizard, Windows installation
@subsection Installing MySQL from a noinstall Zip Archive

@c This is a new section, the next few sections will once again be subsections.

Users who are installing from the Noinstall package, or who are installing a
version of MySQL prior to 4.1.5 can use the instructions in this section to
manually install MySQL. If you are installing a version prior to 4.1.5 with
an install package that includes a Setup program, substitute running the
Setup program for extracting the archive.

The process for installing MySQL from a Zip archive is as follows:

@enumerate
@item
Extract the archive to the desired install directory.

@item
Create an option file.

@item
Choose a MySQL server type.

@item
Start the MySQL server.

@item
Secure the default user accounts.

@end enumerate

This process is described in the sections that follow.

@node Windows extract archive, Windows create option file, Windows install archive, Windows installation
@subsection Extracting the Install Archive

To install MySQL manually, do the following:

@enumerate
@item
If you are upgrading from a previous version please refer to @ref{Windows
upgrading} before beginning the upgrade process.

@item
If you are using a Windows NT-based operating system such as Windows NT,
Windows 2000, Windows XP, or Windows Server 2003, make sure that you are
logged in as a user with administrator privileges.

@item
Choose an installation location. Traditionally the MySQL server is installed at
@file{C:\mysql}, and the new MySQL Installation Wizard installs MySQL to
@file{C:\Program Files\MySQL}. If you do not install MySQL at @file{C:\mysql},
you must specify the
path to the install directory during startup or in an option file.
@xref{Windows create option file}.

@item
Extract the install archive to the chosen installation location using your
preferred Zip archive tool. Some tools may extract the archive to a folder
within your chosen installation location. If this occurs you can move the
contents of the subfolder into the chosen installation location.

@end enumerate


@node Windows create option file, Windows select server, Windows extract archive, Windows installation
@subsection Creating an Option File

If you need to specify startup options when you run the server, you can
indicate them on the command line or place them in an option file. For
options that will be used every time the server starts, you will find it
most convenient to use an option file to specify your MySQL configuration.
This is true particularly under the following circumstances:

@itemize @bullet

@item
The installation or data directory locations are different from the default
locations (@file{C:\mysql} and @file{C:\mysql\data}).

@item
You need to tune the server settings.  For example, to use the @code{InnoDB}
transactional tables in MySQL 3.23, you must manually add some extra lines
to the option file, as described in @ref{InnoDB configuration, ,
@code{InnoDB} configuration}.  (As of MySQL 4.0, @code{InnoDB} creates its
data files and log files in the data directory by default. This means you
need not configure @code{InnoDB} explicitly.  You may still do so if you
wish, and an option file will be useful in this case, too.)

@end itemize

When the MySQL server starts on Windows, it looks for options in
two files:  the @file{my.ini} file in the Windows directory, and
the @file{C:\my.cnf} file.  The Windows directory typically is
named something like @file{C:\WINDOWS} or @file{C:\WinNT}.  You
can determine its exact location from the value of the @code{WINDIR}
environment variable using the following command:

@example
C:\> echo %WINDIR%
@end example

MySQL looks for options first in the @file{my.ini} file, then in
the @file{my.cnf} file.  However, to avoid confusion, it's best if
you use only one file.  If your PC uses a boot loader where the
@code{C:} drive isn't the boot drive, your only option is to use
the @file{my.ini} file.  Whichever option file you use, it must be a plain
text file.

You can also make use of the example option files included with your MySQL
distribution.  Look in your install directory for files such as
my-small.cnf, my-medium.cnf, my-large.cnf, etc., which you can rename and
copy to the appropriate location for use as a base configuration file.

An option file can be created and modified with any text editor,
such as the @code{Notepad} program.  For example, if MySQL is
installed at @file{E:\mysql} and the data directory is located at
@file{E:\mydata\data}, you can create the option file and set up
a @code{[mysqld]} section to specify values for the @code{basedir}
and @code{datadir} parameters:

@example
[mysqld]
# set basedir to your installation path
basedir=E:/mysql
# set datadir to the location of your data directory
datadir=E:/mydata/data
@end example

Note that Windows pathnames are specified in option files using
forward slashes rather than backslashes.  If you do use backslashes,
you must double them:

@example
[mysqld]
# set basedir to your installation path
basedir=E:\\mysql
# set datadir to the location of your data directory
datadir=E:\\mydata\\data
@end example

On Windows, the MySQL installer places the data directory directly under the
directory where you install MySQL.  If you would like to use a data
directory in a different location, you should copy the entire contents of
the @file{data} directory to the new location. For example, by default, the
installer places MySQL in @file{C:\mysql} and the data directory in
@file{C:\mysql\data}. If you want to use a data directory of
@file{E:\mydata}, you must do two things:

@itemize @bullet
@item
Move the data directory from @file{C:\mysql\data} to @file{E:\mydata}.

@item
Use a @code{--datadir} option to specify the new data directory location
each time you start the server.

@end itemize

@node Windows select server, Windows server first start, Windows create option file, Windows installation
@subsection Selecting a MySQL Server type

@c [MH] HOW LONG DO WE WANT TO SUPPORT DOCUMENTING THE INSTALLATION OF 
@c A DEPRECATED VERSION? CAN WE ASSSUME THAT WHEN OLDER VERSIONS ARE NO 
@c DOWNLOADABLE WE DROP THIS?

Starting with MySQL 3.23.38, the Windows distribution includes
both the normal and the MySQL-Max server binaries.

Up through the early releases of MySQL 4.1, the servers included
in Windows distributions are named like this:

@multitable @columnfractions .20 .80
@item @strong{Binary} @tab @strong{Description}
@item @command{mysqld} @tab Compiled with full debugging and automatic memory allocation checking, symbolic links, and @code{InnoDB} and @code{BDB} tables.
@item @command{mysqld-opt} @tab Optimized binary.  From version 4.0 on, @code{InnoDB} is enabled.  Before 4.0, this server includes no transactional table support.
@item @command{mysqld-nt} @tab Optimized binary for Windows NT, 2000, and XP with support for named pipes.
@item @command{mysqld-max} @tab Optimized binary with support for symbolic links, and @code{InnoDB} and @code{BDB} tables.
@item @command{mysqld-max-nt} @tab Like @command{mysqld-max}, but compiled with support for named pipes.
@end multitable

We have found that the server with the most generic name
(@command{mysqld}) is the one that many users are likely to choose
by default. However, that is also the server that results in the
highest memory and CPU use due to the inclusion of full debugging
support.  The server named @command{mysqld-opt} is a better general-use
server choice to make instead if you don't need debugging suport
and don't want the maximal feature set offered by the @code{-max}
servers or named pipe support offered by the @code{-nt} servers.

To make it less likely that the debugging server would be chosen
inadvertantly, some name changes were made from MySQL 4.1.2 to
4.1.4:  @command{mysqld} has been renamed to @command{mysqld-debug}
and @command{mysqld-opt} has been renamed to @command{mysqld}.
Thus, the server that includes debugging support indicates that in
its name, and the server named @command{mysqld} is an efficient
default choice. The other servers still have their same names. The
resulting servers are named like this:

@multitable @columnfractions .20 .80
@item @strong{Binary} @tab @strong{Description}
@item @command{mysqld-debug} @tab Compiled with full debugging and automatic memory allocation checking, symbolic links, and @code{InnoDB} and @code{BDB} tables.
@item @command{mysqld} @tab Optimized binary with @code{InnoDB} support.
@item @command{mysqld-nt} @tab Optimized binary for Windows NT, 2000, and XP with support for named pipes.
@item @command{mysqld-max} @tab Optimized binary with support for symbolic links, and @code{InnoDB} and @code{BDB} tables.
@item @command{mysqld-max-nt} @tab Like @command{mysqld-max}, but compiled with support for named pipes.
@end multitable

The name changes were not both instituted at the same time. If you
have MySQL 4.1.2 or 4.1.3, it might be that you have a server named
@command{mysqld-debug} but not one named @command{mysqld}. In this
case, you should have have a server @command{mysqld-opt}, which you
should choose as your default server unless you need maximal features,
named pipes, or debugging support.

All of the preceding binaries are optimized for modern Intel processors,
but should work on any Intel i386-class or higher processor.

@cindex TCP/IP
@cindex named pipes

MySQL supports TCP/IP on all Windows platforms. The @command{mysqld-nt}
and @code{mysql-max-nt} servers support named pipes on Windows NT, 2000, XP, and 2003.
However, the default is to use TCP/IP regardless of the platform.
(Named pipes are slower than TCP/IP in many Windows configurations.)
@c WHEN IS THIS TRUE? CAN WE BE MORE SPECIFIC ABOUT WHEN NAMED PIPES
@c ARE SLOWER THAN TCP/IP?
Named pipe use is subject to these conditions:

@itemize @bullet
@item
Starting from MySQL 3.23.50, named pipes are enabled only
if you start the server with the @code{--enable-named-pipe} option.
It is now necessary to use this option explicitly because some users have
experienced problems shutting down the MySQL server when named pipes
were used.

@item
Named pipe connections are allowed only by the @command{mysqld-nt} or
@command{mysqld-max-nt} servers, and only if the server is run on a version
of Windows that supports named pipes (NT, 2000, XP, 2003).

@item
These servers can be run on Windows 98 or Me, but only if TCP/IP is installed;
named pipe connections cannot be used.

@item
These servers can not be run on Windows 95.

@end itemize

@strong{Note}:
Most of the examples in reference manual use @command{mysqld} as the
server name. If you choose to use a different server, such as
@command{mysqld-nt}, make the appropriate substitutions in the commands that
are shown in the examples. 

@node Windows server first start, Windows start command line, Windows select server, Windows installation
@subsection Starting the Server for the First Time

On Windows 95, 98, or Me, MySQL clients always connect to the server using
TCP/IP.  (This allows any machine on your network to connect to your MySQL
server.)  Because of this, you must make sure that TCP/IP support is installed
on your machine before starting MySQL.  You can find TCP/IP on your
Windows CD-ROM.

Note that if you are using an old Windows 95 release (for example,
OSR2), it's likely that you have an old Winsock package;
MySQL requires Winsock 2! You can get the newest Winsock from
@uref{http://www.microsoft.com/}.  Windows 98 has the new Winsock 2
library, so it is unnecessary to update the library.

On NT-based systems such as Windows NT, 2000, XP, or 2003, clients have two
options. They can use TCP/IP, or they can use a named pipe if the server
supports named pipe connections.

In MySQL versions 4.1 and higher, Windows servers also support shared-memory
connections if started with the @code{--shared-memory} option.  Clients can
connect through shared memory by using the @code{--protocol=memory} option.

For information about which server binary to run, see
@ref{Windows select server}.

This section gives a general overview of starting the MySQL server.  The
following sections provide more specific information for starting the MySQL
server from the command line or as a Windows service.

The examples in these sections assume that MySQL is installed under the default
location of @file{C:\mysql}. Adjust the pathnames shown in the examples if you
have MySQL installed in a different location.

Testing is best done from a command prompt in a console window (a ``DOS
window''). This way you can have the server display status messages in the
window where they are easy to see.  If something is wrong with your
configuration, these messages make it easier for you to identify
and fix any problems.

To start the server, enter this command:

@example
C:\> C:\mysql\bin\mysqld --console
@end example

For servers that include @code{InnoDB} support,
you should see the following messages as the server starts:

@example
InnoDB: The first specified datafile c:\ibdata\ibdata1 did not exist:
InnoDB: a new database to be created!
InnoDB: Setting file c:\ibdata\ibdata1 size to 209715200
InnoDB: Database physically writes the file full: wait...
InnoDB: Log file c:\iblogs\ib_logfile0 did not exist: new to be created
InnoDB: Setting log file c:\iblogs\ib_logfile0 size to 31457280
InnoDB: Log file c:\iblogs\ib_logfile1 did not exist: new to be created
InnoDB: Setting log file c:\iblogs\ib_logfile1 size to 31457280
InnoDB: Log file c:\iblogs\ib_logfile2 did not exist: new to be created
InnoDB: Setting log file c:\iblogs\ib_logfile2 size to 31457280
InnoDB: Doublewrite buffer not found: creating new
InnoDB: Doublewrite buffer created
InnoDB: creating foreign key constraint system tables
InnoDB: foreign key constraint system tables created
011024 10:58:25  InnoDB: Started
@end example

When the server finishes its startup sequence, you should see something
like this, which indicates that the server is ready to service client
connections:

@example
mysqld: ready for connections
Version: '4.0.14-log'  socket: ''  port: 3306
@end example

The server will continue to write to the console any further diagnostic
output it produces.  You can open a new console window in which to run
client programs.

If you omit the @code{--console} option, the server writes diagnostic output
to the error log in the data directory (@file{C:\mysql\data} by default).
The error log is the file with the @file{.err} extension.

@strong{Note}:
The accounts that are listed in the MySQL grant tables initially have no
passwords.  After starting the server, you should set up passwords for
them using the instructions in @ref{Post-installation}.


@node Windows start command line, Windows start service, Windows server first start, Windows installation
@subsection Starting MySQL from the Windows Command Line

The MySQL server can be started manually from the command line.
This can be done on any version of Windows.

To start the @command{mysqld} server from the command line, you should
start a console window (a ``DOS window'') and enter this command:

@example
C:\> C:\mysql\bin\mysqld
@end example

On non-NT versions of Windows, this will start @command{mysqld} in the
background. That is, after the server starts, you should see another
command prompt. If you start the server this way on Windows NT, 2000, or XP,
the server will run in the foreground and no command prompt will appear
until the server exits.  Because of this, you should open another console
window to run client programs while the server is running.

You can stop the MySQL server by executing this command:

@example
C:\> C:\mysql\bin\mysqladmin -u root shutdown
@end example

This invokes the MySQL administrative utility @command{mysqladmin} to
connect to the server and tell it to shut down. The command connects
as @code{root}, which is the default administrative account in the
MySQL grant system. Note that users in the MySQL grant system
are wholly independent from any login users under Windows.

If @command{mysqld} doesn't start, check the error log to see whether the
server wrote any messages there to indicate the cause of the problem.
The error log is located in the @file{C:\mysql\data} directory. It is
the file with a suffix of @file{.err}. You can also try to start the
server as @command{mysqld --console}; in this case, you may get some useful
information on the screen that may help solve the problem.

The last option is to start @command{mysqld} with @code{--standalone
--debug}.  In this case, @command{mysqld} writes a log file
@file{C:\mysqld.trace} that should contain the reason why @command{mysqld}
doesn't start. @xref{Making trace files}.

Use @command{mysqld --verbose --help} to display all the options that
@command{mysqld} understands.  (Prior to MySQL 4.1, omit the
@code{--verbose} option.)


@node Windows start service, Windows testing, Windows start command line, Windows installation
@subsection Starting MySQL as a Windows Service

On the NT family (Windows NT, 2000, XP, 2003), the recommended way to run
MySQL is to install it as a Windows service. When MySQL is installed as a
service, Windows starts and stops the MySQL server automatically when
Windows starts and stops.  A server installed as a service can also be
controlled from the command line using @command{NET} commands, or with the
graphical @code{Services} utility.

The @code{Services} utility (the Windows @code{Service Control Manager}) can
be found in the Windows @code{Control Panel} (under @code{Administrative
Tools} on Windows 2000, XP, and Server 2003). It is advisable to close the
@code{Services} utility while performing server installation or removal
operations from this command line.  This prevents some odd errors.

To get MySQL to work with TCP/IP on Windows NT 4, you must install
service pack 3 (or newer).

Before installing MySQL as a Windows service, you should first stop
the current server if it is running by using the following command:

@example
C:\> C:\mysql\bin\mysqladmin -u root shutdown
@end example

This invokes the MySQL administrative utility @command{mysqladmin} to
connect to the server and tell it to shut down. The command connects
as @code{root}, which is the default administrative account in the
MySQL grant system. Note that users in the MySQL grant system
are wholly independent from any login users under Windows.

Now install the server as a service:

@example
C:\> mysqld --install
@end example

If you have problems installing @command{mysqld} as a
service using just the server name, try installing it using its full pathname:

@example
C:\> C:\mysql\bin\mysqld --install
@end example

@c I commented this out because no instructions were given how to "fix"
@c the path. -- PD
@c If that doesn't work, you can get @command{mysqld} to
@c start properly by fixing the path in the registry!

As of MySQL 4.0.2, you can specify a specific service name after the
@code{--install} option.  As of MySQL 4.0.3, you can in addition specify a
@code{--defaults-file} option after the service name to indicate where the
server should obtain options when it starts. The rules that determine the
service name and option files the server uses are as follows:

@itemize @bullet

@item
If you specify no service name, the server uses the default service name of
@code{MySQL} and the server reads options from the @code{[mysqld]} group in
the standard option files.

@item
@c TODO change this back after bug gets fixed
@c If you specify a service name different than @code{MySQL} after the
If you specify a service name after the
@code{--install} option, the server ignores the @code{[mysqld]} option
group and instead reads options from the group that has the same name as the
service. The server reads options from the standard option files.

@c TODO preceding item is different for 4.0.17 on? ([mysqld] group is
@c read by all servers, even if installed with a non-default service name?)

@item
If you specify a @code{--defaults-file} option after the service name,
the server ignores the standard option files and reads options only from the
@code{[mysqld]} group of the named file.

@end itemize

@strong{Note}: Prior to MySQL 4.0.17, a server installed as a Windows
service has problems starting if its pathname or the service name contains
spaces. For this reason, avoid installing MySQL in a directory such as
@file{C:\Program Files} or using a service name containing spaces.

As a more complex example, consider the following command:

@example
C:\> C:\mysql\bin\mysqld --install mysql --defaults-file=C:\my-opts.cnf
@end example

Here, a service name is given after the @code{--install} option. If no
@code{--defaults-file} option had been given, this command would have the
effect of causing the server to read the @code{[mysql]} group from the
standard option files. (This would be a bad idea, because that option group
is for use by the @command{mysql} client program.) However, because the
@code{--defaults-file} option is present, the server reads options only from
the named file, and only from the @code{[mysqld]} option group.

You can also specify options as ``@code{Start parameters}'' in the
Windows @code{Services} utility before you start the MySQL service.

Once a MySQL server is installed as a service, Windows will start
the service automatically whenever Windows starts.  The service also
can be started immediately from the @code{Services} utility, or by
using the command @command{NET START MySQL}.  The @command{NET} command
is not case sensitive.

When run as a service, @command{mysqld} has no access
to a console window, so no messages can be seen there.  If
@command{mysqld} doesn't start, check the error log to see whether the
server wrote any messages there to indicate the cause of the problem.
The error log is located in the @file{C:\mysql\data} directory. It
is the file with a suffix of @file{.err}.

When @command{mysqld} is running as a service, it can be stopped by
using the @code{Services} utility, the command @command{NET STOP
MySQL}, or the command @command{mysqladmin shutdown}. If the service
is running when Windows shuts down, Windows will stop the server
automatically.

From MySQL 3.23.44 on, you have the choice of installing the
server as a @code{Manual} service if you don't wish the service to
be started automatically during the boot process. To do this, use
the @code{--install-manual} option rather than the @code{--install}
option:

@example
C:\> C:\mysql\bin\mysqld --install-manual
@end example

To remove a server that is installed as a service, first stop it if it is
running. Then use the @code{--remove} option to remove it:

@example
C:\> C:\mysql\bin\mysqld --remove
@end example

For MySQL versions older than 3.23.49, one problem with automatic
MySQL service shutdown is that Windows waited only for a few
seconds for the shutdown to complete, then killed the database
server process if the time limit was exceeded. This had the potential
to cause problems.  (For example, the @code{InnoDB} storage engine
had to perform crash recovery at the next startup.) Starting from
MySQL 3.23.49, Windows waits longer for the MySQL server
shutdown to complete. If you notice this still is not enough for
your installation, it is safest not to run the MySQL server as a
service. Instead, start it from the command-line prompt, and stop
it with @command{mysqladmin shutdown}.

This change to tell Windows to wait longer when stopping the MySQL server
works for Windows 2000 and XP. It does not work for Windows NT, where Windows
waits only 20 seconds for a service to shut down, and after that kills the
service process. You can increase this default by opening the Registry
Editor @file{\winnt\system32\regedt32.exe} and editing the value of
@code{WaitToKillServiceTimeout} at
@code{HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control}
in the Registry tree. Specify the new larger value in milliseconds.
For example, the value 120000 tells Windows NT to wait up to 120 seconds.

If you don't want to start @command{mysqld} as a service, you can start it
from the command line.  For instructions, see @ref{Windows start command
line}.

Please see @ref{Windows troubleshooting} if you encounter difficulties
during installation.


@node Windows testing, Windows troubleshooting, Windows start service, Windows installation
@subsection Testing The MySQL Installation

@cindex TCP/IP
@cindex named pipes

You can test whether the MySQL server is working by executing any of the
following commands:

@example
C:\> C:\mysql\bin\mysqlshow
C:\> C:\mysql\bin\mysqlshow -u root mysql
C:\> C:\mysql\bin\mysqladmin version status proc
C:\> C:\mysql\bin\mysql test
@end example

If @command{mysqld} is slow to respond to TCP/IP connections from client
programs on Windows 9x/Me, there is probably a problem with your DNS.  In
this case, start @command{mysqld} with the @code{--skip-name-resolve} option
and use only @code{localhost} and IP numbers in the @code{Host} column of
the MySQL grant tables.

You can force a MySQL client to use a named pipe connection rather than
TCP/IP by specifying the @code{--pipe} option or by specifying @code{.}
(period) as the host name.  Use the @code{--socket} option to specify the
name of the pipe.  As of MySQL 4.1, you should use the
@code{--protocol=PIPE} option.

There are two versions of the MySQL command-line tool:
@multitable @columnfractions .20 .80
@item @strong{Binary} @tab @strong{Description}
@item @command{mysql} @tab Compiled on native Windows, offering limited 
text editing capabilities.
@item @command{mysqlc} @tab Compiled with the Cygnus GNU compiler and 
libraries, which offers @code{readline} editing. @command{mysqlc} was 
intended for use primarily with Windows 9x/Me. It does not support the 
updated authentication protocol used beginning with MySQL 4.1, and is 
not supported in MySQL 4.1 and above. Beginning with MySQL 4.1.8, it is 
no longer included in MySQL Windows distributions.
@end multitable

@c TODO: Remove or rewrite all references to mysqlc.exe after a 
@c suitable period of time has elapsed. Suggestion: Move this info to a 
@c separate 'legacy' page?

If you want to use @command{mysqlc}, you must have a copy of the
@file{cygwinb19.dll} library installed somewhere that @command{mysqlc}
can find it. Current distributions of MySQL include this library
in the same directory as @command{mysqlc} (the @file{bin} directory
under the base directory of your MySQL installation). If your
distribution does not have the @code{cygwinb19.dll} library in the
@file{bin} directory, look for it in the @code{lib} directory and
copy it to your Windows system directory
(@file{\Windows\system} or a similar place).

@c TODO: check whether it needs to be in the *system* directory, or if 
@c it can be in the Windows directory.


@node Windows troubleshooting, Windows upgrading, Windows testing, Windows installation
@subsection Troubleshooting a MySQL Installation Under Windows

When installing and running MySQL for the first time, you may encounter 
certain errors that prevent the MySQL server from starting. 
The purpose of this section is to help you diagnose and correct some 
of these errors. 

Your first resource when troubleshooting server issues is the error log. 
The MySQL server uses the error log to record information relevant to the 
error that is preventing the server from starting. The error log is
located in the data directory specified in your @file{my.ini} file.
The default data directory location is @file{C:\mysql\data}.
@xref{Error log}.

Another source of information regarding possible errors is the console
messages displayed when the MySQL service is starting. Use the @command{NET
START mysql} command from the command line after installing @command{mysqld} as
a service to see any error messages regarding the starting of the MySQL
server as a service.
@xref{Windows start service}.

The following are examples of some of the more common error messages you may
encounter when installing MySQL and starting the server for the first time:

@example
System error 1067 has occurred.
Fatal error: Can't open privilege tables: Table 'mysql.host' doesn't exist
@end example

These messages occur when the MySQL server cannot find the @code{mysql} 
privileges database or other critical files. This error is often encountered 
when the MySQL base or data directories are installed in different 
locations than the default locations (@file{C:\mysql} and
@file{C:\mysql\data}, respectively).

If you have installed MySQL to a directory other than @file{C:\mysql} you
need to ensure that the MySQL server is aware of this through the use of a
configuration (@code{my.ini}) file. The @code{my.ini} file needs to be
located in your Windows directory, typically located at @file{C:\WinNT} or
@file{C:\WINDOWS}. You can determine its exact location from the value of
the @code{WINDIR} environment variable by issuing the following command from
the command prompt:

@example
C:\> echo %WINDIR%
@end example

An option file can be created and modified with any text editor, 
such as the Notepad program. For example, if MySQL is installed at 
@file{E:\mysql} and the data directory is located at @file{D:\MySQLdata}, 
you can create the option file and set up a @code{[mysqld]} section to specify 
values for the basedir and datadir parameters:

@example
[mysqld]
# set basedir to your installation path
basedir=E:/mysql
# set datadir to the location of your data directory
datadir=D:/MySQLdata
@end example

Note that Windows pathnames are specified in option files using 
forward slashes rather than backslashes. If you do use backslashes, 
you must double them:

@example
[mysqld]
# set basedir to your installation path
basedir=C:\\Program Files\\mysql
# set datadir to the location of your data directory
datadir=D:\\MySQLdata
@end example

@xref{Windows create option file}.

@node Windows upgrading, Windows vs Unix, Windows troubleshooting, Windows installation
@subsection Upgrading MySQL on Windows

@cindex Windows, upgrading

This section lists some of the steps you should take when upgrading MySQL on
Windows.

@enumerate

@item
You should always back up your current MySQL installation before performing
an upgrade.
@xref{Backup}.

@item
Download the latest Windows distribution of MySQL from
@uref{http://dev.mysql.com}.

@item
Before upgrading MySQL, you must stop the server.

If the server is installed as a service, stop the service with the following
command from the command prompt:
@example
C:\> NET STOP MySQL
@end example

If you are not running the MySQL server as a service, use the following command to stop the server:

@example
C:\> C:\mysql\bin\mysqladmin -u root shutdown
@end example

@item
Exit the @code{WinMySQLAdmin} program if it is running.

@item
When upgrading to MySQL 4.1.5 or higher from a previous version, or when
upgrading from a version of MySQL installed from a Zip archive to a version
of MySQL installed with the MySQL Installation Wizard, you must manually
remove the previous installation and MySQL service (if the server is
installed as a service).

To remove the MySQL service, use the following command:
@example
C:\> C:\mysql\bin\mysqld --remove
@end example

@strong{If you do not remove the existing service, the MySQL Installation
Wizard may fail to properly install the new MySQL service.}

@item
If you are using the MySQL Installation Wizard, start the wizard as
described in @ref{Windows install wizard}.

@item
If you are installing MySQL from a Zip archive, extract the archive. You may
either overwrite your existing MySQL installation (usually located at
@file{C:\mysql}), or install it into a different directory, such as
@code{C:\mysql4}. Overwriting the existing installation is recommended.

@item
Restart the server. For example, use @command{NET START MySQL} if you run MySQL
as a service, or invoke @command{mysqld} directly otherwise.

@item
Refer to @ref{Upgrade} for additional information on upgrading MySQL that is
not specific to Windows.

@item
If you encounter errors, see @ref{Windows troubleshooting}.

@end enumerate


@node Windows vs Unix,  , Windows upgrading, Windows installation
@subsection MySQL on Windows Compared to MySQL on Unix

@cindex Windows, versus Unix
@cindex operating systems, Windows versus Unix

MySQL for Windows has proven itself to be very stable. The Windows
version of MySQL has the same features as the corresponding Unix version,
with the following exceptions:

@table @strong
@item Windows 95 and threads
Windows 95 leaks about 200 bytes of main memory for each thread creation.
Each connection in MySQL creates a new thread, so you shouldn't
run @command{mysqld} for an extended time on Windows 95 if your server handles
many connections!  Other versions of Windows don't suffer from this bug.

@item Limited number of ports
Windows systems have about 4,000 ports available for client connections, and
after a connection on a port closes, it takes two to four minutes before the
port can be reused.  In situations where clients connect to and disconnect
from the server at a high rate, it is possible for all available ports to be
used up before closed ports become available again. If this happens, the
MySQL server will appear to have become unresponsive even though it is
running.  Note that ports may be used by other applications running on the
machine as well, in which case the number of ports available to MySQL is
lower.

For more information, see
@uref{http://support.microsoft.com/default.aspx?scid=kb;en-us;196271}.

@item Concurrent reads
MySQL depends on the @code{pread()} and @code{pwrite()} calls to be
able to mix @code{INSERT} and @code{SELECT}.  Currently we use mutexes
to emulate @code{pread()}/@code{pwrite()}.  We will, in the long run,
replace the file level interface with a virtual interface so that we can
use the @code{readfile()}/@code{writefile()} interface on NT, 2000, and XP to
get more speed.
The current implementation limits the number of open files MySQL can use to
2,048 (1,024 before MySQL 4.0.19), which means that you will not be able to
run as many concurrent threads on NT, 2000, and XP as on Unix.

@item Blocking read
MySQL uses a blocking read for each connection, which has the following
implications if named pipe connections are enabled:

@itemize @bullet
@item
A connection will not be disconnected automatically after eight hours, as
happens with the Unix version of MySQL.

@item
If a connection hangs, it's impossible to break it without killing
MySQL.

@item
@command{mysqladmin kill} will not work on a sleeping connection.

@item
@command{mysqladmin shutdown} can't abort as long as there are sleeping
connections.
@end itemize

We plan to fix this problem when our Windows developers have figured out a
nice workaround.

@item @code{ALTER TABLE}
While you are executing an @code{ALTER TABLE} statement, the table is locked
from being used by other threads.  This has to do with the fact that on Windows,
you can't delete a file that is in use by another thread.  In the future,
we may find some way to work around this problem.

@item @code{DROP TABLE}
@code{DROP TABLE} on a table that is in use by a @code{MERGE} table will
not work on Windows because the @code{MERGE} handler does the table mapping
hidden from the upper layer of MySQL.  Because Windows doesn't allow you
to drop files that are open, you first must flush all @code{MERGE}
tables (with @code{FLUSH TABLES}) or drop the @code{MERGE} table before
dropping the table.  We will fix this at the same time we introduce
views.

@item @code{DATA DIRECTORY} and @code{INDEX DIRECTORY}
The @code{DATA DIRECTORY} and @code{INDEX DIRECTORY} options for
@code{CREATE TABLE} are ignored on Windows, because Windows doesn't support
symbolic links.  These options also are ignored on systems that have a
non-functional @code{realpath()} call.

@item @code{DROP DATABASE}
You cannot drop a database that is in use by some thread.

@item Killing MySQL from the Task Manager
You cannot kill MySQL from the Task Manager or with the shutdown
utility in Windows 95.  You must stop it with @command{mysqladmin shutdown}.

@item Case-insensitive names
Filenames are not case sensitive on Windows, so MySQL database and table
names are also not case sensitive on Windows.  The only restriction is that
database and table names must be specified using the same case throughout a
given statement.  @xref{Name case sensitivity}.

@item The @samp{\} pathname separator character
Pathname components in Windows are separated by the @samp{\} character,
which is also the escape character in MySQL.  If you are using @code{LOAD
DATA INFILE} or @code{SELECT ... INTO OUTFILE},
use Unix-style filenames with @samp{/} characters:

@example
mysql> LOAD DATA INFILE 'C:/tmp/skr.txt' INTO TABLE skr;
mysql> SELECT * INTO OUTFILE 'C:/tmp/skr.txt' FROM skr;
@end example

Alternatively, you must double the @samp{\} character:

@example
mysql> LOAD DATA INFILE 'C:\\tmp\\skr.txt' INTO TABLE skr;
mysql> SELECT * INTO OUTFILE 'C:\\tmp\\skr.txt' FROM skr;
@end example

@item Problems with pipes.
Pipes do not work reliably from the Windows command-line prompt.  If the
pipe includes the character @code{^Z} / @code{CHAR(24)}, Windows will think it
has encountered end-of-file and abort the program.

This is mainly a problem when you try to apply a binary log as follows:

@example
C:\> mysqlbinlog binary-log-name | mysql --user=root
@end example

If you have a problem applying the log and suspect that it is because of a
@code{^Z} / @code{CHAR(24)} character, you can use the following workaround:

@example
C:\> mysqlbinlog binary-log-file --result-file=/tmp/bin.sql
C:\> mysql --user=root --execute "source /tmp/bin.sql"
@end example

The latter command also can be used to reliably read in any SQL file
that may contain binary data.

@c Mike Hillyer - This is getting a little old, commenting out.
@c @item @code{Can't open named pipe} error
@c If you use a MySQL 3.22 server on Windows NT with the newest MySQL client
@c programs, you will get the following error:

@c @example
@c error 2017: can't open named pipe to host: . pipe...
@c @end example

@c @tindex .my.cnf file
@c This happens because the release version of MySQL uses named pipes on NT
@c by default.  You can avoid this error by using the @code{--host=localhost}
@c option to the new MySQL clients or by creating an option file
@c @file{C:\my.cnf} that contains the following information:

@c @example
@c [client]
@c host = localhost
@c @end example

@c Starting from 3.23.50, named pipes are enabled only if @command{mysqld-nt} or
@c @command{mysqld-max-nt} is started with @code{--enable-named-pipe}.

@item @code{Access denied for user} error
If you attempt to run a MySQL client program to connect to a server
running on the same machine, but get the error @code{Access denied
for user '@var{some-user}'@@'unknown' to database 'mysql'}, this means
that MySQL cannot resolve your hostname properly.

To fix this, you should create a file named @file{\windows\hosts} containing
the following information:

@example
127.0.0.1       localhost
@end example

@end table


@c MH - Does this to-do list even still have relevance? I would think we would
@c now Task internal developers rather than ask the world for help.

Here are some open issues for anyone who might want to help us improve MySQL
on Windows:

@cindex Windows, open issues

@itemize @bullet
PD: Commented this one out as obsolete until I hear otherwise
@item
Make a single-user @code{MYSQL.DLL} server.  This should include everything in
a standard MySQL server, except thread creation.  This will make
MySQL much easier to use in applications that don't need a true
client/server and don't need to access the server from other hosts.
@item
Add some nice start and shutdown icons to the MySQL installation.

@item
It would be really nice to be able to kill @command{mysqld} from the Task Manager
in Windows 95.  For the moment, you must use @command{mysqladmin shutdown}.

@item
Port @code{readline} to Windows for use in the @command{mysql} command-line tool.

@item
GUI versions of the standard MySQL clients (@command{mysql},
@command{mysqlshow}, @command{mysqladmin}, and @command{mysqldump}) would be nice.

@item
It would be nice if the socket read and write functions in @file{net.c} were
interruptible. This would make it possible to kill open threads with
@command{mysqladmin kill} on Windows.

@item
Add macros to use the faster thread-safe increment/decrement methods
provided by Windows.
@end itemize


@node Linux-RPM, Mac OS X installation, Windows installation, Installing
@section Installing MySQL on Linux

@cindex RPM file
@cindex RPM Package Manager
@cindex installing, Linux RPM packages

The recommended way to install MySQL on Linux is by using the RPM
packages. The MySQL RPMs are currently built on a SuSE Linux 7.3
system, but should work on most versions of Linux that support @command{rpm}
and use @code{glibc}.
To obtain RPM packages, see @ref{Getting MySQL}.

@strong{Note}: RPM distributions of MySQL often are provided by other
vendors.  Be aware that they may differ in features and capabilities from
those built by MySQL AB, and that the instructions in this manual do not
necessarily apply to installing them. The vendor's instructions should be
consulted instead.

If you have problems with an RPM file (for example, if you receive the error
``@code{Sorry, the host '@var{xxxx}' could not be looked up}''), see
@ref{Binary notes-Linux}.

In most cases, you only need to install the @code{MySQL-server} and
@code{MySQL-client} packages to get a functional MySQL installation. The
other packages are not required for a standard installation.
If you want to run a MySQL-Max server that has additional capabilities,
you should also install the @code{MySQL-Max} RPM. However, you should do so only
@emph{ after} installing the @code{MySQL-server} RPM.
@xref{mysqld-max, , @command{mysqld-max}}.

If you get a dependency failure when trying to install the MySQL 4.0
packages (for example, ``@code{error: removing these packages would break dependencies:
libmysqlclient.so.10 is needed by ...}''), you should also install
the package @code{MySQL-shared-compat}, which includes both the
shared libraries for backward compatibility (@code{libmysqlclient.so.12}
for MySQL 4.0 and @code{libmysqlclient.so.10} for MySQL 3.23).

Many Linux distributions still ship with MySQL 3.23 and they usually link
applications dynamically to save disk space. If these shared libraries are
in a separate package (for example, @code{MySQL-shared}), it is
sufficient to simply leave this package installed and just upgrade
the MySQL server and client packages (which are statically linked
and do not depend on the shared libraries). For distributions that
include the shared libraries in the same package as the MySQL server
(for example, Red Hat Linux), you could either install our 3.23
@code{MySQL-shared} RPM, or use the @code{MySQL-shared-compat} package instead.

The following RPM packages are available:

@itemize @bullet
@item @code{MySQL-server-@var{VERSION}.i386.rpm}

The MySQL server.  You will need this unless you only want to
connect to a MySQL server running on another machine. Note:
Server RPM files were called @code{MySQL-@var{VERSION}.i386.rpm} before
MySQL 4.0.10. That is, they did not have @code{-server} in the name.

@item @code{MySQL-Max-@var{VERSION}.i386.rpm}

The MySQL-Max server. This server has additional capabilities that the
one provided in the @code{MySQL-server} RPM does not.  You must install the
@code{MySQL-server} RPM first, because the @code{MySQL-Max} RPM depends on it.

@item @code{MySQL-client-@var{VERSION}.i386.rpm}

The standard MySQL client programs. You probably always want to
install this package.

@item @code{MySQL-bench-@var{VERSION}.i386.rpm}

Tests and benchmarks. Requires Perl and the @code{DBD::mysql} module.

@item @code{MySQL-devel-@var{VERSION}.i386.rpm}

The libraries and include files that are needed if you want to compile other
MySQL clients, such as the Perl modules.

@item @code{MySQL-shared-@var{VERSION}.i386.rpm}

This package contains the shared libraries (@code{libmysqlclient.so*})
that certain languages and applications need to dynamically load and
use MySQL.

@item @code{MySQL-shared-compat-@var{VERSION}.i386.rpm}

This package includes the shared libraries for both MySQL 3.23 and
MySQL 4.0. Install this package instead of @code{MySQL-shared} if you
have applications installed that are dynamically linked against MySQL
3.23 but you want to upgrade to MySQL 4.0 without breaking the library
dependencies. This package has been available since MySQL 4.0.13.

@item @code{MySQL-embedded-@var{VERSION}.i386.rpm}

The embedded MySQL server library (from MySQL 4.0).

@item @code{MySQL-@var{VERSION}.src.rpm}

This contains the source code for all of the previous packages. It can also
be used to rebuild the RPMs on other architectures (for example, Alpha or SPARC).
@end itemize

To see all files in an RPM package (for example, a @code{MySQL-server}
RPM), run:

@example
shell> rpm -qpl MySQL-server-@var{VERSION}.i386.rpm
@end example

To perform a standard minimal installation, run:

@example
shell> rpm -i MySQL-server-@var{VERSION}.i386.rpm
shell> rpm -i MySQL-client-@var{VERSION}.i386.rpm
@end example

To install just the client package, run:

@example
shell> rpm -i MySQL-client-@var{VERSION}.i386.rpm
@end example

RPM provides a feature to verify the integrity and authenticity of packages
before installing them. If you would like to learn more about this feature,
see @ref{Verifying Package Integrity}.

The server RPM places data under the @file{/var/lib/mysql} directory. The
RPM also creates a login account for a user named @code{mysql} (if one does not
already exist) to use for running the MySQL server, and
creates the appropriate entries in @file{/etc/init.d/} to start the
server automatically at boot time. (This means that if you have performed a
previous installation and have made changes to its startup script, you may
want to make a copy of the script so that you don't lose it when you install a
newer RPM.) See @ref{Automatic start} for more information on how MySQL can be
started automatically on system startup.

If you want to install the MySQL RPM on older Linux distributions that do
not support initialization scripts in @file{/etc/init.d} (directly
or via a symlink), you should create a symbolic link that points
to the location where your initialization scripts actually are
installed. For example, if that location is @file{/etc/rc.d/init.d},
use these commands before installing the RPM to create @file{/etc/init.d}
as a symbolic link that points there:

@example
shell> cd /etc
shell> ln -s rc.d/init.d .
@end example

However, all current major Linux distributions should already support the
new directory layout that uses @file{/etc/init.d}, because it is
required for LSB (Linux Standard Base) compliance.

If the RPM files that you install include @code{MySQL-server}, the
@command{mysqld} server should be up and running after installation.
You should now be able to start using MySQL.

If something goes wrong, you can find more information in the binary
installation section. @xref{Installing binary}.

@strong{Note}:
The accounts that are listed in the MySQL grant tables initially have no
passwords.  After starting the server, you should set up passwords for
them using the instructions in @ref{Post-installation}.


@node Mac OS X installation, NetWare installation, Linux-RPM, Installing
@section Installing MySQL on Mac OS X

@cindex Mac OS X, installation
@cindex installing, Mac OS X PKG packages

Beginning with MySQL 4.0.11, you can install MySQL on Mac OS X 10.2.x
(``Jaguar'') and up using a Mac OS X binary package in PKG format instead of the
binary tarball distribution. Please note that older versions of Mac OS X
(for example, 10.1.x) are not supported by this package.

The package is located inside a disk image (@code{.dmg}) file that you
first need to mount by double-clicking its icon in the Finder. It should
then mount the image and display its contents.

To obtain MySQL, see @ref{Getting MySQL}.

@strong{Note}: Before proceeding with the installation, be sure to
shut down all running MySQL server instances by either
using the MySQL Manager Application (on Mac OS X Server) or via
@command{mysqladmin shutdown} on the command line.

To actually install the MySQL PKG file, double-click on the package icon. This
launches the Mac OS X Package Installer, which will guide you through
the installation of MySQL.

Due to a bug in the Mac OS X package installer, you may see this
error message in the destination disk selection dialog:

@example
You cannot install this software on this disk. (null)
@end example

If this error occurs, simply click the @code{Go Back} button once to return
to the previous screen. Then click @code{Continue} to advance to the
destination disk selection again, and you should be able to choose the
destination disk correctly. We have reported this bug to Apple and it is
investigating this problem.

The Mac OS X PKG of MySQL will install itself into
@file{/usr/local/mysql-@var{VERSION}} and will also install a symbolic link,
@file{/usr/local/mysql}, pointing to the new location. If a directory named
@file{/usr/local/mysql} already exists, it will be renamed to
@file{/usr/local/mysql.bak} first. Additionally, the installer will create the
grant tables in the @code{mysql} database by executing @command{mysql_install_db}
after the installation.

The installation layout is similar to that of a @command{tar} file binary
distribution; all MySQL binaries are located in the directory
@file{/usr/local/mysql/bin}.  The MySQL socket file is created as
@file{/tmp/mysql.sock} by default.
@xref{Installation layouts}.

MySQL installation requires a Mac OS X user account named @code{mysql}.  A
user account with this name should exist by default on Mac OS X 10.2 and up.

If you are running Mac OS X Server, you already have a version of MySQL
installed.  The versions of MySQL that ship with Mac OS X Server versions are
shown in the following table:

@multitable @columnfractions .30 .30
@item @strong{Mac OS X Server Version} @tab @strong{MySQL Version}
@item 10.2-10.2.2   @tab 3.23.51
@item 10.2.3-10.2.6 @tab 3.23.53
@item 10.3          @tab 4.0.14
@item 10.3.2        @tab 4.0.16
@end multitable

This manual section covers the installation of the official MySQL Mac OS X
PKG only.  Make sure to read Apple's help information about installing MySQL:
Run the ``Help View'' application, select ``Mac OS X Server'' help, do a
search for ``MySQL,'' and read the item entitled ``Installing MySQL.''

@c This instance of safe_mysqld should be left unchanged
For pre-installed versions of MySQL on Mac OS X Server, note especially that
you should start @command{mysqld} with @command{safe_mysqld} instead of
@command{mysqld_safe} if MySQL is older than version 4.0.

If you previously used Marc Liyanage's MySQL packages for Mac OS X from
@uref{http://www.entropy.ch}, you can simply follow the update instructions
for packages using the binary installation layout as given on his pages.

If you are upgrading from Marc's 3.23.xx versions or from the Mac OS X
Server version of MySQL to the official MySQL PKG, you also need to convert
the existing MySQL privilege tables to the current format, because
some new security privileges have been added.
@xref{Upgrading-grant-tables}.

If you would like to automatically start up MySQL during system startup, you
also need to install the MySQL Startup Item. Starting with MySQL 4.0.15, it
is part of the Mac OS X installation disk images as a separate installation
package. Simply double-click the @code{MySQLStartupItem.pkg} icon and follow
the instructions to install it.

Note that the Startup Item need be installed only once! There is no need to
install it each time you upgrade the MySQL package later.

The Startup Item will be installed into
@file{/Library/StartupItems/MySQLCOM}.  (Before MySQL 4.1.2, the location
was @file{/Library/StartupItems/MySQL}, but that collided with the MySQL
Startup Item installed by Mac OS X Server.)  Startup Item installation
adds a variable @code{MYSQLCOM=-YES-} to the system configuration file
@file{/etc/hostconfig}. If you would like to disable the automatic startup
of MySQL, simply change this variable to @code{MYSQLCOM=-NO-}.

On Mac OS X Server, the default MySQL installation uses the variable
@code{MYSQL} in the @file{/etc/hostconfig} file.  The MySQL AB Startup Item
installer disables this variable by setting it to @code{MYSQL=-NO-}. This
avoids boot time conflicts with the @code{MYSQLCOM} variable used by the
MySQL AB Startup Item.  However, it does not shut down an already running
MySQL server. You should do that yourself.

After the installation, you can start up MySQL by running the following
commands in a terminal window. You must have administrator privileges to
perform this task.

If you have installed the Startup Item:

@example
shell> sudo /Library/StartupItems/MySQLCOM/MySQLCOM start
(Enter your password, if necessary)
(Press Control-D or enter "exit" to exit the shell)
@end example

For versions of MySQL older than 4.1.3, substitute 
@code{/Library/StartupItems/MySQLCOM/MySQLCOM} with
@code{/Library/StartupItems/MySQL/MySQL} above.

If you don't use the Startup Item, enter the following command sequence:

@example
shell> cd /usr/local/mysql
shell> sudo ./bin/mysqld_safe
(Enter your password, if necessary)
(Press Control-Z)
shell> bg
(Press Control-D or enter "exit" to exit the shell)
@end example

You should now be able to connect to the MySQL server, for example, by running
@file{/usr/local/mysql/bin/mysql}.

@strong{Note}:
The accounts that are listed in the MySQL grant tables initially have no
passwords.  After starting the server, you should set up passwords for
them using the instructions in @ref{Post-installation}.

You might want to add aliases to your shell's resource file to make it easier
to access commonly used programs such as @command{mysql} and @command{mysqladmin}
from the command line. The syntax for @command{tcsh} is:

@example
alias mysql /usr/local/mysql/bin/mysql
alias mysqladmin /usr/local/mysql/bin/mysqladmin
@end example

For @command{bash}, use:

@example
alias mysql=/usr/local/mysql/bin/mysql
alias mysqladmin=/usr/local/mysql/bin/mysqladmin
@end example

Even better,
add @code{/usr/local/mysql/bin} to
your @code{PATH} environment variable. For example, add the following
line to your @file{$HOME/.tcshrc} file if your shell is @command{tcsh}:

@example
setenv PATH $@{PATH@}:/usr/local/mysql/bin
@end example

If no @file{.tcshrc} file exists in your home directory, create it with a text
editor.

If you are upgrading an existing installation,
please note that installing a new MySQL PKG does not remove the directory
of an older installation. Unfortunately, the Mac OS X Installer does not yet
offer the functionality required to properly upgrade previously installed
packages.

To use your existing databases with the new installation, you'll need to copy
the contents of the old data directory to the new data directory. Make sure
that neither the old server nor the new one is running when you do this.
After you have copied over the MySQL database files from the
previous installation and have successfully started the new server, you should
consider removing the old installation files to save disk space.
Additionally, you should also remove older versions of the Package Receipt
directories located in @file{/Library/Receipts/mysql-@var{VERSION}.pkg}.

@node NetWare installation, Installing binary, Mac OS X installation, Installing
@section Installing MySQL on NetWare

@cindex Novell NetWare
@cindex NetWare

Porting MySQL to NetWare was an effort spearheaded by
Novell. Novell customers will be pleased to note that NetWare 6.5
ships with bundled MySQL binaries, complete with an automatic
commercial use license for all servers running that version of NetWare.

MySQL for NetWare is compiled using a combination of @code{Metrowerks
CodeWarrior for NetWare} and special cross-compilation versions of the
GNU autotools.

The latest binary packages for NetWare can be obtained at
@uref{http://dev.mysql.com/downloads/}.
@xref{Getting MySQL}.

In order to host MySQL, the NetWare server must meet these requirements:

@itemize @bullet
@item
NetWare 6.5 Support Pack 2 installed and updated with the latest LibC,
or NetWare 6.0 with Support Pack 4 installed and updated with the latest LibC.
NetWare 6.5 Support Pack 2 and other updates are available at
@uref{http://support.novell.com/filefinder/18197/index.html}.
NetWare 6.0 Support Pack 4 and other updates are available at
@uref{http://support.novell.com/filefinder/13659/index.html}.
The latest LibC is available at @uref{http://developer.novell.com/ndk/libc.htm}.
Steps to update LibC can be found here:
@uref{http://developer.novell.com/ndk/doc/libc/index.html?page=/ndk/doc/libc/libc_enu/data/ajjl0r0.html}

@item
The system must meet Novell's minimum requirements to run the respective
version of NetWare.
@item
MySQL data, as well as the binaries themselves, must be installed on an
NSS volume; traditional volumes are not supported.
@end itemize

To install MySQL for NetWare, use the following procedure:

@enumerate
@item
If you are upgrading from a prior installation, stop the MySQL server.
This is done from the server console, using the following command:

@example
SERVER:  mysqladmin -u root shutdown
@end example

@item
Log on to the target server from a client machine with access to the
location where you will install MySQL.

@item
Extract the binary package Zip file onto the server. Be sure to allow
the paths in the Zip file to be used. It is safe to simply extract the
file to @file{SYS:\}.

If you are upgrading from a prior installation, you may need to copy the
data directory (for example, @file{SYS:MYSQL\DATA}) now, as well as
@file{my.cnf}, if you have customized it. You can then delete the old copy
of MySQL.

@item
You might want to rename the directory to something more consistent and easy
to use. We recommend using @file{SYS:MYSQL}; examples in this manual
use this name to refer to the installation directory in general.

@item
At the server console, add a search path for the directory containing the
MySQL NLMs. For example:

@example
SERVER:  SEARCH ADD SYS:MYSQL\BIN
@end example

@item
Initialize the data directory and the grant tables, if needed, by executing
@command{mysql_install_db} at the server console.

@item
Start the MySQL server using @command{mysqld_safe} at the server console.

@item
To finish the installation, you should also add the following commands to
@code{autoexec.ncf}. For example, if your MySQL installation is in
@file{SYS:MYSQL} and you want MySQL to start automatically, you could
add these lines:

@example
#Starts the MySQL 4.0.x database server
SEARCH ADD SYS:MYSQL\BIN
MYSQLD_SAFE
@end example

If you are running MySQL on NetWare 6.0, we strongly suggest that you use the
@code{--skip-external-locking} option on the command line:

@example
#Starts the MySQL 4.0.x database server
SEARCH ADD SYS:MYSQL\BIN
MYSQLD_SAFE --skip-external-locking
@end example

It will also be necessary to use @code{CHECK TABLE} and @code{REPAIR
TABLE} instead of @command{myisamchk}, because @command{myisamchk} makes use
of external locking.  External locking is known to have problems on
NetWare 6.0; the problem has been eliminated in NetWare 6.5.

@command{mysqld_safe} on NetWare provides a screen presence. When you unload
(shut down) the @command{mysqld_safe} NLM, the screen does not by default go
away.  Instead, it prompts for user input:

@example
*<NLM has terminated; Press any key to close the screen>*
@end example

If you want NetWare to close the screen automatically instead, use the
@code{--autoclose} option to @command{mysqld_safe}. For example:

@example
#Starts the MySQL 4.0.x database server
SEARCH ADD SYS:MYSQL\BIN
MYSQLD_SAFE --autoclose
@end example

@item
When installing the 4.1.x version either for the first time or upgrading the
4.0.x version to 4.1.x, download and install Perl module for MySQL 4.1 from
@uref{http://forge.novell.com/modules/xfmod/project/showfiles.php?group_id=1126}
and PHP Extension for MySQL 4.1 from
@uref{http://forge.novell.com/modules/xfmod/project/showfiles.php?group_id=1078}

@end enumerate

The behavior of @command{mysqld_safe} on NetWare is described further in
@ref{mysqld_safe,  , @command{mysqld_safe}}.

If there was an existing installation of MySQL on the server, be sure
to check for existing MySQL startup commands in @code{autoexec.ncf},
and edit or delete them as necessary.

@strong{Note}:
The accounts that are listed in the MySQL grant tables initially have no
passwords.  After starting the server, you should set up passwords for
them using the instructions in @ref{Post-installation}.


@c TODO: rename this node. "Installing binary" should be used for the
@c general binary installation section

@node Installing binary, Installing source, NetWare installation, Installing
@section Installing MySQL on Other Unix-Like Systems

@cindex installing, binary distribution
@cindex binary distributions, installing

This section covers the installation of MySQL binary distributions that are
provided for various platforms in the form of compressed @command{tar} files
(files with a @code{.tar.gz} extension).  See @ref{MySQL binaries} for a
detailed list.

To obtain MySQL, see @ref{Getting MySQL}.

MySQL @command{tar} file binary distributions have names of the form
@file{mysql-@var{VERSION}-@var{OS}.tar.gz}, where @code{@var{VERSION}} is a number (for
example, @code{4.0.17}), and @var{OS} indicates the type of operating
system for which the distribution is intended (for example,
@code{pc-linux-i686}).

In addition to these generic packages, we also offer binaries in
platform-specific package formats for selected platforms.
See @ref{Quick Standard Installation} for more information on how to install
these.

You need the following tools to install a MySQL @command{tar} file binary
distribution:

@itemize @bullet
@item
GNU @code{gunzip} to uncompress the distribution.

@item
A reasonable @command{tar} to unpack the distribution. GNU @command{tar} is known
to work. Some operating systems come with a pre-installed version of
@command{tar} that is known to have problems.  For example, Mac OS X @command{tar}
and Sun @command{tar} are known to have problems with long filenames.  On Mac
OS X, you can use the pre-installed @command{gnutar} program.  On other systems
with a deficient @command{tar}, you should install GNU @command{tar} first.
@end itemize

@c texi2html fails to split chapters if I use strong for all of this.
If you run into problems, @emph{please always use @command{mysqlbug}} when
posting questions to a MySQL mailing list.  Even if the problem
isn't a bug, @command{mysqlbug} gathers system information that will help others
solve your problem.  By not using @command{mysqlbug}, you lessen the likelihood
of getting a solution to your problem.  You will find @command{mysqlbug} in the
@file{bin} directory after you unpack the distribution.  @xref{Bug reports}.

@cindex commands, for binary distribution
The basic commands you must execute to install and use a MySQL
binary distribution are:

@example
shell> groupadd mysql
shell> useradd -g mysql mysql
shell> cd /usr/local
shell> gunzip < @var{/path/to/mysql-VERSION-OS}.tar.gz | tar xvf -
shell> ln -s @var{full-path-to-mysql-VERSION-OS} mysql
shell> cd mysql
shell> scripts/mysql_install_db --user=mysql
shell> chown -R root  .
shell> chown -R mysql data
shell> chgrp -R mysql .
shell> bin/mysqld_safe --user=mysql &
@end example

For versions of MySQL older than 4.0, substitute @command{bin/safe_mysqld}
for @command{bin/mysqld_safe} in the final command.

@strong{Note}: This procedure does not set up any passwords for MySQL
accounts.  After following the procedure, proceed to @ref{Post-installation}.

A more detailed version of the preceding description for installing
a binary distribution follows:

@enumerate

@item
Add a login user and group for @command{mysqld} to run as:

@example
shell> groupadd mysql
shell> useradd -g mysql mysql
@end example

These commands add the @code{mysql} group and the @code{mysql} user.  The
syntax for @command{useradd} and @command{groupadd} may differ slightly on different
versions of Unix.  They may also be called @command{adduser} and @command{addgroup}.

You might want to call the user and group something else instead
of @code{mysql}.  If so, substitute the appropriate name in the
following steps.

@item
Pick the directory under which you want to unpack the distribution, and
change location into it. In the following example, we unpack the
distribution under @file{/usr/local}. (The instructions, therefore, assume
that you have permission to create files and directories in
@file{/usr/local}.  If that directory is protected, you will need to perform
the installation as @code{root}.)

@example
shell> cd /usr/local
@end example

@item
Obtain a distribution file from one of the sites listed in
@ref{Getting MySQL, , Getting MySQL}.
For a given release, binary distributions for all platforms
are built from the same MySQL source distribution.

@item
Unpack the distribution, which will create the installation directory.
Then create a symbolic link to that directory:

@example
shell> gunzip < @var{/path/to/mysql-VERSION-OS}.tar.gz | tar xvf -
shell> ln -s @var{full-path-to-mysql-VERSION-OS} mysql
@end example

The @command{tar} command creates a directory named
@file{mysql-@var{VERSION}-@var{OS}}.  The
@code{ln} command makes a symbolic link to that directory.  This lets you refer
more easily to the installation directory as @file{/usr/local/mysql}.

With GNU @command{tar}, no separate invocation of @code{gunzip} is necessary.
You can replace the first line with the following
alternative command to uncompress and extract the distribution:

@example
shell> tar zxvf @var{/path/to/mysql-VERSION-OS}.tar.gz
@end example

@item
Change location into the installation directory:

@example
shell> cd mysql
@end example

You will find several files and subdirectories in the @code{mysql} directory.
The most important for installation purposes are the @file{bin} and
@file{scripts} subdirectories.

@table @file
@item bin
@tindex PATH environment variable
@tindex environment variable, PATH
This directory contains client programs and the server.
You should add the full pathname of this directory to your
@code{PATH} environment variable so that your shell finds the MySQL
programs properly. @xref{Environment variables}.

@item scripts
This directory contains the @command{mysql_install_db} script used to initialize
the @code{mysql} database containing the grant tables that store the server
access permissions.
@end table

@item
If you haven't installed MySQL before, you must create the MySQL grant tables:

@example
shell> scripts/mysql_install_db --user=mysql
@end example

If you run the command as @code{root}, you should use the @code{--user}
option as shown.  The value of the option should be the name of the login
account that you created in the first step to use for running the server.
If you run the command while logged in as that user, you can omit the
@code{--user} option.

Note that for MySQL versions older than 3.22.10,
@command{mysql_install_db} left the server running after creating the grant
tables.  This is no longer true; you will need to restart the server after
performing the remaining steps in this procedure.

@item
Change the ownership of program binaries to @code{root} and ownership of the
data directory to the user that you will run @command{mysqld} as.  Assuming
that you are located in the installation directory
(@file{/usr/local/mysql}), the commands look like this:

@example
shell> chown -R root  .
shell> chown -R mysql data
shell> chgrp -R mysql .
@end example

The first command changes the owner attribute of the files to the
@code{root} user. The second changes the owner attribute of the
data directory to the @code{mysql} user. The third changes the
group attribute to the @code{mysql} group.

@item
If you would like MySQL to start automatically when you boot your
machine, you can copy @code{support-files/mysql.server} to the location where
your system has its startup files.  More information can be found in the
@code{support-files/mysql.server} script itself and in
@ref{Automatic start}.

@item
@cindex adding, new users
@cindex new users, adding
@cindex users, adding
You can set up new accounts using the @command{bin/mysql_setpermission} script if
you install the @code{DBI} and @code{DBD::mysql} Perl modules.
For instructions, see @ref{Perl support}.

@item
If you would like to use @command{mysqlaccess} and have the MySQL
distribution in some non-standard place, you must change the location where
@command{mysqlaccess} expects to find the @command{mysql} client.  Edit the
@file{bin/mysqlaccess} script at approximately line 18.  Search for a line
that looks like this:

@example
$MYSQL     = '/usr/local/bin/mysql';    # path to mysql executable
@end example

Change the path to reflect the location where @code{mysql} actually is
stored on your system.  If you do not do this, you will get a @code{Broken
pipe} error when you run @command{mysqlaccess}.

@end enumerate

After everything has been unpacked and installed, you should
test your distribution.

You can start the MySQL server with the following command:

@example
shell> bin/mysqld_safe --user=mysql &
@end example

For versions of MySQL older than 4.0, substitute @command{bin/safe_mysqld}
for @command{bin/mysqld_safe} in the command.

More information about @command{mysqld_safe} is given in
@ref{mysqld_safe, , @command{mysqld_safe}}.

@strong{Note}:
The accounts that are listed in the MySQL grant tables initially have no
passwords.  After starting the server, you should set up passwords for
them using the instructions in @ref{Post-installation}.


@node Installing source, Post-installation, Installing binary, Installing
@section MySQL Installation Using a Source Distribution

@cindex installing, source distribution
@cindex source distribution, installing
@cindex installation overview

@c TODO: Needs intro to mention both Unix and Windows, and how to proceed.
@c Need better outline here. Most of the Unix sections should go under
@c a @subsection and be demoted to @subsubsection.

Before you proceed with the source installation, check first to see whether our
binary is available for your platform and whether it will work for you. We
put a lot of effort into making sure that our binaries are built with the
best possible options.

To obtain a source distribution for MySQL, @ref{Getting MySQL}.

MySQL source distributions are provided as compressed @command{tar}
archives and have names of the form @file{mysql-@var{VERSION}.tar.gz}, where
@var{VERSION} is a number like @code{@value{mysqlversion}}.

You need the following tools to build and install MySQL from source:

@itemize @bullet
@item
GNU @code{gunzip} to uncompress the distribution.

@item
A reasonable @command{tar} to unpack the distribution. GNU @command{tar} is known
to work. Some operating systems come with a pre-installed version of
@command{tar} that is known to have problems.  For example, Mac OS X @command{tar}
and Sun @command{tar} are known to have problems with long filenames.  On Mac
OS X, you can use the pre-installed @command{gnutar} program.  On other systems
with a deficient @command{tar}, you should install GNU @command{tar} first.

@item
A working ANSI C++ compiler.  @command{gcc} 2.95.2 or later, @command{egcs} 1.0.2
or later or @command{egcs 2.91.66}, SGI C++, and SunPro C++ are some of the
compilers that are known to work.  @code{libg++} is not needed when
using @command{gcc}.  @command{gcc} 2.7.x has a bug that makes it impossible
to compile some perfectly legal C++ files, such as
@file{sql/sql_base.cc}.  If you have only @command{gcc} 2.7.x, you must
upgrade your @command{gcc} to be able to compile MySQL. @command{gcc}
2.8.1 is also known to have problems on some platforms, so it should be
avoided if a new compiler exists for the platform.

@command{gcc} 2.95.2 or later is recommended when compiling MySQL
3.23.x.

@item
A good @command{make} program.  GNU @command{make} is always recommended and is
sometimes required.  If you have problems, we recommend trying GNU
@command{make} 3.75 or newer.
@end itemize

If you are using a version of @command{gcc} recent enough to understand the
@code{-fno-exceptions} option, it is @emph{very important} that you use
this option. Otherwise, you may compile a binary that crashes randomly. We also
recommend that you use @code{-felide-constructors} and @code{-fno-rtti} along
with @code{-fno-exceptions}. When in doubt, do the following:

@example
CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors \
       -fno-exceptions -fno-rtti" ./configure \
       --prefix=/usr/local/mysql --enable-assembler \
       --with-mysqld-ldflags=-all-static
@end example

On most systems, this will give you a fast and stable binary.

@c texi2html fails to split chapters if I use strong for all of this.
If you run into problems, @emph{please always use @command{mysqlbug}} when
posting questions to a MySQL mailing list.  Even if the problem
isn't a bug, @command{mysqlbug} gathers system information that will help others
solve your problem.  By not using @command{mysqlbug}, you lessen the likelihood
of getting a solution to your problem.  You will find @command{mysqlbug} in the
@file{scripts} directory after you unpack the distribution.
@xref{Bug reports}.

@menu
* Quick install::               Source Installation Overview
* configure options::           Typical @command{configure} Options
* Installing source tree::      Installing from the Development Source Tree
* Compilation problems::        Dealing with Problems Compiling MySQL
* MIT-pthreads::                MIT-pthreads Notes
* Windows source build::        Installing MySQL from Source on Windows
* Windows client compiling::    Compiling MySQL Clients on Windows
@end menu


@node Quick install, configure options, Installing source, Installing source
@subsection Source Installation Overview

The basic commands you must execute to install a MySQL source
distribution are:

@example
shell> groupadd mysql
shell> useradd -g mysql mysql
shell> gunzip < mysql-@var{VERSION}.tar.gz | tar -xvf -
shell> cd mysql-@var{VERSION}
shell> ./configure --prefix=/usr/local/mysql
shell> make
shell> make install
shell> cp support-files/my-medium.cnf /etc/my.cnf
shell> cd /usr/local/mysql
shell> bin/mysql_install_db --user=mysql
shell> chown -R root  .
shell> chown -R mysql var
shell> chgrp -R mysql .
shell> bin/mysqld_safe --user=mysql &
@end example

For versions of MySQL older than 4.0, substitute @command{bin/safe_mysqld}
for @command{bin/mysqld_safe} in the final command.

If you start from a source RPM, do the following:

@example
shell> rpmbuild --rebuild --clean MySQL-@var{VERSION}.src.rpm
@end example

This will make a binary RPM that you can install. For older versions of RPM,
you may have to replace the command @command{rpmbuild} with @command{rpm} instead.

@strong{Note}: This procedure does not set up any passwords for MySQL
accounts.  After following the procedure, proceed to @ref{Post-installation},
for post-installation setup and testing.

A more detailed version of the preceding description for installing
MySQL from a source distribution follows:

@enumerate

@item
Add a login user and group for @command{mysqld} to run as:

@example
shell> groupadd mysql
shell> useradd -g mysql mysql
@end example

These commands add the @code{mysql} group and the @code{mysql} user.  The
syntax for @command{useradd} and @command{groupadd} may differ slightly on different
versions of Unix.  They may also be called @command{adduser} and @command{addgroup}.

You might want to call the user and group something else instead
of @code{mysql}.  If so, substitute the appropriate name in the
following steps.

@item
Pick the directory under which you want to unpack the distribution, and
change location into it.

@item
Obtain a distribution file from one of the sites listed in
@ref{Getting MySQL, , Getting MySQL}.

@item
Unpack the distribution into the current directory:
@example
shell> gunzip < @var{/path/to/mysql-VERSION}.tar.gz | tar xvf -
@end example

This command creates a directory named @file{mysql-@var{VERSION}}.

With GNU @command{tar}, no separate invocation of @code{gunzip} is necessary.
You can use the following alternative command to uncompress and extract
the distribution:

@example
shell> tar zxvf @var{/path/to/mysql-VERSION-OS}.tar.gz
@end example

@item
Change location into the top-level directory of the unpacked distribution:

@example
shell> cd mysql-@var{VERSION}
@end example

Note that currently you must configure and build MySQL from
this top-level directory.  You cannot build it in a different
directory.

@item
Configure the release and compile everything:

@example
shell> ./configure --prefix=/usr/local/mysql
shell> make
@end example

When you run @command{configure}, you might want to specify some options.
Run @command{./configure --help} for a list of options.
@ref{configure options, , @command{configure} options}, discusses some of the
more useful options.

If @command{configure} fails and you are going to send mail to a MySQL mailing
list to ask for assistance, please include any
lines from @file{config.log} that you think can help solve the problem.  Also
include the last couple of lines of output from @command{configure}.
Post the bug report using the @command{mysqlbug}
script.  @xref{Bug reports}.

If the compile fails, see @ref{Compilation problems} for help.

@item
Install the distribution:

@example
shell> make install
@end example

If you want to set up an option file, use one of those present in the
@file{support-files} directory as a template. For example:

@example
shell> cp support-files/my-medium.cnf /etc/my.cnf
@end example

You might need to run these commands as @code{root}.

If you want to configure support for @code{InnoDB} tables, you should edit the
@code{/etc/my.cnf} file, remove the @code{#} character before the
option lines that start with @code{innodb_...}, and modify the option values
to be what you want.
See @ref{Option files}
and @ref{InnoDB configuration,  , @code{InnoDB} configuration}.

@item
Change location into the installation directory:

@example
shell> cd /usr/local/mysql
@end example

@item
If you haven't installed MySQL before, you must create the MySQL grant tables:

@example
shell> bin/mysql_install_db --user=mysql
@end example

If you run the command as @code{root}, you should use the @code{--user}
option as shown.  The value of the option should be the name of the login
account that you created in the first step to use for running the server.
If you run the command while logged in as that user, you can omit the
@code{--user} option.

Note that for MySQL versions older than 3.22.10,
@command{mysql_install_db} left the server running after creating the grant
tables.  This is no longer true; you will need to restart the server after
performing the remaining steps in this procedure.

@item
Change the ownership of program binaries to @code{root} and ownership of the
data directory to the user that you will run @command{mysqld} as.  Assuming
that you are located in the installation directory
(@file{/usr/local/mysql}), the commands look like this:

@example
shell> chown -R root  .
shell> chown -R mysql var
shell> chgrp -R mysql .
@end example

The first command changes the owner attribute of the files to the
@code{root} user. The second changes the owner attribute of the
data directory to the @code{mysql} user. The third changes the
group attribute to the @code{mysql} group.

@item
If you would like MySQL to start automatically when you boot your
machine, you can copy @code{support-files/mysql.server} to the location where
your system has its startup files.  More information can be found in the
@code{support-files/mysql.server} script itself and in
@ref{Automatic start}.

@item
@cindex adding, new users
@cindex new users, adding
@cindex users, adding
You can set up new accounts using the @command{bin/mysql_setpermission} script if
you install the @code{DBI} and @code{DBD::mysql} Perl modules.
For instructions, see @ref{Perl support}.

@end enumerate

After everything has been installed, you should initialize and test your
distribution using this command:

@example
shell> /usr/local/mysql/bin/mysqld_safe --user=mysql &
@end example

For versions of MySQL older than 4.0, substitute @command{safe_mysqld}
for @command{mysqld_safe} in the command.

If that command fails immediately and prints @code{mysqld ended}, you can
find some information in the @file{@var{host_name}.err} file in the data directory.

More information about @command{mysqld_safe} is given in
@ref{mysqld_safe, , @command{mysqld_safe}}.

@strong{Note}:
The accounts that are listed in the MySQL grant tables initially have no
passwords.  After starting the server, you should set up passwords for
them using the instructions in @ref{Post-installation}.


@node configure options, Installing source tree, Quick install, Installing source
@subsection Typical @command{configure} Options

@findex without-server option
@cindex @command{configure} script
@cindex options, @command{configure}
@cindex configuration options
@cindex log files
@cindex files, log

The @command{configure} script gives you a great deal of control over how
you configure a MySQL source distribution.  Typically you do this
using options on the @command{configure} command line.  You can also affect
@command{configure} using certain environment variables.  @xref{Environment
variables}.  For a list of options supported by @command{configure}, run
this command:

@example
shell> ./configure --help
@end example

Some of the more commonly used @command{configure} options are described here:

@itemize @bullet
@item
To compile just the MySQL client libraries and client programs and
not the server, use the @code{--without-server} option:

@example
shell> ./configure --without-server
@end example

@c FIX incorrect..

If you don't have a C++ compiler, @command{mysql} will not compile (it is the
one client program that requires C++).  In this case,
you can remove the code in @command{configure} that tests for the C++ compiler
and then run @command{./configure} with the @code{--without-server} option. The
compile step will still try to build @command{mysql}, but you can ignore any
warnings about @file{mysql.cc}.  (If @command{make} stops, try @command{make -k}
to tell it to continue with the rest of the build even if errors occur.)

@item
If you want to build the embedded MySQL library (@code{libmysqld.a}) you should
use the @code{--with-embedded-server} option.

@item
If you don't want your log files and database directories located under
@file{/usr/local/var}, use a @command{configure} command something like one
of these:

@example
shell> ./configure --prefix=/usr/local/mysql
shell> ./configure --prefix=/usr/local \
           --localstatedir=/usr/local/mysql/data
@end example

The first command changes the installation prefix so that everything is
installed under @file{/usr/local/mysql} rather than the default of
@file{/usr/local}.  The second command preserves the default installation
prefix, but overrides the default location for database directories
(normally @file{/usr/local/var}) and changes it to
@code{/usr/local/mysql/data}.  After you have compiled MySQL, you can
change these options with option files. @xref{Option files}.

@cindex changing socket location
@cindex socket location, changing
@cindex mysql.sock, changing location of
@item
If you are using Unix and you want the MySQL socket located somewhere
other than the default location (normally in the directory @file{/tmp} or
@file{/var/run}), use a @command{configure} command like this:

@example
shell> ./configure \
           --with-unix-socket-path=/usr/local/mysql/tmp/mysql.sock
@end example

The socket filename must be an absolute pathname.
You can also change the location of @file{mysql.sock} later by using a MySQL
option file. @xref{Problems with mysql.sock,  , Problems with @file{mysql.sock}}.

@cindex compiling, statically
@cindex statically, compiling
@item
If you want to compile statically linked programs (for example, to make a
binary distribution, to get more speed, or to work around problems with some
Red Hat Linux distributions), run @command{configure} like this:

@example
shell> ./configure --with-client-ldflags=-all-static \
           --with-mysqld-ldflags=-all-static
@end example



@tindex @code{CC} environment variable
@tindex environment variable, @code{CC}
@tindex @code{CXX} environment variable
@tindex environment variable, @code{CXX}
@cindex @command{gcc}
@cindex C++ compiler, @command{gcc}
@cindex compiler, C++ @command{gcc}
@item
If you are using @command{gcc} and don't have @code{libg++} or @code{libstdc++}
installed, you can tell @command{configure} to use @command{gcc} as your C++
compiler:

@example
shell> CC=gcc CXX=gcc ./configure
@end example

When you use @command{gcc} as your C++ compiler, it will not attempt to link in
@code{libg++} or @code{libstdc++}.  This may be a good idea to do even if you
have these libraries installed, because some versions of them have
caused strange problems for MySQL users in the past.

The following list indicates some compilers and environment variable settings
that are commonly used with each one.

@tindex CC environment variable
@tindex environment variable, CC
@tindex CXX environment variable
@tindex environment variable, CXX
@tindex CFLAGS environment variable
@tindex environment variable, CFLAGS
@tindex CXXFLAGS environment variable
@tindex environment variable, CXXFLAGS

@table @asis

@item @command{gcc} 2.7.2:

@example
CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors"
@end example

@item @command{egcs} 1.0.3a:

@example
CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors \
-fno-exceptions -fno-rtti"
@end example

@item @command{gcc} 2.95.2:

@example
CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro \
-felide-constructors -fno-exceptions -fno-rtti"
@end example

@item @code{pgcc} 2.90.29 or newer:

@example
CFLAGS="-O3 -mpentiumpro -mstack-align-double" CXX=gcc \
CXXFLAGS="-O3 -mpentiumpro -mstack-align-double \
-felide-constructors -fno-exceptions -fno-rtti"
@end example

@end table

In most cases, you can get a reasonably optimized MySQL binary by using the
options from the preceding list and adding the following options to the
@command{configure} line:

@example
--prefix=/usr/local/mysql --enable-assembler \
--with-mysqld-ldflags=-all-static
@end example

The full @command{configure} line would, in other words, be something like the
following for all recent @command{gcc} versions:

@example
CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro \
-felide-constructors -fno-exceptions -fno-rtti" ./configure \
--prefix=/usr/local/mysql --enable-assembler \
--with-mysqld-ldflags=-all-static
@end example

The binaries we provide on the MySQL Web site at
@uref{http://www.mysql.com/} are all compiled with full optimization and
should be perfect for most users.  @xref{MySQL binaries}.  There are some
configuration settings you can tweak to make an even faster binary, but these
are only for advanced users.  @xref{Compile and link options}.

If the build fails and produces errors about your compiler or linker not
being able to create the shared library @file{libmysqlclient.so.#} (where
@samp{#} is a version number), you can work around this problem by giving the
@code{--disable-shared} option to @command{configure}.  In this case,
@command{configure} will not build a shared @file{libmysqlclient.so.#} library.

@cindex character sets
@findex configure option, --with-charset
@findex configure option, --with-extra-charsets
@findex configure option, --with-collation
@item
By default, MySQL uses the @code{latin1} (ISO-8859-1) character set. To
change the default set, use the @code{--with-charset} option:
@example
shell> ./configure --with-charset=@var{CHARSET}
@end example
@var{CHARSET} may be one of @code{big5}, @code{cp1251}, @code{cp1257},
@code{czech}, @code{danish}, @code{dec8}, @code{dos}, @code{euc_kr},
@code{gb2312}, @code{gbk}, @code{german1}, @code{hebrew}, @code{hp8},
@code{hungarian}, @code{koi8_ru}, @code{koi8_ukr}, @code{latin1},
@code{latin2}, @code{sjis}, @code{swe7}, @code{tis620}, @code{ujis},
@code{usa7}, or @code{win1251ukr}.
@xref{Character sets}.

As of MySQL 4.1.1, the default collation may also be specified. MySQL uses
the @code{latin1_swedish_ci} collation. To change this, use the
@code{--with-collation} option:

@example
shell> ./configure --with-collation=COLLATION
@end example

To change both the character set and the collation, use both the
@code{--with-charset} and @code{--with-collation} options.
The collation must be a legal collation for the character set.
(Use the @code{SHOW COLLATION} statement to determine which collations are
available for each character set.)

If you want to convert characters between the server and the client,
you should take a look at the @code{SET CHARACTER SET} statement.
@xref{SET OPTION, , @code{SET}}.

@cindex @command{myisamchk}
@strong{Warning:} If you change character sets after having created any
tables, you will have to run @command{myisamchk -r -q --set-character-set=@var{charset}}
on every table. Your
indexes may be sorted incorrectly otherwise.  (This can happen if you
install MySQL, create some tables, then reconfigure
MySQL to use a different character set and reinstall it.)

With the @command{configure} option @code{--with-extra-charsets=@var{LIST}}, you can
define which additional character sets should be compiled into the server.
@var{LIST} is either a list of character set names separated by spaces,
@code{complex} to include all character sets that can't be dynamically loaded,
or @code{all} to include all character sets into the binaries.

@item
To configure MySQL with debugging code, use the @code{--with-debug}
option:
@example
shell> ./configure --with-debug
@end example
This causes a safe memory allocator to be included that can find some errors
and that provides output about what is happening.
@xref{Debugging server}.

@item
If your client programs are using threads, you also must compile a
thread-safe version of the MySQL client library with the
@code{--enable-thread-safe-client} configure option. This will create a
@code{libmysqlclient_r} library with which you should link your threaded
applications.  @xref{Threaded clients}.

@item
Options that pertain to particular systems can be found in the
system-specific section of this manual.
@xref{Operating System Specific Notes}.
@end itemize


@node Installing source tree, Compilation problems, configure options, Installing source
@subsection Installing from the Development Source Tree

@cindex development source tree
@cindex BitKeeper tree

@strong{Caution}: You should read this section only if you are interested
in helping us test our new code. If you just want to get MySQL up
and running on your system, you should use a standard release distribution
(either a binary or source distribution will do).

To obtain our most recent development source tree, use these instructions:

@enumerate
@item
Download BitKeeper from
@uref{http://www.bitmover.com/cgi-bin/download.cgi}.  You will need
Bitkeeper 3.0 or newer to access our repository.

@item
Follow the instructions to install it.

@item
After BitKeeper has been installed, first go to the directory you
want to work from, and then use one of the following commands to clone
the MySQL version branch of your choice:

To clone the old 3.23 branch, use this command:

@example
shell> bk clone bk://mysql.bkbits.net/mysql-3.23 mysql-3.23
@end example

To clone the 4.0 stable (production) branch, use this command:

@example
shell> bk clone bk://mysql.bkbits.net/mysql-4.0 mysql-4.0
@end example

To clone the 4.1 stable (production) branch, use this command:

@example
shell> bk clone bk://mysql.bkbits.net/mysql-4.1 mysql-4.1
@end example

To clone the 5.0 development branch, use this command:

@example
shell> bk clone bk://mysql.bkbits.net/mysql-5.0 mysql-5.0
@end example

In the preceding examples, the source tree will be set up in the
@file{mysql-3.23/}, @file{mysql-4.0/}, @file{mysql-4.1/}, or @file{mysql-5.0/}
subdirectory of your current directory.

If you are behind a firewall and can only initiate HTTP connections,
you can also use BitKeeper via HTTP.

If you are required to use a proxy server, set the environment
variable @code{http_proxy} to point to your proxy:

@example
shell> export http_proxy="http://your.proxy.server:8080/"
@end example

Now, simply replace the @code{bk://} with @code{http://} when doing
a clone. Example:

@example
shell> bk clone http://mysql.bkbits.net/mysql-4.1 mysql-4.1
@end example

The initial download of the source tree may take a while, depending on the
speed of your connection. Please be patient.

@item
You will need GNU @command{make}, @command{autoconf} 2.53 (or newer),
@command{automake} 1.5, @command{libtool} 1.5, and @command{m4} to run the next
set of commands. Even though many operating systems already come with their
own implementation of @command{make}, chances are high that the compilation
will fail with strange error messages. Therefore, it is highly recommended
that you use GNU @command{make} (sometimes named @command{gmake}) instead.

Fortunately, a large number of operating systems already ship with the GNU
toolchain preinstalled or supply installable packages of these. In any case,
they can also be downloaded from the following locations:

@itemize @bullet
@item
@uref{http://www.gnu.org/software/autoconf/}
@item
@uref{http://www.gnu.org/software/automake/}
@item
@uref{http://www.gnu.org/software/libtool/}
@item
@uref{http://www.gnu.org/software/m4/}
@item
@uref{http://www.gnu.org/software/make/}
@end itemize

If you are trying to configure MySQL 4.1 or later, you will also need GNU
@command{bison} 1.75 or later.  Older versions of @command{bison} may report this
error:

@example
sql_yacc.yy:#####: fatal error: maximum table size (32767) exceeded
@end example

Note: The maximum table size is not actually exceeded;
the error is caused by bugs in older versions of @command{bison}.

Versions of MySQL before version 4.1 may also compile with other
@command{yacc} implementations (for example, BSD @command{yacc} 91.7.30). For later
versions, GNU @command{bison} is required.

The following example shows the typical commands required to configure a
source tree. The first @code{cd} command changes location into the top-level
directory of the tree; replace @file{mysql-4.0} with the appropriate directory
name.

@example
shell> cd mysql-4.0
shell> bk -r edit
shell> aclocal; autoheader; autoconf; automake
shell> (cd innobase; aclocal; autoheader; autoconf; automake)
shell> (cd bdb/dist; sh s_all)
shell> ./configure  # Add your favorite options here
make
@end example

The command lines that change directory into the @file{innobase} and
@file{bdb/dist} directories are used to configure the @code{InnoDB} and
Berkeley DB (@code{BDB}) storage engines.  You can omit these command lines if
you to not require @code{InnoDB} or @code{BDB} support.

If you get some strange errors during this stage, verify that you really
have @command{libtool} installed.

A collection of our standard configuration scripts is located in the
@file{BUILD/} subdirectory.  You may find it more convenient to use the
@file{BUILD/compile-pentium-debug} script than the preceding set of
shell commands. To compile on a different architecture,
modify the script by removing flags that are Pentium-specific.

@item
When the build is done, run @command{make install}.  Be careful with this
on a production machine; the command may overwrite your live release
installation.  If you have another installation of MySQL, we
recommend that you run @command{./configure} with different values for the
@code{--prefix}, @code{--with-tcp-port}, and @code{--unix-socket-path} options
than those used for your production server.

@item
Play hard with your new installation and try to make the new features
crash.  Start by running @command{make test}.  @xref{MySQL test suite}.

@item
If you have gotten to the @command{make} stage and the distribution does
not compile, please report it in our bugs database at
@uref{http://bugs.mysql.com/}.  If you
have installed the latest versions of the required GNU tools, and they
crash trying to process our configuration files, please report that also.
However, if you execute @code{aclocal} and get a @code{command not found}
error or a similar problem, do not report it.  Instead, make sure that all
the necessary tools are installed and that your @code{PATH} variable is
set correctly so that your shell can find them.

@item
After the initial @code{bk clone} operation to obtain the source tree, you
should run @code{bk pull} periodically to get updates.

@item
You can examine the change history for the tree with all the diffs by using
@code{bk revtool}.  If you see some funny diffs or code that you have a
question about, do not hesitate to send email to the MySQL @code{internals}
mailing list.
@xref{Mailing-list}.
Also, if you think you have a better idea
on how to do something, send an email message to the same address with a patch.
@code{bk diffs} will produce a patch for you after you have made changes
to the source. If you do not have the time to code your idea, just send
a description.

@item
BitKeeper has a nice help utility that you can access via
@code{bk helptool}.

@item
Please note that any commits (made via @code{bk ci} or @code{bk citool}) will
trigger the posting of a message with the changeset to our internals
mailing list, as well as the usual openlogging.org submission with
just the changeset comments.
Generally, you wouldn't need to use commit (since the public tree will
not allow @code{bk push}), but rather use the @code{bk diffs} method
described previously.

@end enumerate

You can also browse changesets, comments, and source code online. For example,
to browse this information for MySQL 4.1, go to
@uref{http://mysql.bkbits.net:8080/mysql-4.1}.

The manual is in a separate tree that can be cloned with:

@example
shell> bk clone bk://mysql.bkbits.net/mysqldoc mysqldoc
@end example

There are also public BitKeeper trees for MySQL Control Center and
MyODBC. They can be cloned respectively as follows.

To clone MySQL Control center, use this command:

@example
shell> bk clone http://mysql.bkbits.net/mysqlcc mysqlcc
@end example

To clone MyODBC, use this command:

@example
shell> bk clone http://mysql.bkbits.net/myodbc3 myodbc3
@end example

To clone Connector/NET, use this command:

@example
shell> bk clone http://mysql.bkbits.net/connector-net connector-net
@end example


@node Compilation problems, MIT-pthreads, Installing source tree, Installing source
@subsection Dealing with Problems Compiling MySQL

@cindex compiling, problems
@cindex problems, compiling
@cindex reconfiguring
@cindex @code{config.cache} file
@cindex files, @code{config.cache}

All MySQL programs compile cleanly for us with no warnings on
Solaris or Linux using @command{gcc}.  On other systems, warnings may occur due to
differences in system include files.  See @ref{MIT-pthreads} for warnings
that may occur when using MIT-pthreads.  For other problems, check
the following list.

The solution to many problems involves reconfiguring.  If you do need to
reconfigure, take note of the following:

@cindex running @command{configure} after prior invocation
@cindex @command{configure}, running after prior invocation
@cindex reconfiguring
@cindex config.cache
@itemize @bullet
@item
If @command{configure} is run after it already has been run, it may use
information that was gathered during its previous invocation.  This
information is stored in @file{config.cache}.  When @command{configure} starts
up, it looks for that file and reads its contents if it exists, on the
assumption that the information is still correct.  That assumption is invalid
when you reconfigure.

@item
Each time you run @command{configure}, you must run @command{make} again
to recompile.  However, you may want to remove old object files from previous
builds first because they were compiled using different configuration options.
@end itemize

To prevent old configuration information or object files from being used,
run these commands before re-running @command{configure}:

@example
shell> rm config.cache
shell> make clean
@end example

Alternatively, you can run @command{make distclean}.

The following list describes some of the problems when compiling MySQL
that have been found to occur most often:

@itemize @bullet
@item
@cindex @code{cc1plus} problems
@cindex @code{fatal signal 11}
@cindex @code{sql_yacc.cc} problems
@cindex internal compiler errors
@cindex virtual memory, problems while compiling
@cindex configure option, --with-low-memory
If you get errors such as the ones shown here when compiling
@file{sql_yacc.cc}, you probably have run out of memory or swap space:

@example
Internal compiler error: program cc1plus got fatal signal 11
Out of virtual memory
Virtual memory exhausted
@end example

The problem is that @command{gcc} requires a huge amount of memory to compile
@file{sql_yacc.cc} with inline functions.  Try running @command{configure} with
the @code{--with-low-memory} option:

@example
shell> ./configure --with-low-memory
@end example

This option causes @code{-fno-inline} to be added to the compile line if you
are using @command{gcc} and @code{-O0} if you are using something else.  You
should try the @code{--with-low-memory} option even if you have so much
memory and swap space that you think you can't possibly have run out.  This
problem has been observed to occur even on systems with generous hardware
configurations and the @code{--with-low-memory} option usually fixes it.

@item
By default, @command{configure} picks @command{c++} as the compiler name and
GNU @command{c++} links with @code{-lg++}.  If you are using @command{gcc},
that behavior can cause problems during configuration such as this:

@cindex C++ compiler cannot create executables
@example
configure: error: installation or configuration problem:
C++ compiler cannot create executables.
@end example

@tindex CXX environment variable
@tindex Environment variable, CXX
You might also observe problems during compilation related to
@command{g++}, @code{libg++}, or @code{libstdc++}.

One cause of these problems is that you may not have @command{g++}, or you may
have @command{g++} but not @code{libg++}, or @code{libstdc++}.  Take a look at
the @file{config.log} file.  It should contain the exact reason why your C++
compiler didn't work.  To work around these problems, you can use @command{gcc}
as your C++ compiler.  Try setting the environment variable @code{CXX} to
@code{"gcc -O3"}.  For example:

@tindex CXX environment variable
@tindex Environment variables, CXX
@example
shell> CXX="gcc -O3" ./configure
@end example

This works because @command{gcc} compiles C++ sources as well as @command{g++}
does, but does not link in @code{libg++} or @code{libstdc++} by default.

Another way to fix these problems is to install @command{g++},
@code{libg++}, and @code{libstdc++}.  We would, however, like to recommend
that you not use @code{libg++} or @code{libstdc++} with MySQL because this will
only increase the binary size of @command{mysqld} without giving you any benefits.
Some versions of these libraries have also caused strange problems for
MySQL users in the past.

@cindex RAID, compile errors
@cindex @code{--with-raid} link errors
Using @command{gcc} as the C++ compiler is also required if you want to
compile MySQL with RAID functionality (see @ref{CREATE TABLE} for more info
on RAID table type) and you are using GNU @command{gcc} version 3 and above. If
you get errors like those following during the linking stage when you
configure MySQL to compile with the option @code{--with-raid}, try to use
@command{gcc} as your C++ compiler by defining the @code{CXX} environment
variable:

@example
gcc -O3 -DDBUG_OFF -rdynamic -o isamchk isamchk.o sort.o  libnisam.a
../mysys/libmysys.a ../dbug/libdbug.a ../strings/libmystrings.a
 -lpthread -lz -lcrypt -lnsl -lm -lpthread
../mysys/libmysys.a(raid.o)(.text+0x79): In function
`my_raid_create':: undefined reference to `operator new(unsigned)'
../mysys/libmysys.a(raid.o)(.text+0xdd): In function
`my_raid_create':: undefined reference to `operator delete(void*)'
../mysys/libmysys.a(raid.o)(.text+0x129): In function
`my_raid_open':: undefined reference to `operator new(unsigned)'
../mysys/libmysys.a(raid.o)(.text+0x189): In function
`my_raid_open':: undefined reference to `operator delete(void*)'
../mysys/libmysys.a(raid.o)(.text+0x64b): In function
`my_raid_close':: undefined reference to `operator delete(void*)'
collect2: ld returned 1 exit status
@end example

@item
If your compile fails with errors such as any of the following,
you must upgrade your version of @command{make} to GNU @command{make}:

@example
making all in mit-pthreads
make: Fatal error in reader: Makefile, line 18:
Badly formed macro assignment
@end example
Or:
@example
make: file `Makefile' line 18: Must be a separator (:
@end example
Or:
@example
pthread.h: No such file or directory
@end example

@cindex Solaris troubleshooting
@cindex FreeBSD troubleshooting
@cindex troubleshooting, Solaris
@cindex troubleshooting, FreeBSD
Solaris and FreeBSD are known to have troublesome @command{make} programs.

GNU @command{make} Version 3.75 is known to work.

@tindex CC environment variable
@tindex environment variable, CC
@tindex CXX environment variable
@tindex environment variable, CXX
@tindex CFLAGS environment variable
@tindex environment variable, CFLAGS
@tindex CXXFLAGS environment variable
@tindex environment variable, CXXFLAGS
@item
If you want to define flags to be used by your C or C++ compilers, do so by
adding the flags to the @code{CFLAGS} and @code{CXXFLAGS} environment
variables.  You can also specify the compiler names this way using @code{CC}
and @code{CXX}.  For example:

@example
shell> CC=gcc
shell> CFLAGS=-O3
shell> CXX=gcc
shell> CXXFLAGS=-O3
shell> export CC CFLAGS CXX CXXFLAGS
@end example

See @ref{MySQL binaries}, for a list of flag definitions that have been found
to be useful on various systems.

@item
If you get an error message like this,
you need to upgrade your @command{gcc} compiler:

@example
client/libmysql.c:273: parse error before `__attribute__'
@end example

@command{gcc} 2.8.1 is known to work, but we recommend using @command{gcc} 2.95.2 or
@command{egcs} 1.0.3a instead.

@item
If you get errors such as those shown here when compiling @command{mysqld},
@command{configure} didn't correctly detect the type of the last argument to
@code{accept()}, @code{getsockname()}, or @code{getpeername()}:

@example
cxx: Error: mysqld.cc, line 645: In this statement, the referenced
     type of the pointer value ''length'' is ''unsigned long'',
     which is not compatible with ''int''.
new_sock = accept(sock, (struct sockaddr *)&cAddr, &length);
@end example

To fix this, edit the @file{config.h} file (which is generated by
@command{configure}).  Look for these lines:

@example
/* Define as the base type of the last arg to accept */
#define SOCKET_SIZE_TYPE XXX
@end example

Change @code{XXX} to @code{size_t} or @code{int}, depending on your
operating system.  (Note that you will have to do this each time you run
@command{configure} because @command{configure} regenerates @file{config.h}.)

@item
The @file{sql_yacc.cc} file is generated from @file{sql_yacc.yy}.  Normally
the build process doesn't need to create @file{sql_yacc.cc}, because
MySQL comes with an already generated copy.  However, if you do need
to re-create it, you might encounter this error:

@example
"sql_yacc.yy", line @var{xxx} fatal: default action causes potential...
@end example

This is a sign that your version of @command{yacc} is deficient.
You probably need to install @command{bison} (the GNU version of @command{yacc})
and use that instead.

@item
On Debian Linux 3.0, you need to install @code{gawk} instead of the default
@code{mawk} if you want to compile MySQL 4.1 or higher with Berkeley DB
support.

@item
If you need to debug @command{mysqld} or a MySQL client, run
@command{configure} with the @code{--with-debug} option, then recompile and
link your clients with the new client library.  @xref{Debugging client}.

@item
If you get a compilation error on Linux (for example, SuSE Linux 8.1 or Red Hat
Linux 7.3) similar to the following one:

@example
libmysql.c:1329: warning: passing arg 5 of `gethostbyname_r' from
incompatible pointer type
libmysql.c:1329: too few arguments to function `gethostbyname_r'
libmysql.c:1329: warning: assignment makes pointer from integer
without a cast
make[2]: *** [libmysql.lo] Error 1
@end example

By default, the @command{configure} script attempts to determine the correct
number of arguments by using @command{g++} the GNU C++ compiler. This test
yields wrong results if @command{g++} is not installed. There are two ways
to work around this problem:

@itemize @bullet
@item
Make sure that the GNU C++ @command{g++} is installed. On some Linux
distributions, the required package is called @code{gpp}; on others, it
is named @command{gcc-c++}.
@item
Use @command{gcc} as your C++ compiler by setting the @code{CXX} environment
variable to @command{gcc}:
@example
export CXX="gcc"
@end example
@end itemize

Please note that you need to run @command{configure} again afterward.

@end itemize


@node MIT-pthreads, Windows source build, Compilation problems, Installing source
@subsection MIT-pthreads Notes

@cindex MIT-pthreads
@cindex thread support, non-native

This section describes some of the issues involved in using MIT-pthreads.

On Linux, you should @emph{not} use MIT-pthreads. Use the
installed LinuxThreads implementation instead.
@xref{Linux}.

If your system does not provide native thread support, you will need to
build MySQL using the MIT-pthreads package.  This includes
older FreeBSD systems, SunOS 4.x, Solaris 2.4 and earlier, and some others.
@xref{Which OS}.

Beginning with MySQL 4.0.2, MIT-pthreads is no longer part of
the source distribution. If you require this package, you need to download
it separately from
@uref{http://www.mysql.com/Downloads/Contrib/pthreads-1_60_beta6-mysql.tar.gz}

After downloading, extract this source archive into the top level of the
MySQL source directory. It will create a new subdirectory named
@code{mit-pthreads}.

@itemize @bullet
@item
On most systems, you can force MIT-pthreads to be used by running
@command{configure} with the @code{--with-mit-threads} option:

@example
shell> ./configure --with-mit-threads
@end example

Building in a non-source directory is not supported when using
MIT-pthreads because we want to minimize our changes to this code.

@item
The checks that determine whether to use MIT-pthreads occur only
during the part of the configuration process that deals with the server
code.  If you have configured the distribution using @code{--without-server}
to build only the client code, clients will not know whether
MIT-pthreads is being used and will use Unix socket connections by default.
Because Unix socket files do not work under MIT-pthreads on some platforms, this
means you will need to use @code{-h} or @code{--host} when you run client
programs.

@item
When MySQL is compiled using MIT-pthreads, system locking is
disabled by default for performance reasons.  You can tell the server to use
system locking with the @code{--external-locking} option.  This is needed
only if you want to be able to run two MySQL servers against the same data
files, which is not recommended.

@item
Sometimes the pthread @code{bind()} command fails to bind to a socket without
any error message (at least on Solaris).  The result is that all connections
to the server fail.  For example:

@example
shell> mysqladmin version
mysqladmin: connect to server at '' failed;
error: 'Can't connect to mysql server on localhost (146)'
@end example

The solution to this is to kill the @command{mysqld} server and restart it.
This has only happened to us when we have forced down the server and done
a restart immediately.

@item
With MIT-pthreads, the @code{sleep()} system call isn't interruptible with
@code{SIGINT} (break).  This is only noticeable when you run
@command{mysqladmin --sleep}.  You must wait for the @code{sleep()} call to
terminate before the interrupt is served and the process stops.

@item
When linking, you may receive warning messages like these (at least on
Solaris); they can be ignored:

@example
ld: warning: symbol `_iob' has differing sizes:
    (file /my/local/pthreads/lib/libpthread.a(findfp.o) value=0x4;
file /usr/lib/libc.so value=0x140);
    /my/local/pthreads/lib/libpthread.a(findfp.o) definition taken
ld: warning: symbol `__iob' has differing sizes:
    (file /my/local/pthreads/lib/libpthread.a(findfp.o) value=0x4;
file /usr/lib/libc.so value=0x140);
    /my/local/pthreads/lib/libpthread.a(findfp.o) definition taken
@end example

@item
Some other warnings also can be ignored:

@example
implicit declaration of function `int strtoll(...)'
implicit declaration of function `int strtoul(...)'
@end example

@item
We haven't gotten @code{readline} to work with MIT-pthreads.  (This isn't
needed, but may be interesting for someone.)
@end itemize


@node Windows source build, Windows client compiling, MIT-pthreads, Installing source
@subsection Installing MySQL from Source on Windows

These instructions describe how to build MySQL binaries from source
for versions 4.1 and above on Windows. Instructions are provided
for building binaries from a standard source distribution or from
the BitKeeper tree that contains the latest development source.

@strong{Note}:
The instructions in this document are strictly for users who want
to test MySQL on Windows from the latest source distribution or
from the BitKeeper tree.  For production use, MySQL AB does not
advise using a MySQL server built by yourself from source.  Normally,
it is best to use precompiled binary distributions of MySQL that
are built specifically for optimal performance on Windows by MySQL
AB.  Instructions for installing a binary distributions are available
at @ref{Windows installation}.

To build MySQL on Windows from source, you need the following
compiler and resources available on your Windows system:

@itemize @bullet
@item
VC++ 6.0 compiler (updated with 4 or 5 SP and pre-processor package).
The pre-processor package is necessary for the macro assembler.
More details can be found at
@uref{http://msdn.microsoft.com/vstudio/downloads/updates/sp/vs6/sp5/faq.aspx}.

@item
Approximately 45MB disk space.

@item
64MB RAM.

@end itemize

You'll also need a MySQL source distribution for Windows.  There
are two ways you can get a source distribution for MySQL version
4.1 and above:

@enumerate
@item
Obtain a source distribution packaged by MySQL AB for the particular
version of MySQL in which you are interested.  Prepackaged source
distributions are available for released versions of MySQL and can
be obtained from @uref{http://dev.mysql.com/downloads/}.

@item
You can package a source distribution yourself from the latest
BitKeeper developer source tree. If you plan to do this, you must
create the package on a Unix system and then transfer it to your
Windows system.  (The reason for this is that some of the configuration
and build steps require tools that work only on Unix.)  The BitKeeper
approach thus requires:

@itemize @bullet
@item
A system running Unix, or a Unix-like system such as Linux.

@item
BitKeeper 3.0 installed on that system. You can obtain
BitKeeper from @uref{http://www.bitkeeper.com/}.

@end itemize

@end enumerate

If you are using a Windows source distribution, you can go directly to
@ref{Windows VC++ Build}. To build from the BitKeeper tree, proceed to
@ref{Windows BitKeeper Build}.

If you find something not working as expected, or you have
suggestions about ways to improve the current build process
on Windows, please send a message to the @code{win32} mailing list.
@xref{Mailing-list}.

@menu
* Windows VC++ Build::          Building MySQL Using VC++
* Windows BitKeeper Build::     Creating a Windows Source Package from the Latest Development Source
@end menu


@node Windows VC++ Build, Windows BitKeeper Build, Windows source build, Windows source build
@subsubsection Building MySQL Using VC++

@strong{Note}:
VC++ workspace files for MySQL 4.1 and above are compatible with
Microsoft Visual Studio 6.0 and above (7.0/.NET) editions and tested
by MySQL AB staff before each release.

Follow this procedure to build MySQL:

@enumerate
@item
Create a work directory (for example, @file{C:\workdir}).
@item
Unpack the source distribution in the aforementioned directory using
@code{WinZip} or other Windows tool that can read @file{.zip} files.
@item
Start the VC++ 6.0 compiler.
@item
In the @code{File} menu, select @code{Open Workspace}.
@item
Open the @file{mysql.dsw} workspace you find in the work directory.
@item
From the @code{Build} menu,
select the @code{Set Active Configuration} menu.
@item
Click over the screen selecting @code{mysqld - Win32 Debug}
and click OK.
@item
Press @code{F7} to begin the build of the debug server, libraries, and
some client applications.
@c @item
@c When the compilation finishes, copy the libraries and the executables
@c to a separate directory.
@item
Compile the release versions that you want in the same way.
@item
Debug versions of the programs and libraries are placed in the
@file{client_debug} and @file{lib_debug} directories.
Release versions of the programs and libraries are placed in the
@file{client_release} and @file{lib_release} directories.
Note that if you want to build both debug and release versions,
you can select the @code{Build All} option from the @code{Build} menu.
@item
Test the server.  The server built using the preceding instructions
will expect that the MySQL base directory and data directory are
@file{C:\mysql} and @file{C:\mysql\data} by default. If you want
to test your server using the source tree root directory and its
data directory as the base directory and data directory, you will
need to tell the server their pathnames. You can either do this on
the command line with the @code{--basedir} and @code{--datadir}
options, or place appropriate options in an option file (the @file{my.ini}
file in your Windows directory or @file{C:\my.cnf}).  If you have
an existing data directory elsewhere that you want to use, you can
specify its pathname instead.
@item
Start your server from the @file{client_release} or @file{client_debug}
directory, depending on which server you want to use. The
general server startup instructions are at @ref{Windows installation}.
You'll need to adapt the instructions appropriately if you
want to use a different base directory or data directory.
@item
When the server is running in standalone fashion or as a service
based on your configuration, try to connect to it from the @command{mysql}
interactive command-line utility that exists in your @file{client_release}
or @file{client_debug} directory.

@end enumerate

When you are satisfied that the programs you have built are working
correctly, stop the server. Then install MySQL as follows:

@enumerate
@item
Create the directories where you want to install MySQL.  For example,
to install into
@file{C:\mysql}, use these commands:

@example
C:\> mkdir C:\mysql
C:\> mkdir C:\mysql\bin
C:\> mkdir C:\mysql\data
C:\> mkdir C:\mysql\share
C:\> mkdir C:\mysql\scripts
@end example

If you want to compile other clients and link them to MySQL, you should
also create several additional directories:

@example
C:\> mkdir C:\mysql\include
C:\> mkdir C:\mysql\lib
C:\> mkdir C:\mysql\lib\debug
C:\> mkdir C:\mysql\lib\opt
@end example

If you want to benchmark MySQL, create this directory:

@example
C:\> mkdir C:\mysql\sql-bench
@end example

Benchmarking requires Perl support.

@item
From the @file{workdir} directory, copy into the @code{C:\mysql} directory the
following directories:

@example
C:\> cd \workdir
C:\workdir> copy client_release\*.exe C:\mysql\bin
C:\workdir> copy client_debug\mysqld.exe C:\mysql\bin\mysqld-debug.exe
C:\workdir> xcopy scripts\*.* C:\mysql\scripts /E
C:\workdir> xcopy share\*.* C:\mysql\share /E
@end example

If you want to compile other clients and link them to MySQL, you should
also copy several libraries and header files:

@example
C:\workdir> copy lib_debug\mysqlclient.lib C:\mysql\lib\debug
C:\workdir> copy lib_debug\libmysql.* C:\mysql\lib\debug
C:\workdir> copy lib_debug\zlib.* C:\mysql\lib\debug
C:\workdir> copy lib_release\mysqlclient.lib C:\mysql\lib\opt
C:\workdir> copy lib_release\libmysql.* C:\mysql\lib\opt
C:\workdir> copy lib_release\zlib.* C:\mysql\lib\opt
C:\workdir> copy include\*.h C:\mysql\include
C:\workdir> copy libmysql\libmysql.def C:\mysql\include
@end example

If you want to benchmark MySQL, you should also do this:

@example
C:\workdir> xcopy sql-bench\*.* C:\mysql\bench /E
@end example

@end enumerate

Set up and start the server in the same way as for the binary
Windows distribution.
@xref{Windows installation}.


@node Windows BitKeeper Build,  , Windows VC++ Build, Windows source build
@subsubsection Creating a Windows Source Package from the Latest Development Source


To create a Windows source package from the current
BitKeeper source tree, use the following instructions. Please
note that this procedure must be performed on a system
running a Unix or Unix-like operating system.  For example, the procedure
is known to work well on Linux.

@enumerate
@item
Clone the BitKeeper source tree for MySQL (version 4.1 or above,
as desired).  For more information on how to clone the source tree,
see the instructions at @ref{Installing source tree}.

@item
Configure and build the distribution so that you have a server
binary to work with.  One way to do this is to run the following
command in the top-level directory of your source tree:

@example
shell> ./BUILD/compile-pentium-max
@end example

@item
After making sure that the build process completed successfully,
run the following utility script from top-level directory of your
source tree:

@example
shell> ./scripts/make_win_src_distribution
@end example

This script creates a Windows source package to be used on your
Windows system.  You can supply different options to the script
based on your needs. It accepts the following options:

@table @code
@item --help
Display a help message.

@item --debug
Print information about script operations, do not create package.

@item --tmp
Specify the temporary location.

@item --suffix
Suffix name for the package.

@item --dirname
Directory name to copy files (intermediate).

@item --silent
Do not print verbose list of files processed.

@item --tar
Create @file{tar.gz} package instead of @file{.zip} package.
@end table

By default, @command{make_win_src_distribution} creates a Zip-format
archive with the name @file{mysql-@var{VERSION}-win-src.zip}, where
@var{VERSION} represents the version of your MySQL source tree.

@item
Copy or upload to your Windows machine the Windows source package
that you have just created. To compile it, use the instructions in
@ref{Windows VC++ Build}.

@end enumerate


@node Windows client compiling,  , Windows source build, Installing source
@subsection Compiling MySQL Clients on Windows

@cindex compiling, on Windows
@cindex Windows, compiling on

In your source files, you should include @file{my_global.h} before
@file{mysql.h}:

@example
#include <my_global.h>
#include <mysql.h>
@end example

@file{my_global.h} includes any other files needed for Windows compatibility
(such as @file{windows.h}) if you compile your program on Windows.

You can either link your code with the dynamic @file{libmysql.lib} library,
which is just a wrapper to load in @file{libmysql.dll} on demand, or link
with the static @file{mysqlclient.lib} library.

The MySQL client libraries are compiled as threaded
libraries, so you should also compile your code to be multi-threaded.


@node Post-installation, Upgrade, Installing source, Installing
@section Post-Installation Setup and Testing

@cindex post-installation, setup and testing
@cindex testing, post-installation
@cindex setup, post-installation

After installing MySQL, there are some issues you should address.  For
example, on Unix, you should initialize the data directory and create the
MySQL grant tables.  On all platforms, an important security concern is that
the initial accounts in the grant tables have no passwords.  You should
assign passwords to prevent unauthorized access to the MySQL server.
For MySQL 4.1.3 and up, you can create time zone tables to enable recognition
of named time zones. (Currently, these tables can be populated only on
Unix. This problem will be addressed soon for Windows.)

The following sections include post-installation procedures that are specific
to Windows systems and to Unix systems. Another section, @ref{Starting
server}, applies to all platforms; it describes what to do if you have
trouble getting the server to start.  @ref{Default privileges} also applies
to all platforms. You should follow its instructions to make sure that you
have properly protected your MySQL accounts by assigning passwords to them.

When you are ready to create additional user accounts, you can find
information on the MySQL access control system and account management in
@ref{Privilege system} and @ref{User Account Management}.

@menu
* Windows post-installation::   Windows Post-Installation Procedures
* Unix post-installation::      Unix Post-Installation Procedures
* Default privileges::          Securing the Initial MySQL Accounts
@end menu

@node Windows post-installation, Unix post-installation, Post-installation, Post-installation
@subsection Windows Post-Installation Procedures

On Windows, the data directory and the grant tables do not have to be
created. MySQL Windows distributions include the grant tables already set up
with a set of preinitialized accounts in the @code{mysql} database under the
data directory. You do not run the @command{mysql_install_db} script that
is used on Unix.  However, if you did not install MySQL using the Windows Installation Wizard,
you should assign passwords to the accounts. @xref{mysql-install-wizard-introduction}.
The procedure for this is given in @ref{Default privileges}.

Before setting up passwords, you might want to try running some client
programs to make sure that you can connect to the server and that it is
operating properly.  Make sure the server is running (@pxref{Windows server
first start}), then issue the following commands to verify that you can
retrieve information from the server.  The output should be similar to
what is shown here:

@example
C:\> C:\mysql\bin\mysqlshow
+-----------+
| Databases |
+-----------+
| mysql     |
| test      |
+-----------+

C:\> C:\mysql\bin\mysqlshow mysql
Database: mysql
+--------------+
|    Tables    |
+--------------+
| columns_priv |
| db           |
| func         |
| host         |
| tables_priv  |
| user         |
+--------------+

C:\> C:\mysql\bin\mysql -e "SELECT Host,Db,User FROM db" mysql
+------+-------+------+
| host | db    | user |
+------+-------+------+
| %    | test% |      |
+------+-------+------+
@end example

If you are running a version of Windows that supports services and you want
the MySQL server to run automatically when Windows starts, see @ref{Windows
start service}.


@node Unix post-installation, Default privileges, Windows post-installation, Post-installation
@subsection Unix Post-Installation Procedures

@menu
* mysql_install_db::            Problems Running @command{mysql_install_db}
* Automatic start::             Starting and Stopping MySQL Automatically
* Starting server::             Starting and Troubleshooting the MySQL Server
@end menu

@c TODO: Many of the testing commands actually are not specific to Unix,
@c so they could be split out into a platform-neutral testing procedure...

After installing MySQL on Unix, you need to initialize the grant tables,
start the server, and make sure that the server works okay.  You may also
wish to arrange for the server to be started and stopped automatically when
your system starts and stops.  You should also assign passwords to the
accounts in the grant tables.

On Unix, the grant tables are set up by the @command{mysql_install_db} program.
For some installation methods, this program is run for you automatically:

@itemize @bullet
@item
If you install MySQL on Linux using RPM distributions, the server RPM runs
@command{mysql_install_db}.
@item
If you install MySQL on Mac OS X using a PKG distribution, the installer runs
@command{mysql_install_db}.
@end itemize

Otherwise, you'll need to run @command{mysql_install_db} yourself.

The following procedure describes how to initialize the grant tables (if
that has not already been done) and then start the server. It also suggests
some commands that you can use to test whether the server is accessible
and working properly.  For information about starting and stopping the
server automatically, see @ref{Automatic start}.

After you complete the procedure and have the server running, you should
assign passwords to the accounts created by @command{mysql_install_db}.
Instructions for doing so are given in @ref{Default privileges}.

In the examples shown here, the server runs under the user ID of the
@code{mysql} login account. This assumes that such an account exists.
Either create the account if it does not exist, or substitute the name of a
different existing login account that you plan to use for running the
server.

@cindex starting, the server
@cindex server, starting
@cindex testing, installation

@enumerate
@item
Change location into the top-level directory of your MySQL installation,
represented here by @var{BASEDIR}:

@example
shell> cd @var{BASEDIR}
@end example

@var{BASEDIR} is likely to be something like @file{/usr/local/mysql} or
@file{/usr/local}.  The following steps assume that you are located in this
directory.

@item
If necessary, run the @command{mysql_install_db} program to set up the initial
MySQL grant tables containing the privileges that determine how users are
allowed to connect to the server. You'll need to do this if you used a
distribution type that doesn't run the program for you.

Typically, @command{mysql_install_db} needs to be run only the first time you
install MySQL, so you can skip this step if you are upgrading an existing
installation, However, @command{mysql_install_db} does not overwrite any
existing privilege tables, so it should be safe to run in any circumstances.

To initialize the grant tables, use one of the following commands,
depending on whether @command{mysql_install_db} is located in the @code{bin}
or @code{scripts} directory:

@example
shell> bin/mysql_install_db --user=mysql
shell> scripts/mysql_install_db --user=mysql
@end example

The @command{mysql_install_db} script creates the data directory, the
@code{mysql} database that holds all database privileges, and the @code{test}
database that you can use to test MySQL. The script also creates privilege
table entries for @code{root} accounts and anonymous-user accounts.
The accounts have no passwords initially.  A description of their initial
privileges is given in @ref{Default privileges}.  Briefly, these privileges
allow the MySQL @code{root} user to do anything, and allow anybody to create
or use databases with a name of @code{test} or starting with @code{test_}.

It is important to make sure that the database directories and files are
owned by the @code{mysql} login account so that the server has read and
write access to them when you run it later. To ensure this, the @code{--user}
option should be used as shown if you run @command{mysql_install_db} as
@code{root}. Otherwise, you should execute the script while logged in as
@code{mysql}, in which case you can omit the @code{--user} option from the
command.

@command{mysql_install_db} creates several tables in the @code{mysql} database:
@code{user}, @code{db}, @code{host}, @code{tables_priv},
@code{columns_priv}, @code{func}, and possibly others depending on your
version of MySQL.

If you don't want to have the @code{test} database, you can remove it with
@command{mysqladmin -u root drop test} after starting the server.

If you have problems with @command{mysql_install_db}, see
@ref{mysql_install_db, , @command{mysql_install_db}}.

There are some alternatives to running the @command{mysql_install_db}
script as it is provided in the MySQL distribution:

@cindex grant tables, re-creating
@cindex re-creating, grant tables

@itemize @bullet
@item
If you want the initial privileges to be different from the standard
defaults, you can modify @command{mysql_install_db} before you run it.
However, a preferable technique is to use @code{GRANT} and @code{REVOKE} to
change the privileges after the grant tables have been set up.  In other
words, you can run @command{mysql_install_db}, and then use @code{mysql -u root
mysql} to connect to the server as the MySQL @code{root} user so that you
can issue the @code{GRANT} and @code{REVOKE} statements.

If you want to install MySQL on a lot of machines with the
same privileges, you can put the @code{GRANT} and @code{REVOKE} statements in
a file and execute the file as a script using @code{mysql} after running
@command{mysql_install_db}. For example:

@example
shell> bin/mysql_install_db --user=mysql
shell> bin/mysql -u root < your_script_file
@end example

By doing this, you can avoid having to issue the statements manually on each
machine.

@item
It is possible to re-create the grant tables completely after they have
already been created.  You might want to do this if you're just learning how
to use @code{GRANT} and @code{REVOKE} and have made so many modifications
after running @command{mysql_install_db} that you want to wipe out the tables
and start over.

To re-create the grant tables, remove all the @file{.frm}, @file{.MYI}, and
@file{.MYD} files in the directory containing the @code{mysql} database.
(This is the directory named @file{mysql} under the data directory, which is
listed as the @code{datadir} value when you run @command{mysqld --help}.) Then
run the @command{mysql_install_db} script again.

@strong{Note}: For MySQL versions older than 3.22.10, you should not
delete the @file{.frm} files.  If you accidentally do this, you should copy
them back into the @file{mysql} directory from your MySQL distribution
before running @command{mysql_install_db}.

@item
You can start @command{mysqld} manually using the @code{--skip-grant-tables}
option and add the privilege information yourself using @command{mysql}:

@example
shell> bin/mysqld_safe --user=mysql --skip-grant-tables &
shell> bin/mysql mysql
@end example

From @command{mysql}, manually execute the SQL commands contained in
@command{mysql_install_db}.  Make sure that you run @command{mysqladmin
flush-privileges} or @command{mysqladmin reload} afterward to tell the server to
reload the grant tables.

Note that by not using @command{mysql_install_db}, you not only have to
populate the grant tables manually, you also have to create them first.
@end itemize

@item
Start the MySQL server:

@example
shell> bin/mysqld_safe --user=mysql &
@end example

For versions of MySQL older than 4.0, substitute @command{bin/safe_mysqld}
for @command{bin/mysqld_safe} in this command.

It is important that the MySQL server be run using an unprivileged
(non-@code{root}) login account.  To ensure this, the @code{--user}
option should be used as shown if you run @code{mysql_safe} as
@code{root}. Otherwise, you should execute the script while logged in as
@code{mysql}, in which case you can omit the @code{--user} option from the
command.

Further instructions for running MySQL as an unprivileged user are given in
@ref{Changing MySQL user}.

If you neglected to create the grant tables before proceeding to this step,
the following message will appear in the error log file when you start the
server:

@tindex host.frm, problems finding
@example
mysqld: Can't find file: 'host.frm'
@end example

If you have other problems starting the server, see @ref{Starting server}.

@item
Use @command{mysqladmin} to verify that the server is running.  The following
commands provide simple tests to check whether the server is up and responding
to connections:

@example
shell> bin/mysqladmin version
shell> bin/mysqladmin variables
@end example

The output from @command{mysqladmin version} varies slightly depending on your
platform and version of MySQL, but should be similar to that shown here:

@example
shell> bin/mysqladmin version
mysqladmin  Ver 8.40 Distrib 4.0.18, for linux on i586
Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL license

Server version          4.0.18-log
Protocol version        10
Connection              Localhost via Unix socket
TCP port                3306
UNIX socket             /tmp/mysql.sock
Uptime:                 16 sec

Threads: 1  Questions: 9  Slow queries: 0
Opens: 7  Flush tables: 2  Open tables: 0
Queries per second avg: 0.000
Memory in use: 132K  Max memory used: 16773K
@end example

To see what else you can do with @command{mysqladmin},
invoke it with the @code{--help} option.

@item
Verify that you can shut down the server:
@cindex server, shutdown
@cindex shutting down, the server

@example
shell> bin/mysqladmin -u root shutdown
@end example

@item
Verify that you can restart the server.  Do this by using @command{mysqld_safe} or
by invoking @command{mysqld} directly.  For example:

@cindex server, restart
@cindex restarting, the server

@example
shell> bin/mysqld_safe --user=mysql --log &
@end example

If @command{mysqld_safe} fails, see @ref{Starting server}.

@item
Run some simple tests to verify that you can retrieve information from the
server.  The output should be similar to what is shown here:

@example
shell> bin/mysqlshow
+-----------+
| Databases |
+-----------+
| mysql     |
| test      |
+-----------+

shell> bin/mysqlshow mysql
Database: mysql
+--------------+
|    Tables    |
+--------------+
| columns_priv |
| db           |
| func         |
| host         |
| tables_priv  |
| user         |
+--------------+

shell> bin/mysql -e "SELECT Host,Db,User FROM db" mysql
+------+--------+------+
| host | db     | user |
+------+--------+------+
| %    | test   |      |
| %    | test_% |      |
+------+--------+------+
@end example

@item
There is a benchmark suite in the @file{sql-bench} directory (under the
MySQL installation directory) that you can use to compare how
MySQL performs on different platforms. The benchmark suite is written in
Perl. It uses the Perl DBI module to provide a database-independent interface
to the various databases, and some other additional Perl modules are required
to run the benchmark suite. You must have the following modules installed:

@example
DBI
DBD::mysql
Data::Dumper
Data::ShowTable
@end example

These modules can be obtained from CPAN (@uref{http://www.cpan.org/}).
@xref{Perl installation}.

The @file{sql-bench/Results} directory contains the results from many runs
against different databases and platforms.  To run all tests, execute these
commands:

@example
shell> cd sql-bench
shell> perl run-all-tests
@end example

If you don't have the @file{sql-bench} directory, you probably installed MySQL
using RPM files other than the source RPM.  (The source RPM includes the
@file{sql-bench} benchmark directory.)  In this case, you must first install
the benchmark suite before you can use it.  Beginning with MySQL 3.22,
there are separate benchmark RPM files named
@file{mysql-bench-@var{VERSION}-i386.rpm} that contain benchmark code and data.

If you have a source distribution, there are also tests in its @file{tests}
subdirectory that you can run. For example, to run @file{auto_increment.tst},
execute this command from the top-level directory of your source distribution:

@example
shell> mysql -vvf test < ./tests/auto_increment.tst
@end example

The expected result of the test can be found in the
@file{./tests/auto_increment.res} file.

@item
At this point, you should have the server running. However, none of the
initial MySQL accounts have a password, so you should assign passwords
using the instructions in @ref{Default privileges}.
@end enumerate

As of MySQL 4.1.3, the installation procedure creates time zone tables
in the @code{mysql} database. However, you must populate the tables manually.
Instructions to do this are given in @ref{Time zone support}.


@node mysql_install_db, Automatic start, Unix post-installation, Unix post-installation
@subsubsection Problems Running @command{mysql_install_db}
@cindex @command{mysql_install_db} script
@cindex scripts, @command{mysql_install_db}

The purpose of the @command{mysql_install_db} script is to generate new MySQL
privilege tables.  It will not overwrite existing MySQL privilege tables,
and it will not affect any other data.

If you want to re-create your privilege tables, first stop
the @command{mysqld} server if it's running. Then rename the @file{mysql}
directory under the data directory to save it, and then run
@command{mysql_install_db}.  For example:

@example
shell> mv mysql-data-directory/mysql mysql-data-directory/mysql-old
shell> mysql_install_db --user=mysql
@end example

This section lists problems you might encounter when you run
@command{mysql_install_db}:

@table @strong
@item @command{mysql_install_db} doesn't install the grant tables

You may find that @command{mysql_install_db} fails to install the grant
tables and terminates after displaying the following messages:

@example
Starting mysqld daemon with databases from XXXXXX
mysqld ended
@end example

In this case, you should examine the error log file very carefully.  The log
should be located in the directory @file{XXXXXX} named by the error message,
and should indicate why @command{mysqld} didn't start.  If you don't understand
what happened, include the log when you post a bug report.
@xref{Bug reports}.

@item There is already a @command{mysqld} process running

This indicates that the server is already running, in which case the grant
tables probably have already been created. If so, you don't have to run
@command{mysql_install_db} at all because it need be run only once (when you
install MySQL the first time).

@item Installing a second @command{mysqld} server doesn't work when one server is running

This can happen when you already have an existing MySQL installation, but
want to put a new installation in a different location.  For example, you
might have a production installation already, but you want to create a
second installation for testing purposes.  Generally the problem that occurs
when you try to run a second server is that it tries to use a network
interface that is already in use by the first server.  In this case, you
will see one of the following error messages:

@example
Can't start server: Bind on TCP/IP port:
Address already in use
Can't start server: Bind on unix socket...
@end example

For instructions on setting up multiple servers, see @ref{Multiple servers}.

@item You don't have write access to @file{/tmp}
@cindex write access, tmp
@cindex temporary file, write access
@cindex files, @code{tmp}

If you don't have write access to create temporary files or a Unix socket
file in the default location (the @file{/tmp} directory), an error will
occur when you run @command{mysql_install_db} or the @command{mysqld} server.

You can specify different temporary directory and Unix socket file locations
by executing these commands prior to starting @command{mysql_install_db} or
@command{mysqld}:

@tindex TMPDIR environment variable
@tindex MYSQL_UNIX_PORT environment variable
@tindex Environment variable, TMPDIR
@tindex Environment variable, MYSQL_UNIX_PORT
@example
shell> TMPDIR=/some_tmp_dir/
shell> MYSQL_UNIX_PORT=/some_tmp_dir/mysql.sock
shell> export TMPDIR MYSQL_UNIX_PORT
@end example

@file{some_tmp_dir} should be the full pathname to some directory for which you
have write permission.

After this, you should be able to run @command{mysql_install_db} and start
the server with these commands:

@example
shell> bin/mysql_install_db --user=mysql
shell> bin/mysqld_safe --user=mysql &
@end example

If @command{mysql_install_db} is located in the @file{scripts} directory,
modify the first command to use @code{scripts/mysql_install_db}.

See @ref{Problems with mysql.sock,  , Problems with @file{mysql.sock}}.
@xref{Environment variables}.

@end table


@node Automatic start, Starting server, mysql_install_db, Unix post-installation
@subsubsection Starting and Stopping MySQL Automatically

@cindex starting, the server automatically
@cindex stopping, the server
@cindex server, starting and stopping

Generally, you start the @command{mysqld} server in one of these ways:

@itemize @bullet

@item
By invoking @command{mysqld} directly. This works on any platform.

@item
By running the MySQL server as a Windows service.
This can be done on versions of Windows that support services (such as
NT, 2000, XP, and 2003). The service can be set to start the server automatically
when Windows starts, or as a manual service that you start on request.
For instructions, see @ref{Windows start service}.

@item
By invoking @command{mysqld_safe}, which tries to determine the proper options
for @command{mysqld} and then runs it with those options.  This script is
used on systems based on BSD Unix.
@xref{mysqld_safe, , @command{mysqld_safe}}.

@item
By invoking @command{mysql.server}.  This script is used primarily at
system startup and shutdown on systems that use System V-style run
directories, where it usually is installed under the name @code{mysql}.
The @command{mysql.server} script starts the server by invoking @command{mysqld_safe}.
@xref{mysql.server, , @command{mysql.server}}.

@item
On Mac OS X, you can install a separate MySQL Startup Item package to
enable the automatic startup of MySQL on system startup.
The Startup Item starts the server by invoking @command{mysql.server}.
See @ref{Mac OS X installation} for details.

@end itemize

The @command{mysql.server} and @command{mysqld_safe} scripts and the Mac OS X
Startup Item can be used to start the server manually, or automatically at
system startup time. @command{mysql.server} and the Startup Item also can be
used to stop the server.

To start or stop the server manually using the @command{mysql.server} script,
invoke it with @code{start} or @code{stop} arguments:

@example
shell> mysql.server start
shell> mysql.server stop
@end example

Before @command{mysql.server} starts the server, it changes location to the
MySQL installation directory, and then invokes @command{mysqld_safe}.  If you
want the server to run as some specific user, add an appropriate @code{user}
option to the @code{[mysqld]} group of the @file{/etc/my.cnf} option file,
as shown later in this section.
(It is possible that you'll need to edit @command{mysql.server}
if you've installed a binary distribution of MySQL in a non-standard
location.  Modify it to @code{cd} into the proper directory before it runs
@command{mysqld_safe}.  If you do this, your modified version of
@command{mysql.server} may be overwritten if you upgrade MySQL in the future,
so you should make a copy of your edited version that you can reinstall.)

@command{mysql.server stop} brings down the server by sending a signal to it.
You can also stop the server manually by executing @command{mysqladmin
shutdown}.

To start and stop MySQL automatically on your server, you need to add start
and stop commands to the appropriate places in your @file{/etc/rc*} files.

If you use the Linux server RPM package (@code{MySQL-server-@var{VERSION}.rpm}),
the @command{mysql.server} script will already have been installed in the
@file{/etc/init.d} directory with the name @file{mysql}. You need not
install it manually. See @ref{Linux-RPM} for more information on the Linux
RPM packages.

Some vendors provide RPM packages that install a startup script under a
different name such as @command{mysqld}.

If you install MySQL from a source distribution or using a binary
distribution format that does not install @command{mysql.server} automatically,
you can install it manually. The script can be found in the
@file{support-files} directory under the MySQL installation directory or in
a MySQL source tree.

To install @command{mysql.server} manually, copy it to the @file{/etc/init.d}
directory with the name @command{mysql}, and then make it executable.  Do this
by changing location into the appropriate directory where
@command{mysql.server} is located and executing these commands:

@example
shell> cp mysql.server /etc/init.d/mysql
shell> chmod +x /etc/init.d/mysql
@end example

Older Red Hat systems use the @file{/etc/rc.d/init.d} directory rather than
@file{/etc/init.d}. Adjust the preceding commands accordingly. Alternatively,
first create @file{/etc/init.d} as a symbolic link that points to
@file{/etc/rc.d/init.d}:

@example
shell> cd /etc
shell> ln -s rc.d/init.d .
@end example

After installing the script, the commands needed to activate it to run
at system startup depend on your operating system.  On Linux, you can use
@code{chkconfig}:

@example
shell> chkconfig --add mysql
@end example

On some Linux systems, the following command also seems to be necessary to
fully enable the @command{mysql} script:

@example
shell> chkconfig --level 345 mysql on
@end example

On FreeBSD, startup scripts generally should go in
@file{/usr/local/etc/rc.d/}. The @code{rc(8)} manual page states that
scripts in this directory are executed only if their basename matches the
@code{*.sh} shell filename pattern.  Any other files or directories present
within the directory are silently ignored. In other words, on FreeBSD, you
should install the @file{mysql.server} script as
@file{/usr/local/etc/rc.d/mysql.server.sh} to enable automatic startup.

As an alternative to the preceding setup, some operating systems also use
@file{/etc/rc.local} or @file{/etc/init.d/boot.local} to start additional
services on startup. To start up MySQL using this method, you could append
a command like the one following to the appropriate startup file:

@example
/bin/sh -c 'cd /usr/local/mysql; ./bin/mysqld_safe --user=mysql &'
@end example

For other systems, consult your operating system documentation to see how
to install startup scripts.

@cindex changing socket location
You can add options for @command{mysql.server} in a global
@file{/etc/my.cnf} file.  A typical @file{/etc/my.cnf} file might look like
this:

@example
[mysqld]
datadir=/usr/local/mysql/var
socket=/var/tmp/mysql.sock
port=3306
user=mysql

[mysql.server]
basedir=/usr/local/mysql
@end example

The @command{mysql.server} script understands the following options:
@code{basedir}, @code{datadir}, and @code{pid-file}.  If specified, they
@emph{must} be placed in an option file, not on the command line.
@command{mysql.server} understands only @code{start} and @code{stop} as
command-line arguments.

The following table shows which option groups the server and each startup
script read from option files:

@c mysql.server also reads [server] as of 4.1.1...

@multitable @columnfractions .20 .80
@item @strong{Script} @tab @strong{Option Groups}
@item @command{mysqld} @tab @code{[mysqld]}, @code{[server]}, @code{[mysqld-major-version]}
@item @command{mysql.server} @tab  @code{[mysqld]}, @code{[mysql.server]}
@item @command{mysqld_safe} @tab @code{[mysqld]}, @code{[server]}, @code{[mysqld_safe]}
@end multitable

@code{[mysqld-major-version]} means that groups with names like
@code{[mysqld-4.0]}, @code{[mysqld-4.1]}, and @code{[mysqld-5.0]} will be
read by servers having versions 4.0.x, 4.1.x, 5.0.x, and so forth.  This
feature was added in MySQL 4.0.14. It can be used to specify options that will
be read only by servers within a given release series.

For backward compatibility, @command{mysql.server} also reads the
@code{[mysql_server]} group and @command{mysqld_safe} also reads the
@code{[safe_mysqld]} group. However, you should update your option
files to use the @code{[mysql.server]} and @code{[mysqld_safe]} groups instead
when you begin using MySQL 4.0 or later.

@xref{Option files}.


@node Starting server,  , Automatic start, Unix post-installation
@subsubsection Starting and Troubleshooting the MySQL Server
@cindex server, starting problems
@cindex problems, starting the server

If you have problems starting the server, here are some things you can try:

@itemize @bullet
@item
Specify any special options needed by the storage engines you are using.

@item
Make sure that the server knows where to find the data directory.

@item
Make sure the server can use the data directory.  The ownership and
permissions of the data directory and its contents must be set such that
the server can access and modify them.

@item
Check the error log to see why the server doesn't start.

@item
Verify that the network interfaces the server wants to use are available.

@end itemize

Some storage engines have options that control their behavior.
You can create a @file{my.cnf} file and set startup options
for the engines you plan to use.
If you are going to use storage engines that support transactional tables
(@code{InnoDB}, @code{BDB}), be sure that you have them configured the
way you want before starting the server:

@itemize @bullet
@item
If you are using @code{InnoDB} tables, refer to the @code{InnoDB}-specific
startup options.  In MySQL 3.23, you must configure @code{InnoDB} explicitly
or the server will fail to start.  From MySQL 4.0 on, @code{InnoDB} uses default
values for its configuration options if you specify none.
@xref{InnoDB configuration,  , @code{InnoDB} configuration}.

@item
If you are using @code{BDB} (Berkeley DB) tables, you should familiarize
yourself with the different @code{BDB}-specific startup options.
@xref{BDB start}.

@end itemize

When the @command{mysqld} server starts, it changes location to the data
directory.  This is where it expects to find databases and where it expects
to write log files. On Unix, the server also writes the pid (process ID)
file in the data directory.

The data directory location is hardwired in when the server is compiled.
This is where the server looks for the data directory by default. If
the data directory is located somewhere else on your system, the server will
not work properly.  You can find out what the default path settings are by
invoking @command{mysqld} with the @code{--verbose} and @code{--help} options.
(Prior to MySQL 4.1, omit the @code{--verbose} option.)

If the defaults don't match the MySQL installation layout on your system,
you can override them by specifying options on the command line to
@command{mysqld} or @command{mysqld_safe}. You can also list the options in an
option file.

To specify the location of the data directory explicitly, use the
@code{--datadir} option. However, normally you can tell @command{mysqld} the
location of the base directory under which MySQL is installed and it will
look for the data directory there.  You can do this with the @code{--basedir}
option.

To check the effect of specifying path options, invoke @command{mysqld} with
those options followed by the @code{--verbose} and @code{--help} options.
For example, if you change location into the directory where @command{mysqld} is
installed, and then run the following command, it
will show the effect of starting the server with a base
directory of @file{/usr/local}:

@example
shell> ./mysqld --basedir=/usr/local --verbose --help
@end example

You can specify other options such as @code{--datadir} as well, but note
that @code{--verbose} and @code{--help} must be the last options.  (Prior to
MySQL 4.1, omit the @code{--verbose} option.)

Once you determine the path settings you want, start the server without
@code{--verbose} and @code{--help}.

If @command{mysqld} is currently running, you can find out what path settings
it is using by executing this command:

@example
shell> mysqladmin variables
@end example

Or:

@example
shell> mysqladmin -h @var{host_name} variables
@end example

@var{host_name} is the name of the MySQL server host.

If you get @code{Errcode 13} (which means @code{Permission denied}) when
starting @command{mysqld}, this means that the access privileges of the data
directory or its contents do not allow the server access.  In this case, you
change the permissions for the involved files and directories so that the
server has the right to use them.  You can also start the server as
@code{root}, but this can raise security issues and should be avoided.

On Unix, change location into the data directory and check the ownership of
the data directory and its contents to make sure the server has access. For
example, if the data directory is @file{/usr/local/mysql/var}, use this
command:

@example
shell> ls -la /usr/local/mysql/var
@end example

If the data directory or its files or subdirectories are not owned by the
account that you use for running the server, change their ownership
to that account:

@example
shell> chown -R mysql /usr/local/mysql/var
shell> chgrp -R mysql /usr/local/mysql/var
@end example

If the server fails to start up correctly, check the error log file to
see if you can find out why.  Log files are located in the data directory
(typically @file{C:\mysql\data} on Windows, @file{/usr/local/mysql/data}
for a Unix binary distribution, and @file{/usr/local/var} for a Unix source
distribution).  Look in the data directory for files with names of the form
@file{@var{host_name}.err} and @file{@var{host_name}.log}, where @var{host_name} is the
name of your server host. (Older servers on Windows use @file{mysql.err}
as the error log name.)  Then check the last few lines of these files.
On Unix, you can use @code{tail} to display the last few lines:

@example
shell> tail @var{host_name}.err
shell> tail @var{host_name}.log
@end example

The error log contains information that indicates why the server couldn't
start.  For example, you might see something like this in the log:

@example
000729 14:50:10  bdb:  Recovery function for LSN 1 27595 failed
000729 14:50:10  bdb:  warning: ./test/t1.db: No such file or directory
000729 14:50:10  Can't init databases
@end example

This means that you didn't start @command{mysqld} with the
@code{--bdb-no-recover} option and Berkeley DB found something wrong with
its own log files when it tried to recover your databases.  To be able to
continue, you should move away the old Berkeley DB log files from the
database directory to some other place, where you can later examine them.
The @code{BDB} log files are named in sequence beginning with
@file{log.0000000001}, where the number increases over time.

If you are running @command{mysqld} with @code{BDB} table support and
@command{mysqld} dumps core at startup, this could be due to problems with the
@code{BDB} recovery log.  In this case, you can try starting @command{mysqld}
with @code{--bdb-no-recover}.  If that helps, then you should remove
all @code{BDB} log files from the data directory and try starting @command{mysqld}
again without the @code{--bdb-no-recover} option.

If either of the following errors occur, it means that some other program
(perhaps another @command{mysqld} server) is already using the TCP/IP port or
Unix socket file that @command{mysqld} is trying to use:

@example
Can't start server: Bind on TCP/IP port: Address already in use
Can't start server: Bind on unix socket...
@end example

Use @command{ps} to determine whether you have another @command{mysqld} server
running. If so, shut down the server before starting @command{mysqld} again.
(If another server is running, and you really want to run multiple servers,
you can find information about how to do so in @ref{Multiple servers}.)

If no other server is running, try to execute the command @code{telnet
your-host-name tcp-ip-port-number}.  (The default MySQL port number is
3306.) Then press Enter a couple of times.  If you don't get an error
message like @code{telnet: Unable to connect to remote host: Connection
refused}, some other program is using the TCP/IP port that @command{mysqld} is
trying to use.  You'll need to track down what program this is and disable
it, or else tell @command{mysqld} to listen to a different port with the
@code{--port} option.  In this case, you'll also need to specify the port
number for client programs when connecting to the server via TCP/IP.

Another reason the port might be inaccessible is that you have a firewall
running that blocks connections to it. If so, modify the firewall settings to
allow access to the port.

If the server starts but you can't connect to it, you should make sure
that you have an entry in @file{/etc/hosts} that looks like this:

@example
127.0.0.1       localhost
@end example

This problem occurs only on systems that don't have a working thread
library and for which MySQL must be configured to use MIT-pthreads.

If you can't get @command{mysqld} to start, you can try to make a trace file
to find the problem by using the @code{--debug} option.
@xref{Making trace files}.

@xref{Windows troubleshooting}, for more information on troubleshooting
Windows installations.

@node Default privileges,  , Unix post-installation, Post-installation
@subsection Securing the Initial MySQL Accounts

@cindex privileges, default
@cindex default, privileges
@cindex root password
@cindex superuser
@cindex accounts, root
@cindex accounts, anonymous user
@cindex users, root
@cindex anonymous user
@cindex password, root user

Part of the MySQL installation process is to set up the @code{mysql} database
containing the grant tables:

@itemize @bullet
@item
Windows distributions contain preinitialized grant tables that are installed
automatically.
@item
On Unix, the grant tables are populated by the @command{mysql_install_db}
program. Some installation methods run this program for you. Others require
that you execute it manually. For details, see @ref{Unix post-installation}.
@end itemize

The grant tables define the initial MySQL user accounts and their access
privileges.  These accounts are set up as follows:

@itemize @bullet

@item
Two accounts are created with a username of @code{root}.  These are
superuser accounts that can do anything.  The initial @code{root} account
passwords are empty, so anyone can connect to the MySQL server as @code{root}
@emph{without a password} and be granted all privileges.

@itemize @bullet

@item
On Windows, one @code{root} account is for connecting from the local host
and the other allows connections from any host.

@item
On Unix, both @code{root} accounts are for connections from the local host.
Connections must be made from the local host by specifying a hostname of
@code{localhost} for one account, or the actual hostname or IP number for
the other.

@end itemize

@item
@cindex anonymous user
Two anonymous-user accounts are created, each with an empty username.
The anonymous accounts have no passwords, so anyone can use them to connect
to the MySQL server.

@itemize @bullet

@item
On Windows, one anonymous account is for connections from the local host.
It has all privileges, just like the @code{root} accounts.
The other is for connections from any host and has all privileges for the
@code{test} database or other databases with names that start with @code{test}.

@item
On Unix, both anonymous accounts are for connections from the local host.
Connections must be made from the local host by specifying a hostname of
@code{localhost} for one account, or the actual hostname or IP number for
the other.  These accounts have all privileges for the @code{test} database
or other databases with names that start with @code{test_}.

@end itemize

@end itemize

As noted, none of the initial accounts have passwords.  This means that
your MySQL installation is unprotected until you do something about it:

@itemize @bullet

@item
If you want to prevent clients from connecting as anonymous users without a
password, you should either assign passwords to the anonymous accounts or else
remove them.

@item
You should assign passwords to the MySQL @code{root} accounts.

@end itemize

The following instructions describe how to set up passwords for the
initial MySQL accounts, first for the anonymous accounts and then for the
@code{root} accounts.  Replace ``@var{newpwd}'' in the examples with the
actual password that you want to use.  The instructions also cover how
to remove the anonymous accounts, should you prefer not to allow anonymous
access at all.

You might want to defer setting the passwords until later, so that you
don't need to specify them while you perform additional setup or testing.
However, be sure to set them before using your installation for any real
production work.

To assign passwords to the anonymous accounts, you can use either
@code{SET PASSWORD} or @code{UPDATE}.  In both cases, be sure to encrypt the
password using the @code{PASSWORD()} function.

To use @code{SET PASSWORD} on Windows, do this:

@example
shell> mysql -u root
mysql> SET PASSWORD FOR ''@@'localhost' = PASSWORD('@var{newpwd}');
mysql> SET PASSWORD FOR ''@@'%' = PASSWORD('@var{newpwd}');
@end example

To use @code{SET PASSWORD} on Unix, do this:

@example
shell> mysql -u root
mysql> SET PASSWORD FOR ''@@'localhost' = PASSWORD('@var{newpwd}');
mysql> SET PASSWORD FOR ''@@'@var{host_name}' = PASSWORD('@var{newpwd}');
@end example

In the second @code{SET PASSWORD} statement, replace @var{host_name}
with the name of the server host.  This is the name that is specified in
the @code{Host} column of the non-@code{localhost} record for @code{root}
in the @code{user} table.  If you don't know what hostname this is, issue
the following statement before using @code{SET PASSWORD}:

@example
mysql> SELECT Host, User FROM mysql.user;
@end example

Look for the record that has @code{root} in the @code{User} column and
something other than @code{localhost} in the @code{Host} column. Then use that
@code{Host} value in the second @code{SET PASSWORD} statement.

The other way to assign passwords to the anonymous accounts is by using
@code{UPDATE} to modify the @code{user} table directly.  Connect to the
server as @code{root} and issue an @code{UPDATE} statement that assigns a
value to the @code{Password} column of the appropriate @code{user} table
records.  The procedure is the same for Windows and Unix.  The following
@code{UPDATE} statement assigns a password to both anonymous accounts at
once:

@example
shell> mysql -u root
mysql> UPDATE mysql.user SET Password = PASSWORD('@var{newpwd}')
    ->     WHERE User = '';
mysql> FLUSH PRIVILEGES;
@end example

After you update the passwords in the @code{user} table directly using
@code{UPDATE}, you must tell the server to re-read the grant tables with
@code{FLUSH PRIVILEGES}. Otherwise, the change will go unnoticed until you
restart the server.

If you prefer to remove the anonymous accounts instead, do so as follows:

@example
shell> mysql -u root
mysql> DELETE FROM mysql.user WHERE User = '';
mysql> FLUSH PRIVILEGES;
@end example

The @code{DELETE} statement applies both to Windows and to Unix.
On Windows, if you want to remove only the anonymous account that has the same
privileges as @code{root}, do this instead:

@example
shell> mysql -u root
mysql> DELETE FROM mysql.user WHERE Host='localhost' AND User='';
mysql> FLUSH PRIVILEGES;
@end example

This account allows anonymous access but has full privileges, so removing
it improves security.

You can assign passwords to the @code{root} accounts in several ways. The
following discussion demonstrates three methods:

@itemize @bullet
@item
Use the @code{SET PASSWORD} statement
@item
Use the @command{mysqladmin} command-line client program
@item
Use the @code{UPDATE} statement
@end itemize

To assign passwords using @code{SET PASSWORD}, connect to the server as
@code{root} and issue two @code{SET PASSWORD} statements.
Be sure to encrypt the password using the @code{PASSWORD()} function.

For Windows, do this:

@example
shell> mysql -u root
mysql> SET PASSWORD FOR 'root'@@'localhost' = PASSWORD('@var{newpwd}');
mysql> SET PASSWORD FOR 'root'@@'%' = PASSWORD('@var{newpwd}');
@end example

For Unix, do this:

@example
shell> mysql -u root
mysql> SET PASSWORD FOR 'root'@@'localhost' = PASSWORD('@var{newpwd}');
mysql> SET PASSWORD FOR 'root'@@'@var{host_name}' = PASSWORD('@var{newpwd}');
@end example

In the second @code{SET PASSWORD} statement, replace @var{host_name} with
the name of the server host.  This is the same hostname that you used when
you assigned the anonymous account passwords.

To assign passwords to the @code{root} accounts using @command{mysqladmin},
execute the following commands:

@example
shell> mysqladmin -u root password "@var{newpwd}"
shell> mysqladmin -u root -h @var{host_name} password "@var{newpwd}"
@end example

These commands apply both to Windows and to Unix.  In the second command,
replace @var{host_name} with the name of the server host.  The double
quotes around the password are not always necessary, but you should use
them if the password contains spaces or other characters that are special
to your command interpreter.

If you are using a server from a @emph{very} old version of MySQL, the
@command{mysqladmin} commands to set the password will fail with the message
@code{parse error near 'SET password'}.  The solution to this problem is
to upgrade the server to a newer version of MySQL.

You can also use @code{UPDATE} to modify the @code{user} table directly.
The following @code{UPDATE} statement assigns a password to both @code{root}
accounts at once:

@example
shell> mysql -u root
mysql> UPDATE mysql.user SET Password = PASSWORD('@var{newpwd}')
    ->     WHERE User = 'root';
mysql> FLUSH PRIVILEGES;
@end example

The @code{UPDATE} statement applies both to Windows and to Unix.

After the passwords have been set, you must supply the appropriate
password whenever you connect to the server.
For example, if you want to use @command{mysqladmin} to shut
down the server, you can do so using this command:

@example
shell> mysqladmin -u root -p shutdown
Enter password: (enter root password here)
@end example

@strong{Note}: If you forget your @code{root} password after setting it up,
the procedure for resetting it is covered in @ref{Resetting permissions}.

To set up new accounts, you can use the @code{GRANT} statement. For
instructions, see @ref{Adding users}.


@node Upgrade, Downgrading, Post-installation, Installing
@section Upgrading MySQL

@cindex upgrading

As a general rule, we recommend that when upgrading from one release series to
another, you should go to the next series rather than skipping a series. For
example, if you currently are running MySQL 3.23 and wish to upgrade to a
newer series, upgrade to MySQL 4.0 rather than to 4.1 or 5.0.

The following items form a checklist of things you should do whenever you
perform an upgrade:

@itemize @bullet
@item
Read the upgrading section for the release series to which you are upgrading.
Read the change notes as well.
These provide information about new features you can use.
For example, before upgrading from MySQL 4.1 to 5.0, read the 5.0 upgrading
section (@pxref{Upgrading-from-4.1}) and read the 5.0 change notes
(@pxref{News}).

@item
Before you do an upgrade, back up your databases.

@item
If you are running MySQL Server on Windows, see @ref{Windows upgrading}.

@item
An upgrade may involve changes to the grant tables that are stored in the
@code{mysql} database. Occasionally new columns or tables are added to
support new features.  To take advantage of these features, be sure that
your grant tables are up to date.  The upgrade procedure is described in
@ref{Upgrading-grant-tables}.

@item
If you are using replication, see @ref{Replication Upgrade}
for information on upgrading your replication setup.

@item
If you install a MySQL-Max distribution that includes a server named
@command{mysqld-max}, then upgrade later to a non-Max version of MySQL,
@command{mysqld_safe} will still attempt to run the old @command{mysqld-max}
server.  If you perform such an upgrade, you should manually remove the old
@command{mysqld-max} server to ensure that @command{mysqld_safe} runs the new
@command{mysqld} server.

@end itemize

You can always move the MySQL format files and data files between different
versions on the same architecture as long as you stay within versions for
the same release series of MySQL. The current production release series is
4.1. If you change the character set when running MySQL, you must run
@command{myisamchk -r -q --set-character-set=@var{charset}} on all @code{MyISAM} tables.
Otherwise, your indexes may not be ordered correctly, because changing the
character set may also change the sort order.

Normally you can upgrade MySQL to a newer MySQL version without having
to do any changes to your tables.  Please confirm if the upgrade notes
to the particular version you are upgrading to tells you anything about
this.  If there would be any incompatibilites you can use
@command{mysqldump} to dump your tables before upgrading. After
upgrading, reload the dump file using @command{mysql} or @code{mysqlimport}
to re-create your tables.

If you are cautious about using new versions, you can always rename your old
@command{mysqld} before installing a newer one. For example, if you are using
MySQL 4.0.18 and want to upgrade to 4.1.1, rename your current server from
@command{mysqld} to @command{mysqld-4.0.18}.  If your new @command{mysqld} then does
something unexpected, you can simply shut it down and restart with your old
@command{mysqld}.

If, after an upgrade, you experience problems with recompiled client programs,
such as @code{Commands out of sync} or unexpected core dumps, you probably have
used old header or library files when compiling your programs.  In this
case, you should check the date for your @file{mysql.h} file and
@file{libmysqlclient.a} library to verify that they are from the new
MySQL distribution.  If not, recompile your programs with the new
headers and libraries.

If problems occur, such as that the new @command{mysqld} server doesn't want to
start or that you can't connect without a password, verify that you don't
have some old @file{my.cnf} file from your previous installation.  You can
check this with the @code{--print-defaults} option (for example,
@command{mysqld --print-defaults}).  If this displays
anything other than the program name, you have an active @file{my.cnf}
file that affects server or client operation.

It is a good idea to rebuild and reinstall the Perl @code{DBD::mysql}
module whenever you install a new release of MySQL. The same applies to other
MySQL interfaces as well, such as the PHP @code{mysql} extension and the
Python @code{MySQLdb} module.

@menu
* Upgrading-from-4.1::          Upgrading from Version 4.1 to 5.0
* Upgrading-from-4.0::          Upgrading from Version 4.0 to 4.1
* Upgrading-from-3.23::         Upgrading from Version 3.23 to 4.0
* Upgrading-from-3.22::         Upgrading from Version 3.22 to 3.23
* Upgrading-from-3.21::         Upgrading from Version 3.21 to 3.22
* Upgrading-from-3.20::         Upgrading from Version 3.20 to 3.21
* Upgrading-grant-tables::      Upgrading the Grant Tables
* Upgrading-to-arch::           Copying MySQL Databases to Another Machine
@end menu


@node Upgrading-from-4.1, Upgrading-from-4.0, Upgrade, Upgrade
@subsection Upgrading from Version 4.1 to 5.0

@cindex compatibility, between MySQL versions
@cindex upgrading, to 5.0

In general, you should do the following when upgrading to MySQL 5.0 from 4.1:

@itemize @bullet

@item
Check the items in the change list found later in this section to see whether
any of them might affect your applications.


@item
Read the 5.0 news items to see what significant new features you can use in
5.0.
@xref{News-5.0.x}.

@item
If you are running MySQL Server on Windows, see @ref{Windows upgrading}.
Also, two of the Windows MySQL servers were renamed.
@xref{Windows select server}.

@item
MySQL 5.0 adds support for stored procedures. This support requires the
@code{proc} table in the @code{mysql} database.
To create this file, you should run the @command{mysql_fix_privilege_tables}
script as described in @ref{Upgrading-grant-tables}.

@item
MySQL 5.0 adds support for views. This support requires the extra privilege
columns in the @code{user} and @code{db} tables in the @code{mysql} database.
To create these columns, you should run the @command{mysql_fix_privilege_tables}
script as described in @ref{Upgrading-grant-tables}.

@item
If you are using replication, see @ref{Replication Upgrade}
for information on upgrading your replication setup.

@item
MySQL 5.0.2 adds several new SQL modes that allow stricter control over
rejecting records that have invalid or missing values.
@xref{Server SQL mode}.
@xref{constraint invalid data}.
If you want to enable this control but continue to use MySQL's capability
for storing incorrect dates such as @code{'2004-02-31'}, you should start
the server with @code{--sql_mode=TRADITIONAL,ALLOW_INVALID_DATES}.

@item
As of MySQL 5.0.2, the @code{SCHEMA} and @code{SCHEMAS} keywords are
accepted as synonyms for @code{DATABASE} and @code{DATABASES}.

@item
The update log is removed in MySQL 5.0.

@end itemize

The following list describes changes that may affect applications and that
you should watch out for when upgrading to version 5.0:

@itemize @bullet
@item
The update log is removed, so if you enabled it in the past,
you should enable the binary log instead.
@xref{News-5.0.x}.

@item
User variables now are not case sensitive. In MySQL 4.1,
@code{SET @@x = 0; SET @@X = 1; SELECT @@x;} creates two variables and
returns @code{0}. In MySQL 5.0, it creates one variable and returns
@code{1}.

@item
API change: the @code{reconnect} flag in the @code{MYSQL} structure is now set
to 0 by @code{mysql_real_connect()}. Only those client programs which didn't
explicitely set this flag to 0 or 1 after @code{mysql_real_connect()} will
experience a change. Having automatic reconnection enabled by default was
considered too dangerous (after reconnection, table locks, temporary tables,
user and session variables are lost).

@end itemize


@node Upgrading-from-4.0, Upgrading-from-3.23, Upgrading-from-4.1, Upgrade
@subsection Upgrading from Version 4.0 to 4.1

@cindex compatibility, between MySQL versions
@cindex upgrading, 4.0 to 4.1

In general, you should do the following when upgrading to MySQL 4.1 from 4.0:

@itemize @bullet
@item
Check the items in the change lists found later in this section to see whether
any of them might affect your applications. Some of them result in
incompatibilities with earlier versions.

@item
Read the 4.1 news items to see what significant new features you can use in 4.1.
@xref{News-4.1.x}.

@item
Character set support has been improved. The server now supports multiple
character sets.

@item
@strong{Important note:}
MySQL 4.1 stores table names and column names in @code{UTF8}. If you have
table names or column names that use characters outside of the standard 7-bit
US-ASCII range, you may have to do a @code{mysqldump} of your tables
in MySQL 4.0 and restore them after upgrading to MySQL 4.1.  The symptom for
this problem is that you get a @code{table not found} error when trying to
access your tables. In this case, you should be able to downgrade back to
MySQL 4.0 and access your data.

@item
If you are running MySQL Server on Windows, see @ref{Windows upgrading}.

@c THIS IS OUTDATED, THOSE DOWNLOADING 4.1 WILL HAVE AN INSTALLER
@c AND THOSE WHO ARE USING AN EARLY VERSION ARE ALREADY INSTALLED.
@c @strong{Important note:}
@c Early alpha Windows distributions for MySQL 4.1 do not contain an
@c installer program.  Such a 4.1 distribution is a Zip file that you just
@c unzip in the location where you want to install MySQL. For example,
@c to install @file{mysql-4.1.1-alpha-win.zip} as @file{C:\mysql}, unzip
@c the distribution file on the @code{C:} drive, then rename the resulting
@c @file{mysql-4.1.1-alpha} directory to @file{mysql}.

@item
After upgrading, update the grant tables to have the new longer
@code{Password} column that is needed for more secure handling of passwords.
The procedure uses @command{mysql_fix_privilege_tables} and is described
in @ref{Upgrading-grant-tables}.  If you don't do this, MySQL will not
us the new more secure protocol to authenticate.  Implications of the
password-handling change for applications are given later in this section.

@item
If you are using replication, see @ref{Replication Upgrade}
for information on upgrading your replication setup.

@item
The Berkeley DB table handler is updated to DB 4.1 (from 3.2) which has
a new log format. If you have to downgrade back to 4.0 you must use
@command{mysqldump} to dump your @code{BDB} tables in text format and delete
all @code{log.XXXXXXXXXX} files before you start MySQL 4.0 and reload
the data.

@item
MySQL 4.1.3 introduces support for per-connection time zones.
@xref{Time zone support}. To enable recognition of named time zones,
you should create the time zone tables in the @code{mysql} database.
For instructions, see @ref{Post-installation}.

@item
If you are using an old @code{DBD-mysql} module
(@code{Msql-MySQL-modules}) you have to upgrade to use the newer
@code{DBD-mysql} module. Anything above @code{DBD-mysql} 2.xx should be fine.

If you don't upgrade, some methods (such as @code{DBI->do()}) will not
notice error conditions correctly.

@item
The @code{--defaults-file=option-file-name} option now will give an error if
the option file doesn't exist.

@item
Some notes about upgrading from MySQL 4.0 to MySQL 4.1 on Netware:
Make sure to upgrade Perl and PHP versions. Download and install Perl module for MySQL 4.1 from
@uref{http://forge.novell.com/modules/xfmod/project/showfiles.php?group_id=1126}
and PHP Extension for MySQL 4.1 from
@uref{http://forge.novell.com/modules/xfmod/project/showfiles.php?group_id=1078}.

@end itemize

Several visible behaviors have changed between MySQL 4.0 and MySQL 4.1 to
fix some critical bugs and make MySQL more compatible with standard SQL.
These changes may affect your applications.

Some of the 4.1 behaviors can be tested in 4.0 before performing
a full upgrade to 4.1. We have added to later MySQL 4.0 releases
(from 4.0.12 on) a @code{--new} startup option for @command{mysqld}.
@xref{Server options}.

This option gives you the 4.1 behavior for the most critical changes.
You can also enable these behaviors for a given client connection with
the @code{SET @@@@new=1} command, or turn them off if they are on with
@code{SET @@@@new=0}.

@c TODO: preceding para means there is a global/session variable named "new"
@c that should be listed under system variables.

If you believe that some of the 4.1 changes will affect you,
we recommend that before upgrading to 4.1, you download
the latest MySQL 4.0 version and run it with the @code{--new} option by
adding the following to your config file:

@example
[mysqld-4.0]
new
@end example

That way you can test the new behaviors in 4.0 to make sure that your
applications work with them. This will help you have a smooth, painless
transition when you perform a full upgrade to 4.1 later. Putting the
@code{--new} option in the @code{[mysqld-4.0]} option group ensures
that you don't accidentally later run the 4.1
version with the @code{--new} option.

The following lists describe changes that may affect applications and that
you should watch out for when upgrading to version 4.1:

@strong{Server Changes:}

@itemize @bullet

@item
All tables and string columns now have a character set.
@xref{Charset}.
Character set information is displayed by
@code{SHOW CREATE TABLE} and @command{mysqldump}.
(MySQL versions 4.0.6 and above can read the new dump files; older
versions cannot.)
This change should not affect applications that use only one character set.

@item
If you have table columns that
store character data represented in a character set that the 4.1 server
now supports directly, you can convert the columns to the proper character
set using the instructions in @ref{Charset-conversion}.  Also, database,
table, and column identifiers now are stored internally using Unicode (UTF8)
regardless of the default character set.
@xref{Legal names}.

@item
@strong{Incompatible change:}
There are conditions under which you should rebuild tables.
In general, to rebuild a table, dump it with @command{mysqldump}
and reload the dump file.  Some items in the following list indicate
alternatives means for rebuilding.

@itemize @minus
@item
If you have created or used @code{InnoDB} tables with @code{TIMESTAMP}
columns in MySQL versions 4.1.0 to 4.1.3, you have to rebuild those tables
when you upgrade to MySQL 4.1.4 or later. The storage format in those
MySQL versions for a @code{TIMESTAMP} column was incorrect. If you upgrade
from MySQL 4.0 to 4.1.4 or later, then no rebuild of tables with
@code{TIMESTAMP} columns is needed.

@item
Starting from MySQL 4.1.3, @code{InnoDB} uses the same character set
comparison functions as MySQL for non-@code{latin1_swedish_ci} character
strings that are not @code{BINARY}.  This changes the sorting order of
space and characters with a code < ASCII(32) in those character sets.
For @code{latin1_swedish_ci} character strings and @code{BINARY} strings,
@code{InnoDB} uses its own pad-spaces-at-end comparison method, which
stays unchanged.  If you have an @code{InnoDB} table created with MySQL
4.1.2 or earlier, with an index on a non-@code{latin1} character set
(in the case of 4.1.0 and 4.1.1, with any character set) and the table
contains any @code{CHAR}/@code{VARCHAR}/or @code{TEXT} columns that are
not @code{BINARY} but may contain characters with a code < ASCII(32),
then you should do @code{ALTER TABLE} or @code{OPTIMIZE TABLE} on it to
regenerate the index, after upgrading to MySQL 4.1.3 or later.
Also, @code{MyISAM} tables have to be rebuilt or repaired in these cases.

@item
If you have used column prefix indexes on UTF8 columns or other multibyte
character set columns in MySQL 4.1.0 to 4.1.5, you must rebuild the tables
when you upgrade to MySQL 4.1.6 or later.

@item
If you have used accent characters (characters with byte values of 128 to
255) in database names, table names, constraint names, or column names
in versions of MySQL earlier than 4.1, you cannot upgrade to MySQL 4.1
directly, because 4.1 uses UTF8 to store metadata names. Use @code{RENAME
TABLE} to overcome this if the accent character is in the table name or
the database name, or rebuild the table.

@end itemize

@item
@strong{Incompatible change:}
MySQL now interprets length specifications in character column
definitions in characters. (Earlier versions interpret them in bytes.)
For example, @code{CHAR(@var{N})} now means @var{N} characters, not @var{N}
bytes.

For single-byte character sets, this change makes no difference. However,
if you upgrade to MySQL 4.1 and configure the server to use a multi-byte
character set, the apparent length of character columns will change. Suppose
that a 4.0 table contains a @code{CHAR(8)} column used to store @code{ujis}
characters. Eight bytes can store from two to four @code{ujis} characters.
If you upgrade to 4.1 and configure the server to use @code{ujis} as its
default character set, the server interprets character column lengths
based on the maximum size of a @code{ujis} character, which is three
bytes.  The number of three-byte characters that fit in eight bytes is
two. Consequently, if you use @code{SHOW CREATE TABLE} to view the table
definition, MySQL displays @code{CHAR(2)}.  You can retrieve existing
data from the table, but you will be able to store new values containing
only up to two characters. To correct this issue, use @code{ALTER TABLE}
to change the column definition. For example:

@example
ALTER TABLE @var{tbl_name} MODIFY @var{col_name} CHAR(8);
@end example

@item
The table definition format used in @file{.frm} files
has changed slightly in 4.1.  MySQL 4.0 versions from 4.0.11 on can
read the new @file{.frm} format directly, but older versions cannot.
If you need to move tables from 4.1 to a version earlier than 4.0.11, you
should use @command{mysqldump}.
@xref{mysqldump, , @command{mysqldump}}.

@item
@strong{Important note:} If you upgrade to MySQL 4.1.1 or higher, it is
difficult to downgrade back to 4.0 or 4.1.0! That is because, for earlier
versions, @code{InnoDB} is not aware of multiple tablespaces.

@item
@strong{Incompatible change:}
In connection with the support for per-connection time zones in MySQL 4.1.3,
the @code{timezone} system variable was renamed to @code{system_time_zone}.

@item
Windows servers now support connections from local clients using shared
memory if run with the @code{--shared-memory} option.  If you are running
multiple servers this way on the same Windows machine, you should use a
different @code{--shared-memory-base-name} option for each server.

@item
The interface to aggregated UDF functions has changed a bit. You must now
declare a @code{xxx_clear()} function for each aggregate function @code{XXX()}.

@end itemize

@strong{Client Changes:}

@itemize @bullet

@item
@command{mysqldump} now has the @code{--opt} and @code{--quote-names} options
enabled by default. You can turn them off with @code{--skip-opt} and
@code{--skip-quote-names}.

@end itemize

@strong{SQL Changes:}

@itemize @bullet

@item
@strong{Incompatible change:}
In MySQL 4.1.2, the @code{Type} column in the output from @code{SHOW TABLE
STATUS} was renamed to @code{Engine}.

@item
@strong{Incompatible change:}
String comparison now works according to SQL standard: Instead of
stripping end spaces before comparison, we now extend the shorter string
with spaces.  The problem with this is that now @code{'a' > 'a\t'},
which it wasn't before.  If you have any tables where you
have a @code{CHAR} or @code{VARCHAR} column in which the last character in the
column may be less than @code{ASCII(32)}, you should use @code{REPAIR TABLE} or
@command{myisamchk} to ensure that the table is correct.

@item
When using multiple-table @code{DELETE} statements, you should use the
alias of the tables from which you want to delete, not the actual table name.
For example, instead of doing this:

@example
DELETE test FROM test AS t1, test2 WHERE ...
@end example

Do this:

@example
DELETE t1 FROM test AS t1, test2 WHERE ...
@end example

This corrects a problem that was present in MySQL 4.0.

@item
@strong{Incompatible change:}
@code{TIMESTAMP} is now returned as a string in @code{'YYYY-MM-DD HH:MM:SS'}
format (from 4.0.12 the @code{--new} option can be used to make a
4.0 server behave as 4.1 in this respect).
@xref{TIMESTAMP 4.1,  , @code{TIMESTAMP} 4.1}.

If you want to have the value returned as a number (as MySQL 4.0 does) you
should add @code{+0} to @code{TIMESTAMP} columns when you retrieve them:

@example
mysql> SELECT ts_col + 0 FROM @var{tbl_name};
@end example

Display widths for @code{TIMESTAMP} columns are no longer supported.
For example, if you declare a column as @code{TIMESTAMP(10)}, the @code{(10)}
is ignored.

These changes were necessary for SQL standards compliance. In a future
version, a further change will be made (backward compatible with this
change), allowing the timestamp length to indicate the desired number of
digits for fractions of a second.

@item
@strong{Incompatible change:}
Binary values such as @code{0xFFDF} now are assumed to be strings instead of
numbers.  This fixes some problems with character sets where it's
convenient to input a string as a binary value.  With this change,
you should use @code{CAST()} if you want to compare binary values
numerically as integers:

@example
mysql> SELECT CAST(0xFEFF AS UNSIGNED INTEGER)
    ->        < CAST(0xFF AS UNSIGNED INTEGER);
        -> 0
@end example

If you don't use @code{CAST()}, a lexical string comparison will be done:

@example
mysql> SELECT 0xFEFF < 0xFF;
        -> 1
@end example

Using binary items in a numeric context or comparing them using the
@code{=} operator should work as before.  (The @code{--new} option can
be used from 4.0.13 on to make a 4.0 server behave as 4.1 in this respect.)

@item
For functions that produce a @code{DATE}, @code{DATETIME}, or @code{TIME}
value, the result returned to the client now is fixed up to have a temporal
type. For example, in MySQL 4.1, you get this result:

@example
mysql> SELECT CAST('2001-1-1' AS DATETIME);
       -> '2001-01-01 00:00:00'
@end example

In MySQL 4.0, the result is different:

@example
mysql> SELECT CAST('2001-1-1' AS DATETIME);
       -> '2001-01-01'
@end example

@item
@code{DEFAULT} values no longer can be specified for @code{AUTO_INCREMENT}
columns. (In 4.0, a @code{DEFAULT} value is silently ignored; in 4.1,
an error occurs.)

@item
@code{LIMIT} no longer accepts negative arguments.
Use some large number (maximum 18446744073709551615) instead of -1.

@item
@code{SERIALIZE} is no longer a valid mode value for the @code{sql_mode}
variable.  You should use @code{SET TRANSACTION ISOLATION LEVEL SERIALIZABLE}
instead. @code{SERIALIZE} is no longer valid for the @code{--sql-mode} option
for @command{mysqld}, either. Use @code{--transaction-isolation=SERIALIZABLE}
instead.

@end itemize

@strong{C API Changes:}

@itemize @bullet

@item
@strong{Incompatible change:}
The @code{mysql_shutdown()} C API function has an extra parameter
as of MySQL 4.1.3: @code{SHUTDOWN}-level. You should convert any
@code{mysql_shutdown(@var{X})} call you have in your application to
@code{mysql_shutdown(@var{X},SHUTDOWN_DEFAULT)}.

@item
Some C API calls such as @code{mysql_real_query()} now return @code{1} on error,
not @code{-1}.  You may have to change some old applications if they use
constructs like this:

@example
if (mysql_real_query(mysql_object, query, query_length) == -1)
@{
  printf("Got error");
@}
@end example

Change the call to test for a non-zero value instead:

@example
if (mysql_real_query(mysql_object, query, query_length) != 0)
@{
  printf("Got error");
@}
@end example

@end itemize

@strong{Password-Handling Changes:}

The password hashing mechanism has changed in 4.1 to provide better
security, but this may cause compatibility problems if you still have
clients that use the client library from 4.0 or earlier.  (It is very likely that you will
have 4.0 clients in situations where clients connect from remote hosts
that have not yet upgraded to 4.1.)  The following list indicates some
possible upgrade strategies.  They represent various tradeoffs between
the goal of compatibility with old clients and the goal of security.

@itemize @bullet

@item
Only upgrade the client to use 4.1 client libraries (not the server). No
behavior will change (except the return value of some API calls), but
you cannot use any of the new features provided by the 4.1 client/server
protocol, either.  (MySQL 4.1 has an extended client/server protocol
that offers such features as prepared statements and multiple result
sets.)  @xref{C API Prepared statements}.

@item
Upgrade to 4.1 and run the @command{mysql_fix_privilege_tables} script
to widen the @code{Password} column in the @code{user} table so
that it can hold long password hashes.  But run the server with the
@code{--old-passwords} option to provide backward compatibility that
allows pre-4.1 clients to continue to connect to their short-hash
accounts.
Eventually, when all your clients are upgraded to 4.1, you can stop using the
@code{--old-passwords} server option. You can also change the passwords for
your MySQL accounts to use the new more secure format.

@item
Upgrade to 4.1 and run the @command{mysql_fix_privilege_tables} script to widen the
@code{Password} column in the @code{user} table.  If you know that all clients
also have been upgraded to 4.1, don't run the server with the
@code{--old-passwords} option.  Instead, change the passwords on all existing
accounts so that they have the new format.  A pure-4.1 installation
is the most secure.

@item
Some notes about upgrading from MySQL 4.0 to MySQL 4.1 on Netware:
Make sure to upgrade Perl and PHP versions. Download Perl 5 for
Netware from http://forge.novell.com/modules/xfmod/project/?perl5) and
PHP from http://forge.novell.com/modules/xfmod/project/?php.


@end itemize

Further background on password hashing with respect to client authentication
and password-changing operations may be found in @ref{Password hashing} and
@ref{Old client}.


@node Upgrading-from-3.23, Upgrading-from-3.22, Upgrading-from-4.0, Upgrade
@subsection Upgrading from Version 3.23 to 4.0

@cindex compatibility, between MySQL versions
@cindex upgrading, 3.23 to 4.0

In general, you should do the following when upgrading to MySQL 4.0 from 3.23:

@itemize @bullet
@item
Check the items in the change lists found later in this section to see whether
any of them might affect your applications.

@item
Read the 4.0 news items to see what significant new features you can use in 4.0.
@xref{News-4.0.x}.

@item
If you are running MySQL Server on Windows, see @ref{Windows upgrading}.

@item
After upgrading,
update the grant tables to add new privileges and features.  The
procedure uses the @command{mysql_fix_privilege_tables} script and is described
in @ref{Upgrading-grant-tables}.

@item
If you are using replication, see @ref{Replication Upgrade}
for information on upgrading your replication setup.

@item
Edit any MySQL startup scripts or option files to not use any of the
deprecated options described later in this section.

@item
Convert your old @code{ISAM} files to @code{MyISAM} files. One way to do this
is with the
@code{mysql_convert_table_format} script. (This is a Perl script;
it requires that DBI be installed.) To convert the tables in a given database,
use this command:

@example
shell> mysql_convert_table_format database @var{db_name}
@end example

Note that this should be used only if all tables in the given database
are @code{ISAM} or @code{MyISAM} tables. To avoid converting tables
of other types to @code{MyISAM}, you can explicitly list the names
of your @code{ISAM} tables after the database name on the command
line.

Individual tables can be changed to @code{MyISAM} by using the following
@code{ALTER TABLE} statement for each table to be converted:

@example
mysql> ALTER TABLE @var{tbl_name} TYPE=MyISAM;
@end example

If you are not sure of the table type for a given table, use this statement:

@example
mysql> SHOW TABLE STATUS LIKE '@var{tbl_name}';
@end example

@item
Ensure that you don't have any MySQL clients that use shared libraries
(like the Perl @code{DBD::mysql} module). If you do, you should recompile
them, because the data structures used in @file{libmysqlclient.so} have changed.
The same applies to other MySQL interfaces as well, such as the Python
@code{MySQLdb} module.

@end itemize

MySQL 4.0 will work even if you don't perform the preceding actions, but you
will not be able to use the new security privileges in MySQL 4.0 and you
may run into problems when upgrading later to MySQL 4.1 or newer.  The
@code{ISAM} file format still works in MySQL 4.0, but is deprecated and
is not compiled in by default as of MySQL 4.1. @code{MyISAM} tables should
be used instead.

Old clients should work with a MySQL 4.0 server without any problems.

Even if you perform the preceding actions, you can still downgrade to MySQL
3.23.52 or newer if you run into problems with the MySQL 4.0 series.  In
this case, you must use @command{mysqldump} to dump any tables that use
full-text indexes and reload the dump file into the 3.23 server.  This is
necessary because 4.0 uses a new format for full-text indexing.

The following lists describe changes that may affect applications and that
you should watch out for when upgrading to version 4.0:

@strong{Server Changes:}

@itemize @bullet

@item
MySQL 4.0 has a lot of new privileges in the @code{mysql.user} table.
@xref{Privileges provided}.

To get these new privileges to work, you must update the grant tables.
The procedure is described in @ref{Upgrading-grant-tables}.
Until you do this, all
accounts have the @code{SHOW DATABASES}, @code{CREATE TEMPORARY TABLES},
and @code{LOCK TABLES} privileges. @code{SUPER} and @code{EXECUTE}
privileges take their value from @code{PROCESS}.
@code{REPLICATION SLAVE} and @code{REPLICATION CLIENT} take their
values from @code{FILE}.

If you have any scripts that create new MySQL user accounts, you may want to change
them to use the new privileges.  If you are not using @code{GRANT}
commands in the scripts, this is a good time to change your scripts to use
@code{GRANT} instead of modifying the grant tables directly.

From version 4.0.2 on, the option @code{--safe-show-database} is deprecated
(and no longer does anything). @xref{Privileges options}.

If you get @code{Access denied} errors for new users in version 4.0.2 and up, you
should check whether you need some of the new grants that you didn't need
before.  In particular, you will need @code{REPLICATION SLAVE}
(instead of @code{FILE}) for new slave servers.

@item
@command{safe_mysqld} has been renamed to @command{mysqld_safe}.  For backward
compatibility, binary distributions will for some time include
@command{safe_mysqld} as a symlink to @command{mysqld_safe}.

@item
@code{InnoDB} support is now included by default in binary distributions.
If you build MySQL from source, @code{InnoDB} is configured in by default.
If you do not use @code{InnoDB} and want to save memory when running a
server that has @code{InnoDB} support enabled, use the @code{--skip-innodb}
server startup option. To compile MySQL without @code{InnoDB} support, run
@command{configure} with the @code{--without-innodb} option.

@item
Values for the startup parameters @code{myisam_max_extra_sort_file_size} and
@code{myisam_max_extra_sort_file_size} now are given in bytes
(they were given in megabytes before 4.0.3).

@item
@command{mysqld} now has the option @code{--temp-pool} enabled by default
because this gives better performance with some operating systems (most
notably Linux).

@item
The @command{mysqld} startup options @code{--skip-locking} and
@code{--enable-locking} were renamed to @code{--skip-external-locking}
and @code{--external-locking}.

@item
External system locking of @code{MyISAM}/@code{ISAM} files is now
turned off by default.  You can turn this on with
@code{--external-locking}. (However, this is never needed for most users.)

@item
The following startup variables and options have been renamed:

@multitable @columnfractions .50 .50
@item @strong{Old Name} @tab @strong{New Name}
@item @code{myisam_bulk_insert_tree_size} @tab @code{bulk_insert_buffer_size}
@item @code{query_cache_startup_type} @tab @code{query_cache_type}
@item @code{record_buffer} @tab @code{read_buffer_size}
@item @code{record_rnd_buffer} @tab @code{read_rnd_buffer_size}
@item @code{sort_buffer} @tab @code{sort_buffer_size}
@item @code{warnings} @tab @code{log-warnings}
@item @code{--err-log} @tab @code{--log-error} (for @command{mysqld_safe})
@end multitable

The startup options @code{record_buffer}, @code{sort_buffer}, and
@code{warnings} will still work in MySQL 4.0 but are deprecated.
@end itemize

@strong{SQL Changes:}

@itemize @bullet

@item
The following SQL variables have been renamed:

@c arjen note: New table, not yet measured for DocBook.
@multitable @columnfractions .50 .50
@item @strong{Old Name} @tab @strong{New Name}
@item @code{SQL_BIG_TABLES} @tab @code{BIG_TABLES}
@item @code{SQL_LOW_PRIORITY_UPDATES} @tab @code{LOW_PRIORITY_UPDATES}
@item @code{SQL_MAX_JOIN_SIZE} @tab @code{MAX_JOIN_SIZE}
@item @code{SQL_QUERY_CACHE_TYPE} @tab @code{QUERY_CACHE_TYPE}
@end multitable
The old names still work in MySQL 4.0 but are deprecated.

@item
You have to use @code{SET GLOBAL SQL_SLAVE_SKIP_COUNTER=skip_count} instead of
@code{SET SQL_SLAVE_SKIP_COUNTER=skip_count}.

@item
@code{SHOW MASTER STATUS} now returns an empty set if binary logging is not
enabled.

@item
@code{SHOW SLAVE STATUS} now returns an empty set if the slave is not
initialized.

@item
@code{SHOW INDEX} has two more columns than it had in 3.23 (@code{Null} and
@code{Index_type}).

@item
The format of @code{SHOW OPEN TABLES} has changed.

@item
@code{ORDER BY col_name DESC} sorts @code{NULL} values last, as of
MySQL 4.0.11. In 3.23 and in earlier 4.0 versions, this was not
always consistent.

@item
@code{CHECK}, @code{LOCALTIME}, and @code{LOCALTIMESTAMP}
now are reserved words.

@item
@code{DOUBLE} and @code{FLOAT} columns now honor the
@code{UNSIGNED} flag on storage (before, @code{UNSIGNED} was ignored for
these columns).

@item
The result of all bitwise operators (@code{|}, @code{&}, @code{<<},
@code{>>}, and @code{~}) is now unsigned.  This may cause problems if you
are using them in a context where you want a signed result.
@xref{Cast Functions}.

@strong{Note}: When you use subtraction between integer values where
one is of type @code{UNSIGNED}, the result will be unsigned.  In other
words, before upgrading to MySQL 4.0, you should check your application
for cases in which you are subtracting a value from an unsigned entity and
want a negative answer or subtracting an unsigned value from an
integer column. You can disable this behavior by using the
@code{--sql-mode=NO_UNSIGNED_SUBTRACTION} option when starting
@command{mysqld}.  @xref{Server SQL mode}.

@item
You should use integers to store values in @code{BIGINT} columns (instead
of using strings, as you did in MySQL 3.23).  Using strings will still
work, but using integers is more efficient.

@item
In MySQL 3.23, @code{INSERT INTO ... SELECT} always had @code{IGNORE} enabled.
As of 4.0.1, MySQL will stop (and possibly roll back) by default in case of
an error unless you specify @code{IGNORE}.

@item
You should use @code{TRUNCATE TABLE} when you want to delete all rows
from a table and you don't need to obtain a count of the number of rows
that were deleted.  (@code{DELETE FROM @var{tbl_name}} returns a row count in
4.0 and doesn't reset the @code{AUTO_INCREMENT} counter, and
@code{TRUNCATE TABLE} is faster.)

@item
You will get an error if you have an active transaction or @code{LOCK TABLES}
statement when trying to execute @code{TRUNCATE TABLE} or @code{DROP
DATABASE}.

@item
To use @code{MATCH ... AGAINST (... IN BOOLEAN MODE)} full-text searches
with your tables, you must rebuild their indexes with @code{REPAIR TABLE
tbl_name USE_FRM}.  If you attempt a boolean full-text search without
rebuilding the indexes this way, the search will return incorrect results.
@xref{Fulltext Fine-tuning}.

@item
@code{LOCATE()} and @code{INSTR()} are case sensitive if one of the
arguments is a binary string. Otherwise they are case insensitive.

@item
@code{STRCMP()} now uses the current character set when performing comparisons.
This makes the default comparison behavior not case sensitive unless
one or both of the operands are binary strings.

@item
@code{HEX(@var{str})} now returns the characters in @var{str} converted to
hexadecimal.  If you want to convert a number to hexadecimal, you should
ensure that you call @code{HEX()} with a numeric argument.

@item
@code{RAND(seed)} returns a different random number series in 4.0 than in
3.23; this was done to further differentiate @code{RAND(seed)} and
@code{RAND(seed+1)}.

@item
The default type returned by @code{IFNULL(A,B)} is now set to be the
more ``general'' of the types of @code{A} and @code{B}. (The general-to-specific
order is string, @code{REAL}, @code{INTEGER}).

@end itemize

@strong{C API Changes:}

@itemize @bullet

@item
The old C API functions @code{mysql_drop_db()}, @code{mysql_create_db()}, and
@code{mysql_connect()} are no longer supported unless you compile
MySQL with @code{CFLAGS=-DUSE_OLD_FUNCTIONS}.  However, it is preferable
to change client programs to use the new 4.0 API instead.

@item
In the @code{MYSQL_FIELD} structure, @code{length} and @code{max_length} have
changed from @code{unsigned int} to @code{unsigned long}. This should not
cause any problems, except that they may generate warning messages when
used as arguments in the @code{printf()} class of functions.

@item
Multi-threaded clients should use @code{mysql_thread_init()} and
@code{mysql_thread_end()}. @xref{Threaded clients}.

@end itemize

@strong{Other Changes:}

@itemize @bullet

@item
If you want to recompile the Perl @code{DBD::mysql} module, use a recent
version.  Version 2.9003 is recommended. Versions older than 1.2218 should
not be used because they use the deprecated @code{mysql_drop_db()} call.

@end itemize


@node Upgrading-from-3.22, Upgrading-from-3.21, Upgrading-from-3.23, Upgrade
@subsection Upgrading from Version 3.22 to 3.23

@cindex compatibility, between MySQL versions
@cindex upgrading, 3.22 to 3.23

MySQL 3.22 and 3.21 clients will work without any problems with a MySQL
3.23 server.

When upgrading to MySQL 3.23 from an earlier version, note the following
changes:

@strong{Table Changes:}

@itemize @bullet

@item
MySQL 3.23 supports tables of the new @code{MyISAM} type and the old
@code{ISAM} type.  By default, all new tables are created with type
@code{MyISAM} unless you start @command{mysqld} with the
@code{--default-table-type=isam} option.  You don't have to convert your old
@code{ISAM} tables to use them with MySQL 3.23.  You can convert an
@code{ISAM} table to @code{MyISAM} format with @code{ALTER TABLE @var{tbl_name}
TYPE=MyISAM} or the Perl script @code{mysql_convert_table_format}.

@item
All tables that use the @code{tis620} character set must be fixed
with @command{myisamchk -r} or @code{REPAIR TABLE}.

@item
If you are using the @code{german} character sort order for @code{ISAM}
tables, you must repair them with @command{isamchk -r}, because we have made
some changes in the sort order.

@end itemize

@strong{Client Program Changes:}

@itemize @bullet
@item
The MySQL client @command{mysql} is now by default started with the
@code{--no-named-commands (-g)} option. This option can be disabled with
@code{--enable-named-commands (-G)}. This may cause incompatibility problems in
some cases---for example, in SQL scripts that use named commands without a
semicolon.  Long format commands still work from the first line.

@item
If you want your @command{mysqldump} files to be compatible between
MySQL 3.22 and 3.23, you should not use the
@code{--opt} or @code{--all} option to @command{mysqldump}.

@end itemize

@strong{SQL Changes:}

@itemize @bullet
@item
If you do a @code{DROP DATABASE} on a symbolically linked database, both the
link and the original database are deleted.  This didn't happen in MySQL 3.22
because @command{configure} didn't detect the availability of the
@code{readlink()} system call.

@item
@code{OPTIMIZE TABLE} now works only for @code{MyISAM} tables.
For other table types, you can use @code{ALTER TABLE} to optimize the table.
During @code{OPTIMIZE TABLE}, the table is now locked to prevent it from being
used by other threads.

@item
Date functions that work on parts of dates (such as @code{MONTH()}) will now
return 0 for @code{0000-00-00} dates. In MySQL 3.22, these functions returned
@code{NULL}.

@item
The default return type of @code{IF()} now depends on both arguments,
not just the first one.

@item
@code{AUTO_INCREMENT} columns should not be used to store negative
numbers. The reason for this is that negative numbers caused problems
when wrapping from @minus{}1 to 0.  You should not store 0 in @code{AUTO_INCREMENT}
columns, either; @code{CHECK TABLE} will complain about 0 values because
they may change if you dump and restore the table.  @code{AUTO_INCREMENT}
for @code{MyISAM} tables is now handled at a lower level and is much
faster than before. In addition, for @code{MyISAM} tables, old numbers
are no longer reused, even if you delete rows from the table.

@item
@code{CASE}, @code{DELAYED}, @code{ELSE}, @code{END}, @code{FULLTEXT},
@code{INNER}, @code{RIGHT}, @code{THEN}, and @code{WHEN} now are reserved words.

@item
@code{FLOAT(p)} now is a true floating-point type and not a value with a
fixed number of decimals.

@item
When declaring columns using a @code{DECIMAL(length,dec)} type, the
@code{length} argument no longer includes a place for the sign or the
decimal point.

@item
A @code{TIME} string must now be of one of the following formats:
@code{[[[DAYS] [H]H:]MM:]SS[.fraction]} or
@code{[[[[[H]H]H]H]MM]SS[.fraction]}.

@item
@code{LIKE} now compares strings using the same character comparison rules
as for the @code{=} operator.  If you require the old behavior, you can
compile MySQL with the @code{CXXFLAGS=-DLIKE_CMP_TOUPPER} flag.

@item
@code{REGEXP} now is case insensitive if neither of the strings is a binary
string.

@item
When you check or repair @code{MyISAM} (@file{.MYI}) tables, you should use
the @code{CHECK TABLE} statement or the @command{myisamchk} command. For
@code{ISAM} (@file{.ISM}) tables, use the @command{isamchk} command.

@item
Check all your calls to @code{DATE_FORMAT()} to make sure that there is a
@samp{%} before each format character.
(MySQL 3.22 already allowed this syntax, but now @samp{%} is required.)

@item
In MySQL 3.22, the output of @code{SELECT DISTINCT ...} was
almost always sorted.  In MySQL 3.23, you must use @code{GROUP BY} or
@code{ORDER BY} to obtain sorted output.

@item
@code{SUM()} now returns @code{NULL} instead of 0 if
there are no matching rows. This is required by standard SQL.

@item
An @code{AND} or @code{OR} with @code{NULL} values will now return
@code{NULL} instead of 0. This mostly affects queries that use @code{NOT}
on an @code{AND/OR} expression as @code{NOT NULL} = @code{NULL}.

@item
@code{LPAD()} and @code{RPAD()} now shorten the result string if it's longer
than the length argument.

@end itemize

@strong{C API Changes:}

@itemize @bullet
@item
@code{mysql_fetch_fields_direct()} now is a function instead of a macro.
It now returns a pointer to a @code{MYSQL_FIELD} instead of a
@code{MYSQL_FIELD}.

@item
@code{mysql_num_fields()} no longer can be used on a @code{MYSQL*} object (it's
now a function that takes a @code{MYSQL_RES*} value as an argument). With a
@code{MYSQL*} object, you now should use @code{mysql_field_count()} instead.

@end itemize


@node Upgrading-from-3.21, Upgrading-from-3.20, Upgrading-from-3.22, Upgrade
@subsection Upgrading from Version 3.21 to 3.22

@cindex compatibility, between MySQL versions
@cindex upgrading, 3.21 to 3.22

Nothing that affects compatibility has changed between versions 3.21 and 3.22.
The only pitfall is that new tables that are created with @code{DATE} type
columns will use the new way to store the date. You can't access these new
columns from an old version of @command{mysqld}.

When upgrading to MySQL 3.23 from an earlier version, note the following
changes:

@itemize @bullet
@item
After installing MySQL Version 3.22, you should start the new server
and then run the @command{mysql_fix_privilege_tables} script. This will add the
new privileges that you need to use the @code{GRANT} command.  If you forget
this, you will get @code{Access denied} when you try to use @code{ALTER
TABLE}, @code{CREATE INDEX}, or @code{DROP INDEX}. The procedure for updating
the grant tables is described in @ref{Upgrading-grant-tables}.

@item
The C API interface to @code{mysql_real_connect()} has changed.  If you have
an old client program that calls this function, you must pass a @code{0} for
the new @code{db} argument (or recode the client to send the @code{db}
element for faster connections).  You must also call @code{mysql_init()}
before calling @code{mysql_real_connect()}.  This change was done to allow
the new @code{mysql_options()} function to save options in the @code{MYSQL}
handler structure.

@item
The @command{mysqld} variable @code{key_buffer} has been renamed to
@code{key_buffer_size}, but you can still use the old name in your
startup files.

@end itemize


@node Upgrading-from-3.20, Upgrading-grant-tables, Upgrading-from-3.21, Upgrade
@subsection Upgrading from Version 3.20 to 3.21

@cindex upgrading, 3.20 to 3.21

If you are running a version older than Version 3.20.28 and want to
switch to Version 3.21, you need to do the following:

You can start the @command{mysqld} Version 3.21 server with the
@code{--old-protocol} option to use it with clients from a Version 3.20
distribution.  In this case, the server uses the old pre-3.21
@code{password()} checking rather than the new method. Also, the new client
function @code{mysql_errno()} will not return any server error, only
@code{CR_UNKNOWN_ERROR}. The function does work for client errors.

If you are @emph{not} using the @code{--old-protocol} option to
@command{mysqld}, you will need to make the following changes:

@itemize @bullet

@item
All client code must be recompiled. If you are using ODBC, you must get
the MyODBC 2.x driver.

@item
The @code{scripts/add_long_password} script must be run to convert the
@code{Password} field in the @code{mysql.user} table to @code{CHAR(16)}.

@item
All passwords must be reassigned in the @code{mysql.user} table to get 62-bit
rather than 31-bit passwords.

@item
The table format hasn't changed, so you don't have to convert any tables.

@end itemize

MySQL 3.20.28 and above can handle the new @code{user} table
format without affecting clients. If you have a MySQL version earlier
than 3.20.28, passwords will no longer work with it if you convert the
@code{user} table. So to be safe, you should first upgrade to at least Version
3.20.28 and then upgrade to Version 3.21.

@cindex Protocol mismatch
The new client code works with a 3.20.x @command{mysqld} server, so
if you experience problems with 3.21.x, you can use the old 3.20.x server
without having to recompile the clients again.

If you are not using the @code{--old-protocol} option to @command{mysqld},
old clients will be unable to connect and will issue the following error
message:

@example
ERROR: Protocol mismatch. Server Version = 10 Client Version = 9
@end example

The Perl DBI interface also supports the old
@code{mysqlperl} interface.  The only change you have to make if you use
@code{mysqlperl} is to change the arguments to the @code{connect()} function.
The new arguments are: @code{host}, @code{database}, @code{user},
and @code{password} (note that the @code{user} and @code{password} arguments
have changed places).

The following changes may affect queries in old applications:

@itemize @bullet

@item
@code{HAVING} must now be specified before any @code{ORDER BY} clause.

@item
The parameters to @code{LOCATE()} have been swapped.

@item
There are some new reserved words. The most noticeable are @code{DATE},
@code{TIME}, and @code{TIMESTAMP}.

@end itemize


@node Upgrading-grant-tables, Upgrading-to-arch, Upgrading-from-3.20, Upgrade
@subsection Upgrading the Grant Tables

@cindex upgrading, grant tables
@cindex grant tables, upgrading

Some releases introduce changes to the structure of the grant tables
(the tables in the @code{mysql} database)
to add new  privileges or features. To make sure that your grant tables
are current when you update to a new version of MySQL, you should update
your grant tables as well.

On Unix or Unix-like systems, update the grant tables by running the
@command{mysql_fix_privilege_tables} script:

@example
shell> mysql_fix_privilege_tables
@end example

You must run this script while the server is running. It attempts to
connect to the server running on the local host as @code{root}.
If your @code{root} account requires a password, indicate the password
on the command line.  For MySQL 4.1 and up, specify the password like this:

@example
shell> mysql_fix_privilege_tables --password=root_password
@end example

Prior to MySQL 4.1, specify the password like this:

@example
shell> mysql_fix_privilege_tables root_password
@end example

The @command{mysql_fix_privilege_tables} script performs any actions
necessary to convert your grant tables to the current format. You
might see some @code{Duplicate column name} warnings as it runs; you can
ignore them.

After running the script, stop the server and restart it.

On Windows systems, there isn't an easy way to update the grant tables
until MySQL 4.0.15.  From version 4.0.15 on, MySQL distributions include a
@file{mysql_fix_privilege_tables.sql} SQL script that you can run using
the @command{mysql} client.  If your MySQL installation is located at
@file{C:\mysql}, the commands look like this: 

@example
C:\> C:\mysql\bin\mysql -u root -p mysql
mysql> SOURCE C:\mysql\scripts\mysql_fix_privilege_tables.sql
@end example

If your installation is located in some other directory, adjust the
pathnames appropriately.

The @command{mysql} command will prompt you for the @code{root} password; enter it
when prompted.

As with the Unix procedure, you might see some @code{Duplicate column name}
warnings as @command{mysql} processes the statements in the
@file{mysql_fix_privilege_tables.sql} script; you can ignore them.

After running the script, stop the server and restart it.

If you are upgrading to MySQL 5.0.1 or later, the grant table upgrade
procedure just described will add view-related columns for the
@code{CREATE VIEW} and @code{SHOW VIEW} privileges.  These privileges
exist at the global and database levels. Their initial values are assigned
as follows:

@itemize @bullet

@item
In MySQL 5.0.2 or later, @command{mysql_fix_privilege_tables}
copies the @code{Create_priv} value in the @code{user} table to the
@code{Create_view_priv} and @code{Show_view_priv} columns.

@item
In 5.0.1, the view-related privileges are not enabled for any accounts, so
you cannot immediately use @code{GRANT} to give them give them to accounts
that should have them. To deal with this, first connect to the server as
@code{root} and issue the following statements to give the privileges to
the @code{root} accounts manually with @code{UPDATE}:

@example
mysql> UPDATE mysql.user SET Show_view_priv = 'Y', Create_view_priv = 'Y'
    -> WHERE User = 'root';
mysql> FLUSH PRIVILEGES;
@end example

After this, @code{root} can use @code{GRANT} to give the view privileges
to other accounts. Note: You should issue the statements just shown,
@code{GRANT ALL} will not work at the global and database levels, because
@code{GRANT ALL} requires that you actually possess all privileges.

@end itemize


@node Upgrading-to-arch,  , Upgrading-grant-tables, Upgrade
@subsection Copying MySQL Databases to Another Machine

@cindex upgrading, different architecture
@cindex copying databases
@cindex databases, copying

If you are using MySQL 3.23 or later, you can copy the @file{.frm},
@file{.MYI}, and @file{.MYD} files for @code{MyISAM} tables between different
architectures that support the same floating-point format.  (MySQL takes care
of any byte-swapping issues.)
@xref{MyISAM storage engine, , @code{MyISAM} storage engine}.

The MySQL @code{ISAM} data and index files (@file{.ISD} and @file{*.ISM},
respectively) are architecture dependent and in some cases operating
system dependent.  If you want to move your applications to another
machine that has a different architecture or operating system than your
current machine, you should not try to move a database by simply copying
the files to the other machine. Use @command{mysqldump} instead.

By default, @command{mysqldump} will create a file containing SQL statements.
You can then transfer the file to the other machine and feed it as input
to the @command{mysql} client.

Try @command{mysqldump --help} to see what options are available.
If you are moving the data to a newer version of MySQL, you should use
@command{mysqldump --opt} to take advantage of any optimizations that result
in a dump file that is smaller and can be processed faster.

The easiest (although not the fastest) way to move a database between two
machines is to run the following commands on the machine on which the
database is located:

@example
shell> mysqladmin -h '@var{other_hostname}' create @var{db_name}
shell> mysqldump --opt @var{db_name} | mysql -h '@var{other_hostname}' @var{db_name}
@end example

@c TODO: next example not only changes copy direction (from local->remote
@c to remote->local), it adds --compress.  But --compress is a separate
@c thing and can be used no matter the copy direction.  Split into two
@c examples.

If you want to copy a database from a remote machine over a slow network,
you can use:

@example
shell> mysqladmin create @var{db_name}
shell> mysqldump -h '@var{other_hostname}' --opt --compress @var{db_name} | mysql @var{db_name}
@end example

You can also store the result in a file, then transfer the file to the
target machine and load the file into the database there.  For example,
you can dump a database to a file on the source machine like this:

@example
shell> mysqldump --quick @var{db_name} | gzip > @var{db_name.contents}.gz
@end example

(The file created in this example is compressed.) Transfer the file
containing the database contents to the target machine and run these commands
there:

@example
shell> mysqladmin create @var{db_name}
shell> gunzip < @var{db_name.contents}.gz | mysql @var{db_name}
@end example

@cindex @command{mysqldump}
@cindex @command{mysqlimport}
You can also use @command{mysqldump} and @command{mysqlimport} to transfer
the database.
For big tables, this is much faster than simply using @command{mysqldump}.
In the following commands, @code{DUMPDIR} represents the full pathname
of the directory you use to store the output from @command{mysqldump}.

First, create the directory for the output files and dump the database:

@example
shell> mkdir DUMPDIR
shell> mysqldump --tab=DUMPDIR @var{db_name}
@end example

Then transfer the files in the @code{DUMPDIR} directory to some corresponding
directory on the target machine and load the files into MySQL
there:

@example
shell> mysqladmin create @var{db_name}           # create database
shell> cat DUMPDIR/*.sql | mysql @var{db_name}   # create tables in database
shell> mysqlimport @var{db_name} DUMPDIR/*.txt   # load data into tables
@end example

Also, don't forget to copy the @code{mysql} database because that is
where the @code{user}, @code{db}, and @code{host} grant tables are stored.
You might have to run commands as the MySQL @code{root} user on the new
machine until you have the @code{mysql} database in place.

After you import the @code{mysql} database on the new machine, execute
@command{mysqladmin flush-privileges} so that the server reloads the grant table
information.

@node Downgrading, Operating System Specific Notes, Upgrade, Installing
@section Downgrading MySQL

@cindex downgrading

This section describes what you should do if you are downgrading to an
older MySQL version in the unlikely case that the previous version worked
better than the new one.

If you are downgrading within the same release series (for example, from
4.0.20 to 4.0.19) the general rule is that you just have to install the
new binaries on top of the old ones. There is no need to do anything with
the databases.  As always, however, it's always a good idea to make a backup.

The following items form a checklist of things you should do whenever you
perform an downgrade:

@itemize @bullet
@item
Read the upgrading section for the release series from which you are
downgrading to be sure that it doesn't have any features you really need.
@ref{Upgrade}.

@item
If there is a downgrading section for that version, please read it, too!
@end itemize

You can always move the MySQL format files and data files between different
versions on the same architecture as long as you stay within versions for
the same release series of MySQL. The current production release series is
4.1.

If you downgrade from one release series to another, there may be
incompatibilities in table storage formats. In this case, you can use
@command{mysqldump} to dump your tables before dowgnrading.  After
downgrading, reload the dump file using @command{mysql} or @code{mysqlimport}
to re-create your tables.  See @ref{Upgrading-to-arch} for examples.

The normal symptom of a downward-incompatible table format change when you
downgrade is you can't open tables.  In that case, use the follwing procedure:

@enumerate
@item
Stop the older MySQL server that you are trying to downgrade to.
@item
Restart the newer MySQL server you are trying to downgrade from.
@item
Dump any tables that were inaccessible to the older server by using
@command{mysqldump} to create a dump file.
@item
Stop the newer MySQL server and restart the older one.
@item
Reload the dump file into the older server. Your tables now should be
accessible.
@end enumerate

@menu
* Downgrading to-4.0::          Downgrading to 4.0
@end menu

@node Downgrading to-4.0,  , Downgrading, Downgrading
@subsection Downgrading to 4.0

The table format in 4.1 changed to include more and new character set
information. Because of this, you must use @code{mysqldump} to dump any tables
you have created with the newer MySQL server.  For example, if all the tables
in a particular database need to be dumped to be reverted back to MySQL 4.0
format, use this command:

@example
shell> mysqldump --create-options --compatible=mysql40 @var{db_name} > @var{dump_file}
@end example

Then stop the newer server, restart the older server, and read in the dump
file:

@example
shell> mysql @var{db_name} < @var{dump_file}
@end example

If you used the @code{mysql_fix_privilege_tables} script to upgrade the
grant tables, you can either use the preceding method to convert them to back to
MySQL 4.0 or do the following in MySQL 4.1 (or above):

@example
ALTER TABLE mysql.user CONVERT TO CHARACTER SET latin1 COLLATE latin1_swedish_ci;
ALTER TABLE mysql.db CONVERT TO CHARACTER SET latin1 COLLATE latin1_swedish_ci;
ALTER TABLE mysql.host CONVERT TO CHARACTER SET latin1 COLLATE latin1_swedish_ci;
ALTER TABLE mysql.tables_priv CONVERT TO CHARACTER SET latin1 COLLATE latin1_swedish_ci;
ALTER TABLE mysql.columns_priv CONVERT TO CHARACTER SET latin1 COLLATE latin1_swedish_ci;
ALTER TABLE mysql.func CONVERT TO CHARACTER SET latin1 COLLATE latin1_swedish_ci;
@end example


@node Operating System Specific Notes, Perl support, Downgrading, Installing
@section Operating System-Specific Notes

@menu
* Linux::                       Linux Notes
* Mac OS X::                    Mac OS X Notes
* Solaris::                     Solaris Notes
* BSD Notes::                   BSD Notes
* Other Unix Notes::            Other Unix Notes
* OS/2::                        OS/2 Notes
* BeOS::                        BeOS Notes
@end menu


@node Linux, Mac OS X, Operating System Specific Notes, Operating System Specific Notes
@subsection Linux Notes

This section discusses issues that have been found to occur on Linux.
The first few subsections describe general operating system-related issues,
problems that can occur when using binary or source distributions, and
post-installation issues. The remaining subsections discuss problems that occur
with Linux on specific platforms.

Note that most of these problems occur on older versions of Linux. If you are
running a recent version, you likely will see none of them.

@menu
* Linux-OS::                    Linux Operating System Notes
* Binary notes-Linux::          Linux Binary Distribution Notes
* Source notes-Linux::          Linux Source Distribution Notes
* Linux-post-install::          Linux Post-Installation Notes
* Linux-x86::                   Linux x86 Notes
* Linux-SPARC::                 Linux SPARC Notes
* Linux-Alpha::                 Linux Alpha Notes
* Linux-PowerPC::               Linux PowerPC Notes
* Linux-MIPS::                  Linux MIPS Notes
* Linux-IA-64::                 Linux IA-64 Notes
@end menu


@node Linux-OS, Binary notes-Linux, Linux, Linux
@subsubsection Linux Operating System Notes

MySQL needs at least Linux Version 2.0.

@strong{Warning:}
We have seen some strange problems with Linux 2.2.14 and MySQL on SMP
systems.  We also have reports from some MySQL users that they have
encountered serious stability problems using MySQL with kernel 2.2.14.
If you are using this kernel, you should upgrade to 2.2.19 (or newer) or to
a 2.4 kernel.  If you have a multiple-CPU box, then you should seriously
consider using 2.4 because it will give you a significant speed boost.
Your system also will be more stable.

@c TODO: this isn't really an "issue"; put in a FAQ somewhere:
@c "Why do I always see at least three mysqld processes on Linux?"

When using LinuxThreads, you will see a minimum of three @command{mysqld} processes
running.  These are in fact threads.  There will be one thread for the
LinuxThreads manager, one thread to handle connections, and one thread
to handle alarms and signals.


@node Binary notes-Linux, Source notes-Linux, Linux-OS, Linux
@subsubsection Linux Binary Distribution Notes

@cindex binary distributions, on Linux
@cindex Linux, binary distribution

The Linux-Intel binary and RPM releases of MySQL are configured
for the highest possible speed.  We are always trying to use the fastest
stable compiler available.

The binary release is linked with @code{-static}, which means you do not
normally need to worry about which version of the system libraries you
have. You need not install LinuxThreads, either.  A program linked with
@code{-static} is slightly larger than a dynamically linked program,
but also slightly faster (3-5%).  However, one problem with a statically
linked program is that you can't use user-defined functions (UDFs).
If you are going to write or use UDFs (this is something for C or C++
programmers only), you must compile MySQL yourself using dynamic linking.

A known issue with binary distributions is that on older Linux
systems that use @code{libc} (such as Red Hat 4.x or Slackware), you will get
some non-fatal problems with hostname resolution. If your system uses
@code{libc} rather than @code{glibc2},
you probably will encounter some difficulties with hostname resolution and
@code{getpwnam()}. This happens because @code{glibc}
unfortunately depends on some external libraries to implement hostname
resolution and @code{getpwent()}, even when compiled with @code{-static}.
These problems manifest themselves in two ways:

@itemize @bullet
@item
You probably will see  the following error message when you run
@command{mysql_install_db}:

@example
Sorry, the host '@var{xxxx}' could not be looked up
@end example

You can deal with this by executing
@command{mysql_install_db --force}, which will not execute the
@command{resolveip} test in @command{mysql_install_db}.  The downside is that
you can't use hostnames in the grant tables: Except for @code{localhost},
you must use IP numbers instead.  If you are using an old version of MySQL
that doesn't support @code{--force}, you must manually remove the
@code{resolveip} test in @code{mysql_install} using an editor.

@item
You also may see
the following error when you try to run @command{mysqld} with the @code{--user}
option:

@example
getpwnam: No such file or directory
@end example

To work around this, start @command{mysqld} by using
the @code{su} command rather than by specifying the @code{--user}
option. This causes the system itself to change the user ID of the
@command{mysqld} process so that @command{mysqld} need not do so.

@end itemize

Another solution, which solves both problems, is to not use a binary
distribution.  Get a MySQL source distribution (in RPM or @code{tar.gz}
format) and install that instead.

On some Linux 2.2 versions, you may get the error @code{Resource
temporarily unavailable} when clients make a lot of new connections to
a @command{mysqld} server over TCP/IP.  The problem is that Linux has a
delay between the time that you close a TCP/IP socket and the time that
the system actually frees it.  There is room for only a finite number
of TCP/IP slots, so you will encounter the resource-unavailable error if
clients attempt too many new TCP/IP connections during a short time. For
example, you may see the error when you run the MySQL @file{test-connect}
benchmark over TCP/IP.

We have inquired about this problem a few times on different Linux mailing
lists but have never been able to find a suitable resolution.  The only
known ``fix'' is for the clients to use persistent connections, or,
if you are running the database server and clients on the same machine,
to use Unix socket file connections rather than TCP/IP connections.


@node Source notes-Linux, Linux-post-install, Binary notes-Linux, Linux
@subsubsection Linux Source Distribution Notes

@cindex source distributions, on Linux
@cindex Linux, source distribution

The following notes regarding @code{glibc} apply only to the situation
when you build MySQL
yourself. If you are running Linux on an x86 machine, in most cases it is
much better for you to just use our binary. We link our binaries against
the best patched version of @code{glibc} we can come up with and with the
best compiler options, in an attempt to make it suitable for a high-load
server.  For a typical user, even for setups with a lot of concurrent
connections or tables exceeding the 2GB limit, our binary is
the best choice in most cases.  After reading the following text, if you
are in doubt about what to do, try our binary first to see whether it meets
your needs.  If you discover that it is not good enough, then
you may want to try your own build.  In that case, we would appreciate
a note about it so that we can build a better binary next time.

MySQL uses LinuxThreads on Linux.  If you are using an old
Linux version that doesn't have @code{glibc2}, you must install
LinuxThreads before trying to compile MySQL.   You can get
LinuxThreads at @uref{http://dev.mysql.com/downloads/os-linux.html}.

Note that @code{glibc} versions before and including Version 2.1.1 have
a fatal bug in @code{pthread_mutex_timedwait()} handling, which is used
when you issue @code{INSERT DELAYED} statements.  We recommend that you not use
@code{INSERT DELAYED} before upgrading @code{glibc}.

Note that Linux kernel and the LinuxThread library can by default
only have 1,024 threads.  If you plan to have more than 1,000 concurrent
connections, you will need to make some changes to LinuxThreads:

@itemize @bullet
@item
Increase @code{PTHREAD_THREADS_MAX} in
@file{sysdeps/unix/sysv/linux/bits/local_lim.h} to 4096 and decrease
@code{STACK_SIZE} in @file{linuxthreads/internals.h} to 256KB. The
paths are relative to the root of @code{glibc}. (Note that MySQL will
not be stable with around 600-1000 connections if @code{STACK_SIZE}
is the default of 2MB.)

@item
Recompile LinuxThreads to produce a new @file{libpthread.a} library,
and relink MySQL against it.

@end itemize

The page @uref{http://www.volano.com/linuxnotes.html} contains additional
information about circumventing thread limits in LinuxThreads.

There is another issue that greatly hurts MySQL performance, especially on
SMP systems.  The mutex implementation in LinuxThreads in @code{glibc}
2.1 is very bad for programs with many threads that hold the mutex
only for a short time.  This produces a paradoxical result: If you link
MySQL against an unmodified LinuxThreads, removing processors from an
SMP actually improves MySQL performance in many cases.  We have made a
patch available for @code{glibc} 2.1.3 to correct this behavior
(@uref{http://www.mysql.com/Downloads/Linux/linuxthreads-2.1-patch}).

With @code{glibc} 2.2.2,
MySQL 3.23.36 will use the adaptive mutex, which is much
better than even the patched one in @code{glibc} 2.1.3. Be warned, however,
that under some conditions, the current mutex code in @code{glibc} 2.2.2
overspins, which hurts MySQL performance. The likelihood that this condition
will occur can be reduced by renicing the @command{mysqld} process to the highest
priority. We have also been able to correct the overspin behavior with
a patch, available at
@uref{http://www.mysql.com/Downloads/Linux/linuxthreads-2.2.2.patch}.
It combines the correction of overspin, maximum number of
threads, and stack spacing all in one. You will need to apply it in the
@code{linuxthreads} directory with
@code{patch -p0 </tmp/linuxthreads-2.2.2.patch}.
We hope it will be included in
some form in future releases of @code{glibc} 2.2. In any case, if
you link against @code{glibc} 2.2.2, you still need to correct
@code{STACK_SIZE} and @code{PTHREAD_THREADS_MAX}. We hope that the defaults
will be corrected to some more acceptable values for high-load
MySQL setup in the future, so that the commands needed to produce
your own build can be reduced to @command{./configure; make; make install}.

We recommend that you use these patches to build a special static
version of @code{libpthread.a} and use it only for statically linking
against MySQL. We know that the patches are safe for MySQL
and significantly improve its performance, but we cannot say anything
about other applications. If you link other applications that require
LinuxThreads against the
patched static version of the library, or build a patched shared version and
install it on your system, you do so at your own risk.

If you experience any strange problems during the installation of
MySQL, or with some common utilities hanging, it is very likely that
they are either library or compiler related. If this is the case, using our
binary will resolve them.

If you link your own MySQL client programs, you may see the following error at
runtime:

@example
ld.so.1: fatal: libmysqlclient.so.#:
open failed: No such file or directory
@end example

This problem can be avoided by one of the following methods:

@itemize @bullet
@item
Link clients with the @code{-Wl,r/full/path/to/libmysqlclient.so}
flag rather than with @code{-Lpath}).

@item
Copy @code{libmysqclient.so} to @file{/usr/lib}.

@tindex LD_RUN_PATH environment variable
@tindex environment variable, LD_RUN_PATH
@item
Add the pathname of the directory where @file{libmysqlclient.so} is located
to the @code{LD_RUN_PATH} environment variable before running your client.
@end itemize

If you are using the Fujitsu compiler (@code{fcc/FCC}), you will have
some problems compiling MySQL because the Linux header files are very
@command{gcc} oriented.
The following @command{configure} line should work with @command{fcc/FCC}:

@example
CC=fcc CFLAGS="-O -K fast -K lib -K omitfp -Kpreex -D_GNU_SOURCE \
    -DCONST=const -DNO_STRTOLL_PROTO" \
CXX=FCC CXXFLAGS="-O -K fast -K lib \
    -K omitfp -K preex --no_exceptions --no_rtti -D_GNU_SOURCE \
    -DCONST=const -Dalloca=__builtin_alloca -DNO_STRTOLL_PROTO \
    '-D_EXTERN_INLINE=static __inline'" \
./configure \
    --prefix=/usr/local/mysql --enable-assembler \
    --with-mysqld-ldflags=-all-static --disable-shared \
    --with-low-memory
@end example


@node Linux-post-install, Linux-x86, Source notes-Linux, Linux
@subsubsection Linux Post-Installation Notes

@command{mysql.server} can be found in the @file{support-files} directory under
the MySQL installation directory or in a MySQL source tree.  You can install
it as @file{/etc/init.d/mysql} for automatic MySQL startup and shutdown.
@xref{Automatic start}.

If MySQL can't open enough files or connections, it may be that
you haven't configured Linux to handle enough files.

In Linux 2.2 and onward, you can check the number of allocated
file handles as follows:

@example
shell> cat /proc/sys/fs/file-max
shell> cat /proc/sys/fs/dquot-max
shell> cat /proc/sys/fs/super-max
@end example

If you have more than 16MB of memory, you should add something like the
following to your init scripts (for example, @file{/etc/init.d/boot.local} on SuSE Linux):

@example
echo 65536 > /proc/sys/fs/file-max
echo 8192 > /proc/sys/fs/dquot-max
echo 1024 > /proc/sys/fs/super-max
@end example

You can also run the @code{echo} commands from the command line as @code{root},
but these settings will be lost the next time your computer restarts.

Alternatively, you can set these parameters on startup by using the
@code{sysctl} tool, which is used by many Linux distributions (SuSE has
added it as well, beginning with SuSE Linux 8.0). Just put the following
values into a file named @file{/etc/sysctl.conf}:

@example
# Increase some values for MySQL
fs.file-max = 65536
fs.dquot-max = 8192
fs.super-max = 1024
@end example

You should also add the following to @file{/etc/my.cnf}:

@example
[mysqld_safe]
open-files-limit=8192
@end example

This should allow the server a limit of 8,192 for the combined number of
connections and open files.

The @code{STACK_SIZE} constant in LinuxThreads controls the spacing of thread
stacks in the address space.  It needs to be large enough so that there will
be plenty of room for each individual thread stack, but small enough
to keep the stack of some threads from running into the global @command{mysqld}
data.  Unfortunately, as we have experimentally discovered, the Linux
implementation of @code{mmap()} will successfully unmap an already mapped
region if you ask it to map out an address already in use, zeroing out the data
on the entire page instead of returning an error.  So, the safety of
@command{mysqld} or any other threaded application depends on ``gentlemanly''
behavior of the code that creates threads.  The user must take measures to
make sure that the number of running threads at any time is sufficiently low for
thread stacks to stay away from the global heap.  With @command{mysqld}, you
should enforce this behavior by setting a reasonable value for
the @code{max_connections} variable.

If you build MySQL yourself, you can patch LinuxThreads for better stack use.
@xref{Source notes-Linux}.
If you do not want to patch
LinuxThreads, you should set @code{max_connections} to a value no higher
than 500.  It should be even less if you have a large key buffer,  large
heap tables, or some other things that make @command{mysqld} allocate a lot
of memory, or if you are running a 2.2 kernel with a 2GB patch. If you are
using our binary or RPM version 3.23.25 or later, you can safely set
@code{max_connections} at 1500, assuming no large key buffer or heap tables
with lots of data.  The more you reduce @code{STACK_SIZE} in LinuxThreads
the more threads you can safely create.  We recommend values between
128KB and 256KB.

If you use a lot of concurrent connections, you may suffer from a ``feature''
in the 2.2 kernel that attempts to prevent fork bomb attacks by penalizing
a process for forking or cloning a child.  This causes MySQL
not to scale well as you increase the number of concurrent clients.  On
single-CPU systems, we have seen this manifested as very slow thread
creation: It may take a long time to connect to MySQL
(as long as one minute), and it may take just as long to shut it down.  On
multiple-CPU systems, we have observed a gradual drop in query speed as
the number of clients increases.  In the process of trying to find a
solution, we have received a kernel patch from one of our users who
claimed it made a lot of difference for his site.  The patch is available at
@uref{http://www.mysql.com/Downloads/Patches/linux-fork.patch}. We have
now done rather extensive testing of this patch on both development and
production systems.  It has significantly
improved MySQL performance without causing any problems and we now
recommend it to our users who still run high-load servers on
2.2 kernels.

This issue has been fixed in the 2.4 kernel, so if you are not satisfied
with the current performance of your system, rather than patching
your 2.2 kernel, it might be easier to upgrade to 2.4. On SMP systems,
upgrading also will give you a nice SMP boost in addition to fixing the
fairness bug.

We have tested MySQL on the 2.4 kernel on a two-CPU machine and found MySQL
scales @emph{much} better. There was virtually no slowdown on query
throughput all the way up to 1,000 clients, and the MySQL scaling factor
(computed as the ratio of maximum throughput to the throughput for one
client) was 180%.  We have observed similar results on a four-CPU system:
Virtually no slowdown as the number of clients was increased up to 1,000,
and a 300% scaling factor. Based on these results, for a high-load SMP
server using a 2.2 kernel, we definitely recommend upgrading to the 2.4
kernel at this point.

We have discovered that it is essential to run the @command{mysqld} process
with the highest possible priority on the 2.4 kernel to achieve maximum
performance.  This can be done by adding a @code{renice -20 $$} command
to @command{mysqld_safe}. In our testing on a four-CPU machine, increasing
the priority resulted in a 60% throughput increase with 400 clients.

We are currently also trying to collect more information on how well
MySQL performs with a 2.4 kernel on four-way and eight-way systems. If you have
access such a system and have done some benchmarks, please send an email
message to @email{benchmarks@@mysql.com} with the results. We will review
them for inclusion in the manual.

If you see a dead @command{mysqld} server process with @command{ps}, this usually
means that you have found a bug in MySQL or you have a corrupted
table. @xref{Crashing}.

To get a core dump on Linux if @command{mysqld} dies with a @code{SIGSEGV} signal,
you can start @command{mysqld} with the @code{--core-file} option.  Note
that you also probably need to raise the core file size by adding
@command{ulimit -c 1000000} to @command{mysqld_safe} or starting
@command{mysqld_safe} with @code{--core-file-size=1000000}.
@xref{mysqld_safe, , @command{mysqld_safe}}.


@node Linux-x86, Linux-SPARC, Linux-post-install, Linux
@subsubsection Linux x86 Notes

MySQL requires @code{libc} Version 5.4.12 or newer. It's known to
work with @code{libc} 5.4.46.  @code{glibc} Version 2.0.6 and later should
also work. There have been some problems with the @code{glibc} RPMs from
Red Hat, so if you have problems, check whether there are any updates.
The @code{glibc} 2.0.7-19 and 2.0.7-29 RPMs are known to work.

If you are using Red Hat 8.0 or a new @code{glibc} 2.2.x library, you may see
@command{mysqld} die in @code{gethostbyaddr()}. This happens because the new
@code{glibc} library requires a stack size greater than 128KB for this call.
To fix the problem, start @command{mysqld} with the @code{--thread-stack=192K}
option.  (Use @code{-O thread_stack=192K} before MySQL 4.)
This stack size is now the default on MySQL 4.0.10 and above, so you should
not see the problem.

If you are using @command{gcc} 3.0 and above to compile MySQL, you must install
the @code{libstdc++v3} library before compiling MySQL; if you don't do
this, you will get an error about a missing @code{__cxa_pure_virtual}
symbol during linking.

On some older Linux distributions, @command{configure} may produce an error
like this:

@example
Syntax error in sched.h. Change _P to __P in the
/usr/include/sched.h file.
See the Installation chapter in the Reference Manual.
@end example

Just do what the error message says. Add an extra underscore to the
@code{_P} macro name that has only one underscore, then try again.

You may get some warnings when compiling. Those shown here can be ignored:

@example
mysqld.cc -o objs-thread/mysqld.o
mysqld.cc: In function `void init_signals()':
mysqld.cc:315: warning: assignment of negative value `-1' to
`long unsigned int'
mysqld.cc: In function `void * signal_hand(void *)':
mysqld.cc:346: warning: assignment of negative value `-1' to
`long unsigned int'
@end example

If @command{mysqld} always dumps core when it starts, the problem may be that
you have an old @file{/lib/libc.a}.  Try renaming it, then remove
@file{sql/mysqld} and do a new @command{make install} and try again.  This
problem has been reported on some Slackware installations.

If you get the following error when linking @command{mysqld},
it means that your @file{libg++.a} is not installed correctly:

@example
/usr/lib/libc.a(putc.o): In function `_IO_putc':
putc.o(.text+0x0): multiple definition of `_IO_putc'
@end example

You can avoid using @file{libg++.a} by running @command{configure} like this:

@example
shell> CXX=gcc ./configure
@end example

If @command{mysqld} crashes immediately and you are running Red Hat Version 5.0
with a version of @code{glibc} older than 2.0.7-5, you should make sure that
you have installed all @code{glibc} patches.  There is a lot of information
about this in the MySQL mail archives, available online at
@uref{http://lists.mysql.com/}.


@node Linux-SPARC, Linux-Alpha, Linux-x86, Linux
@subsubsection Linux SPARC Notes

In some implementations, @code{readdir_r()} is broken.  The symptom is
that the @code{SHOW DATABASES} statement always returns an empty set.
This can be fixed by removing @code{HAVE_READDIR_R} from @file{config.h}
after configuring and before compiling.

@c this patch is no longer available, and this is an ancient version of
@c Linux for the Sparc

@c Some problems will require patching your Linux installation.  The patch can
@c be found at
@c @uref{http://www.mysql.com/Downloads/patches/Linux-sparc-2.0.30.diff}.
@c This patch is against the Linux distribution @file{sparclinux-2.0.30.tar.gz}
@c that is available at @code{vger.rutgers.edu} (a version of Linux that was
@c never merged with the official 2.0.30).  You must also install LinuxThreads
@c Version 0.6 or newer.


@node Linux-Alpha, Linux-PowerPC, Linux-SPARC, Linux
@subsubsection Linux Alpha Notes

MySQL 3.23.12 is the first MySQL version that is
tested on Linux-Alpha.  If you plan to use MySQL on Linux-Alpha,
you should ensure that you have this version or newer.

We have tested MySQL on Alpha with our benchmarks and test suite,
and it appears to work nicely. 

We currently build the MySQL binary packages on SuSE Linux 7.0 for AXP,
kernel 2.4.4-SMP, Compaq C compiler (V6.2-505) and Compaq C++ compiler
(V6.3-006) on a Compaq DS20 machine with an Alpha EV6 processor.

You can find the preceding compilers at
@uref{http://www.support.compaq.com/alpha-tools/}.  By using these compilers
rather than @command{gcc}, we get about 9-14% better MySQL performance.

Note that until MySQL version 3.23.52 and 4.0.2, we optimized the binary for
the current CPU only (by using the @code{-fast} compile option). This means
that for older versions, you can use our Alpha binaries only if you have an
Alpha EV6 processor.

For all following releases, we added the @code{-arch generic} flag
to our compile options, which makes sure that the binary runs on all Alpha
processors. We also compile statically to avoid library problems.
The @command{configure} command looks like this:

@example
CC=ccc CFLAGS="-fast -arch generic" CXX=cxx \
CXXFLAGS="-fast -arch generic -noexceptions -nortti" \
./configure --prefix=/usr/local/mysql --disable-shared \
    --with-extra-charsets=complex --enable-thread-safe-client \
    --with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared
@end example

If you want to use @command{egcs}, the following @command{configure} line worked
for us:

@example
CFLAGS="-O3 -fomit-frame-pointer" CXX=gcc \
CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors \
    -fno-exceptions -fno-rtti" \
./configure --prefix=/usr/local/mysql --disable-shared
@end example

Some known problems when running MySQL on Linux-Alpha:

@itemize @bullet
@item
Debugging threaded applications like MySQL will not work with
@code{gdb 4.18}.  You should use @command{gdb} 5.1 instead.

@item
If you try linking @command{mysqld} statically when using @command{gcc}, the
resulting image will dump core at startup time.  In other words, @emph{do not}
use @code{--with-mysqld-ldflags=-all-static} with @command{gcc}.
@end itemize


@node Linux-PowerPC, Linux-MIPS, Linux-Alpha, Linux
@subsubsection Linux PowerPC Notes

MySQL should work on MkLinux with the newest @code{glibc} package
(tested with @code{glibc} 2.0.7).


@node Linux-MIPS, Linux-IA-64, Linux-PowerPC, Linux
@subsubsection Linux MIPS Notes

To get MySQL to work on Qube2 (Linux Mips), you need the
newest @code{glibc} libraries. @code{glibc-2.0.7-29C2} is known to
work.  You must also use the @command{egcs} C++ compiler
(@command{egcs} 1.0.2-9, @command{gcc} 2.95.2 or newer).


@node Linux-IA-64,  , Linux-MIPS, Linux
@subsubsection Linux IA-64 Notes

To get MySQL to compile on Linux IA-64, we use the following @command{configure}
command for building with @command{gcc} 2.96:

@example
CC=gcc \
CFLAGS="-O3 -fno-omit-frame-pointer" \
CXX=gcc \
CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors \
    -fno-exceptions -fno-rtti" \
    ./configure --prefix=/usr/local/mysql \
    "--with-comment=Official MySQL binary" \
    --with-extra-charsets=complex
@end example

On IA-64, the MySQL client binaries use shared libraries. This means
that if you install our binary distribution at a location other than
@file{/usr/local/mysql}, you need to add the path of the directory
where you have @file{libmysqlclient.so} installed either to the
@file{/etc/ld.so.conf} file or to the value of your @code{LD_LIBRARY_PATH}
environment variable.

@xref{Link errors}.


@node Mac OS X, Solaris, Linux, Operating System Specific Notes
@subsection Mac OS X Notes

On Mac OS X, @command{tar} cannot handle long filenames. If you need to unpack a
@file{.tar.gz} distribution, use @command{gnutar} instead.

@menu
* Mac OS X 10.x::               Mac OS X 10.x (Darwin)
* Mac OS X Server::             Mac OS X Server 1.2 (Rhapsody)
@end menu


@node Mac OS X 10.x, Mac OS X Server, Mac OS X, Mac OS X
@subsubsection Mac OS X 10.x (Darwin)

MySQL should work without any problems on Mac OS X 10.x 
(Darwin).

Our binary for Mac OS X is compiled on Darwin 6.3 with the following
@command{configure} line:

@example
CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc \
CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors \
    -fno-exceptions -fno-rtti" \
    ./configure --prefix=/usr/local/mysql \
    --with-extra-charsets=complex --enable-thread-safe-client \
    --enable-local-infile --disable-shared
@end example

@xref{Mac OS X installation}.

@node Mac OS X Server,  , Mac OS X 10.x, Mac OS X
@subsubsection Mac OS X Server 1.2 (Rhapsody)

For current versions of Mac OS X Server, no operating system changes are
necessary before compiling MySQL.  Compiling for the Server platform is
the same as for the client version of Mac OS X. (However, note that MySQL
comes preinstalled on Mac OS X Server, so you need not build it yourself.)

For older versions (Mac OS X Server 1.2, a.k.a. Rhapsody), you must
first install a pthread package before trying to configure MySQL.


@xref{Mac OS X installation}.


@node Solaris, BSD Notes, Mac OS X, Operating System Specific Notes
@subsection Solaris Notes

@cindex Solaris installation problems
@cindex problems, installing on Solaris
@cindex tar, problems on Solaris
@cindex errors, directory checksum
@cindex checksum errors

On Solaris, you may run into trouble even before you get the MySQL
distribution unpacked!  Solaris @command{tar} can't handle long filenames, so
you may see an error like this when you unpack MySQL:

@example
x mysql-3.22.12-beta/bench/Results/ATIS-mysql_odbc-NT_4.0-cmp-db2,
informix,ms-sql,mysql,oracle,solid,sybase, 0 bytes, 0 tape blocks
tar: directory checksum error
@end example

In this case, you must use GNU @command{tar} (@command{gtar}) to unpack the
distribution.  You can find a precompiled copy for Solaris at
@uref{http://dev.mysql.com/downloads/os-solaris.html}.

Sun native threads work only on Solaris 2.5 and higher.  For Version 2.4 and
earlier, MySQL automatically uses MIT-pthreads.
@xref{MIT-pthreads}.

If you get the following error from @command{configure},
it means that you have something wrong with your compiler installation:

@example
checking for restartable system calls... configure: error can not
run test programs while cross compiling
@end example

In this case, you should upgrade your compiler to a newer version.  You may
also be able to solve this problem by inserting the following row into the
@file{config.cache} file:

@example
ac_cv_sys_restartable_syscalls=$@{ac_cv_sys_restartable_syscalls='no'@}
@end example

If you are using Solaris on a SPARC, the recommended compiler is
@command{gcc} 2.95.2 or 3.2. You can find this at @uref{http://gcc.gnu.org/}.
Note that @command{egcs} 1.1.1 and @command{gcc} 2.8.1 don't work reliably on
SPARC!

The recommended @command{configure} line when using @command{gcc} 2.95.2 is:

@example
CC=gcc CFLAGS="-O3" \
CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti" \
./configure --prefix=/usr/local/mysql --with-low-memory \
    --enable-assembler
@end example

If you have an UltraSPARC system, you can get 4% better performance by adding
@code{-mcpu=v8 -Wa,-xarch=v8plusa} to the @code{CFLAGS} and @code{CXXFLAGS}
environment variables.

If you have Sun's Forte 5.0 (or newer) compiler, you can
run @command{configure} like this:

@example
CC=cc CFLAGS="-Xa -fast -native -xstrconst -mt" \
CXX=CC CXXFLAGS="-noex -mt" \
./configure --prefix=/usr/local/mysql --enable-assembler
@end example

To create a 64-bit binary with Sun's Forte compiler, use the
following configuration options:

@example
CC=cc CFLAGS="-Xa -fast -native -xstrconst -mt -xarch=v9" \
CXX=CC CXXFLAGS="-noex -mt -xarch=v9" ASFLAGS="-xarch=v9" \
./configure --prefix=/usr/local/mysql --enable-assembler
@end example

To create a 64-bit Solaris binary using @command{gcc}, add @code{-m64} to
@code{CFLAGS} and @code{CXXFLAGS} and remove @code{--enable-assembler} from
the @command{configure} line. This works only with MySQL
4.0 and up; MySQL 3.23 does not include the required modifications to
support this.

In the MySQL benchmarks, we got a 4% speedup on an UltraSPARC when using
Forte 5.0 in 32-bit mode compared to using @command{gcc} 3.2 with the @code{-mcpu}
flag.

If you create a 64-bit @command{mysqld} binary, it is 4% slower than the 32-bit
binary, but can handle more threads and memory.

If you get a problem with @code{fdatasync} or @code{sched_yield},
you can fix this by adding @code{LIBS=-lrt} to the @command{configure} line

For compilers older than WorkShop 5.3, you might have to edit the
@command{configure} script. Change this line:

@example
#if !defined(__STDC__) || __STDC__ != 1
@end example

To this:

@example
#if !defined(__STDC__)
@end example

If you turn on @code{__STDC__} with the @code{-Xc} option, the Sun compiler
can't compile with the Solaris @file{pthread.h} header file.  This is a Sun
bug (broken compiler or broken include file).

If @command{mysqld} issues the following error message when you run it, you have
tried to compile MySQL with the Sun compiler without enabling the @code{-mt}
multi-thread option:

@example
libc internal error: _rmutex_unlock: rmutex not held
@end example

Add @code{-mt} to @code{CFLAGS} and @code{CXXFLAGS} and recompile.

If you are using the SFW version of @command{gcc} (which comes with Solaris 8),
you must add @file{/opt/sfw/lib} to the environment variable
@code{LD_LIBRARY_PATH} before running @command{configure}.

If you are using the @command{gcc} available from @code{sunfreeware.com}, you may
have many problems.  To avoid this, you should recompile @command{gcc} and GNU
@code{binutils} on the machine where you will be running them.

If you get the following error when compiling MySQL with @command{gcc},
it means that your @command{gcc} is not configured for your version of Solaris:

@example
shell> gcc -O3 -g -O2 -DDBUG_OFF  -o thr_alarm ...
./thr_alarm.c: In function `signal_hand':
./thr_alarm.c:556: too many arguments to function `sigwait'
@end example

The proper thing to do in this case is to get the newest version of
@command{gcc} and compile it with your current @command{gcc} compiler.  At
least for Solaris 2.5, almost all binary versions of @command{gcc} have
old, unusable include files that will break all programs that use
threads, and possibly other programs!

Solaris doesn't provide static versions of all system libraries
(@code{libpthreads} and @code{libdl}), so you can't compile MySQL
with @code{--static}.  If you try to do so, you will get one of the following
errors:

@example
ld: fatal: library -ldl: not found
undefined reference to `dlopen'
cannot find -lrt
@end example

If you link your own MySQL client programs, you may see the following error at
runtime:

@example
ld.so.1: fatal: libmysqlclient.so.#:
open failed: No such file or directory
@end example

This problem can be avoided by one of the following methods:

@itemize @bullet
@item
Link clients with the @code{-Wl,r/full/path/to/libmysqlclient.so}
flag rather than with @code{-Lpath}).

@item
Copy @code{libmysqclient.so} to @file{/usr/lib}.

@tindex LD_RUN_PATH environment variable
@tindex environment variable, LD_RUN_PATH
@item
Add the pathname of the directory where @file{libmysqlclient.so} is located
to the @code{LD_RUN_PATH} environment variable before running your client.
@end itemize

If you have problems with @command{configure} trying to link with @code{-lz} when
you don't have @code{zlib} installed, you have two options:

@itemize @bullet
@item
If you want to be able to use the compressed communication protocol,
you need to get and install @code{zlib} from @code{ftp.gnu.org}.

@item
Run @command{configure} with the @code{--with-named-z-libs=no} option when
building MySQL.
@end itemize

If you are using @command{gcc} and have problems with loading user-defined
functions (UDFs) into MySQL, try adding @code{-lgcc} to the link line
for the UDF.

If you would like MySQL to start automatically, you can copy
@file{support-files/mysql.server} to @file{/etc/init.d} and create a
symbolic link to it named @file{/etc/rc3.d/S99mysql.server}.

If too many processes try to connect very rapidly to @command{mysqld}, you will
see this error in the MySQL log:

@example
Error in accept: Protocol error
@end example

You might try starting the server with the @code{--back_log=50}
option as a workaround for this.  (Use @code{-O back_log=50} before MySQL 4.)

Solaris doesn't support core files for @code{setuid()} applications, so
you can't get a core file from @command{mysqld} if you are using the
@code{--user} option.

@menu
* Solaris 2.7::                 Solaris 2.7/2.8 Notes
* Solaris x86::                 Solaris x86 Notes
@end menu


@node Solaris 2.7, Solaris x86, Solaris, Solaris
@subsubsection Solaris 2.7/2.8 Notes

Normally, you can use a Solaris 2.6 binary on Solaris 2.7 and 2.8.  Most
of the Solaris 2.6 issues also apply for Solaris 2.7 and 2.8.

MySQL 3.23.4 and above should be able to detect new versions of
Solaris automatically and enable workarounds for the following problems.

Solaris 2.7 / 2.8 has some bugs in the include files.  You may see the
following error when you use @command{gcc}:

@example
/usr/include/widec.h:42: warning: `getwc' redefined
/usr/include/wchar.h:326: warning: this is the location of the previous
definition
@end example

If this occurs, you can fix the problem by copying
@code{/usr/include/widec.h} to
@code{.../lib/gcc-lib/os/gcc-version/include} and changing line 41 from this:

@example
#if     !defined(lint) && !defined(__lint)
@end example

To this:

@example
#if     !defined(lint) && !defined(__lint) && !defined(getwc)
@end example

Alternatively, you can edit @file{/usr/include/widec.h} directly.  Either
way, after you make the fix, you should remove @file{config.cache} and run
@command{configure} again.

If you get the following errors when you run @command{make}, it's because
@command{configure} didn't detect the @file{curses.h} file (probably
because of the error in @file{/usr/include/widec.h}):

@example
In file included from mysql.cc:50:
/usr/include/term.h:1060: syntax error before `,'
/usr/include/term.h:1081: syntax error before `;'
@end example

The solution to this problem is to do one of the following:

@itemize @bullet
@item
Configure with @code{CFLAGS=-DHAVE_CURSES_H CXXFLAGS=-DHAVE_CURSES_H ./configure}.

@item
Edit @file{/usr/include/widec.h} as indicated in the preceding discussion
and re-run @command{configure}.

@item
Remove the @code{#define HAVE_TERM} line from the @file{config.h} file and
run @command{make} again.
@end itemize

If your linker can't find @code{-lz} when linking
client programs, the problem is probably that your @file{libz.so} file is
installed in @file{/usr/local/lib}.  You can fix this problem by one of the
following methods:

@itemize @bullet
@item
Add @file{/usr/local/lib} to @code{LD_LIBRARY_PATH}.

@item
Add a link to @file{libz.so} from @file{/lib}.

@item
If you are using Solaris 8, you can install the optional @code{zlib} from your
Solaris 8 CD distribution.

@item
Run @command{configure} with the @code{--with-named-z-libs=no} option when
building MySQL.
@end itemize


@node Solaris x86,  , Solaris 2.7, Solaris
@subsubsection Solaris x86 Notes

On Solaris 8 on x86, @command{mysqld} will dump core if you remove the
debug symbols using @code{strip}.

If you are using @command{gcc} or @command{egcs} on Solaris x86 and you
experience problems with core dumps under load, you should use the
following @command{configure} command:

@example
CC=gcc CFLAGS="-O3 -fomit-frame-pointer -DHAVE_CURSES_H" \
CXX=gcc \
CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors \
    -fno-exceptions -fno-rtti -DHAVE_CURSES_H" \
./configure --prefix=/usr/local/mysql
@end example

This will avoid problems with the @code{libstdc++} library and with C++
exceptions.

If this doesn't help, you should compile a debug version and run
it with a trace file or under @command{gdb}.
@xref{Using gdb on mysqld,  , Using @command{gdb} on @command{mysqld}}.


@node BSD Notes, Other Unix Notes, Solaris, Operating System Specific Notes
@subsection BSD Notes

This section provides information about using MySQL on variants of BSD Unix.

@menu
* FreeBSD::                     FreeBSD Notes
* NetBSD::                      NetBSD Notes
* OpenBSD::                     OpenBSD 2.5 Notes
* OpenBSD 2.8::                 OpenBSD 2.8 Notes
* BSDI::                        BSD/OS Version 2.x Notes
* BSDI3::                       BSD/OS Version 3.x Notes
* BSDI4::                       BSD/OS Version 4.x Notes
@end menu


@node FreeBSD, NetBSD, BSD Notes, BSD Notes
@subsubsection FreeBSD Notes

FreeBSD 4.x or newer is recommended for running MySQL, because the thread
package is much more integrated.
To get a secure and stable system, you should use only FreeBSD kernels
that are marked @code{-RELEASE}.

The easiest (and preferred) way to install MySQL is to use the
@command{mysql-server} and @code{mysql-client} ports available at
@uref{http://www.freebsd.org/}.
Using these ports gives you the following benefits:

@itemize @bullet
@item
A working MySQL with all optimizations enabled that are known to work on your
version of FreeBSD.

@item
Automatic configuration and build.

@item
Startup scripts installed in @file{/usr/local/etc/rc.d}.

@item
The ability to use @code{pkg_info -L} to see which files are installed.

@item
The ability to use @code{pkg_delete} to remove MySQL if you no longer want it
on your machine.
@end itemize

It is recommended you use MIT-pthreads on FreeBSD 2.x, and native threads on
Versions 3 and up. It is possible to run with native threads on some late
2.2.x versions, but you may encounter problems shutting down @command{mysqld}.

Unfortunately, certain function calls on FreeBSD are not yet fully thread-safe.
Most notably, this includes the @code{gethostbyname()} function, which is
used by MySQL to convert hostnames into IP addresses. Under certain
circumstances, the @command{mysqld} process will suddenly cause 100%
CPU load and will be unresponsive. If you encounter this problem, try to start
MySQL using the @code{--skip-name-resolve} option.

Alternatively, you can link MySQL on FreeBSD 4.x against the LinuxThreads
library, which avoids a few of the problems that the native FreeBSD thread
implementation has. For a very good comparison of LinuxThreads versus native
threads, see Jeremy Zawodny's article @cite{FreeBSD or Linux for your
MySQL Server?} at
@uref{http://jeremy.zawodny.com/blog/archives/000697.html}.

A known problem when using LinuxThreads on FreeBSD is that the
@code{wait_timeout} value is not honored (probably a signal handling problem in
FreeBSD/LinuxThreads).  This is supposed to be fixed in FreeBSD 5.0.
The symptom is that persistent connections can hang for a very long
time without getting closed down.

The MySQL build process requires GNU make (@command{gmake}) to work.  If
GNU @command{make} is not available, you must install it first before compiling
MySQL.

The recommended way to compile and install MySQL on FreeBSD with
@command{gcc} (2.95.2 and up) is:

@example
CC=gcc CFLAGS="-O2 -fno-strength-reduce" \
    CXX=gcc CXXFLAGS="-O2 -fno-rtti -fno-exceptions \
    -felide-constructors -fno-strength-reduce" \
    ./configure --prefix=/usr/local/mysql --enable-assembler
gmake
gmake install
cd /usr/local/mysql
bin/mysql_install_db --user=mysql
bin/mysqld_safe &
@end example

If you notice that @command{configure} will use MIT-pthreads, you should read
the MIT-pthreads notes.  @xref{MIT-pthreads}.

If you get an error from @command{make install} that it can't find
@file{/usr/include/pthreads}, @command{configure} didn't detect that you need
MIT-pthreads. To fix this problem, remove @file{config.cache}, then re-run
@command{configure} with the @code{--with-mit-threads} option.

@c TODO: This is not really FreeBSD-specific. Move to general
@c troublshooting section.

Be sure that your name resolver setup is correct.  Otherwise, you may
experience resolver delays or failures when connecting to @command{mysqld}.
Also make sure that the @code{localhost} entry in the @file{/etc/hosts} file is
correct.  The file should start with a line similar to this:

@example
127.0.0.1       localhost localhost.your.domain
@end example

FreeBSD is known to have a very low default file handle limit.
@xref{Not enough file handles}.  Start the server by using the
@code{--open-files-limit} option for @command{mysqld_safe}, or raise
the limits for the @command{mysqld} user in @file{/etc/login.conf} and
rebuild it with @code{cap_mkdb /etc/login.conf}.  Also be sure that you set
the appropriate class for this user in the password file if you are not
using the default (use @code{chpass mysqld-user-name}).
@xref{mysqld_safe,  , @command{mysqld_safe}}.

If you have a lot of memory, you should consider rebuilding
the kernel to allow MySQL to use more than 512MB of RAM.
Take a look at @code{option MAXDSIZ} in the LINT config
file for more information.

If you get problems with the current date in MySQL, setting the
@code{TZ} variable will probably help.  @xref{Environment variables}.


@node NetBSD, OpenBSD, FreeBSD, BSD Notes
@subsubsection NetBSD Notes

To compile on NetBSD, you need GNU @command{make}. Otherwise, the build process will
fail when @command{make} tries to run @code{lint} on C++ files.


@node OpenBSD, OpenBSD 2.8, NetBSD, BSD Notes
@subsubsection OpenBSD 2.5 Notes

On OpenBSD Version 2.5, you can compile MySQL with native threads
with the following options:

@example
CFLAGS=-pthread CXXFLAGS=-pthread ./configure --with-mit-threads=no
@end example


@node OpenBSD 2.8, BSDI, OpenBSD, BSD Notes
@subsubsection OpenBSD 2.8 Notes

Our users have reported that OpenBSD 2.8 has a threading bug that causes
problems with MySQL.  The OpenBSD Developers have fixed the problem,
but as of January 25, 2001, it's only available in the ``-current'' branch.
The symptoms of this threading bug are slow response, high load, high CPU
usage, and crashes.

If you get an error like @code{Error in accept:: Bad file descriptor} or
error 9 when trying to open tables or directories, the problem is probably
that you have not allocated enough file descriptors for MySQL.

In this case, try starting @command{mysqld_safe} as @code{root} with the following
options:

@example
mysqld_safe --user=mysql --open-files-limit=2048 &
@end example

@node BSDI, BSDI3, OpenBSD 2.8, BSD Notes
@subsubsection BSD/OS Version 2.x Notes

If you get the following error when compiling MySQL, your
@command{ulimit} value for virtual memory is too low:

@example
item_func.h: In method
`Item_func_ge::Item_func_ge(const Item_func_ge &)':
item_func.h:28: virtual memory exhausted
make[2]: *** [item_func.o] Error 1
@end example

Try using @command{ulimit -v 80000} and run @command{make} again.  If this
doesn't work and you are using @command{bash}, try switching to @command{csh}
or @command{sh}; some BSDI users have reported problems with @command{bash}
and @command{ulimit}.

If you are using @command{gcc}, you may also use have to use the
@code{--with-low-memory} flag for @command{configure} to be able to compile
@file{sql_yacc.cc}.

If you get problems with the current date in MySQL, setting the
@code{TZ} variable will probably help.  @xref{Environment variables}.


@node BSDI3, BSDI4, BSDI, BSD Notes
@subsubsection BSD/OS Version 3.x Notes

Upgrade to BSD/OS Version 3.1.  If that is not possible, install
BSDIpatch M300-038.

Use the following command when configuring MySQL:

@example
env CXX=shlicc++ CC=shlicc2 \
./configure \
    --prefix=/usr/local/mysql \
    --localstatedir=/var/mysql \
    --without-perl \
    --with-unix-socket-path=/var/mysql/mysql.sock
@end example

The following is also known to work:

@example
env CC=gcc CXX=gcc CXXFLAGS=-O3 \
./configure \
    --prefix=/usr/local/mysql \
    --with-unix-socket-path=/var/mysql/mysql.sock
@end example

You can change the directory locations if you wish, or just use the
defaults by not specifying any locations.

If you have problems with performance under heavy load, try using the
@code{--skip-thread-priority} option to @command{mysqld}!  This will run
all threads with the same priority. On BSDI Version 3.1, this gives better
performance, at least until BSDI fixes its thread scheduler.

If you get the error @code{virtual memory exhausted} while compiling,
you should try using @command{ulimit -v 80000} and running @command{make} again.
If this doesn't work and you are using @command{bash}, try switching to
@command{csh} or @command{sh}; some BSDI users have reported problems with
@command{bash} and @command{ulimit}.


@node BSDI4,  , BSDI3, BSD Notes
@subsubsection BSD/OS Version 4.x Notes

BSDI Version 4.x has some thread-related bugs.  If you want to use
MySQL on this, you should install all thread-related patches.  At
least M400-023 should be installed.

On some BSDI Version 4.x systems, you may get problems with shared libraries.
The symptom is that you can't execute any client programs, for example,
@command{mysqladmin}.  In this case, you need to reconfigure not to use
shared libraries with the @code{--disable-shared} option to configure.

Some customers have had problems on BSDI 4.0.1 that the @command{mysqld}
binary after a while can't open tables.  This is because some
library/system-related bug causes @command{mysqld} to change current
directory without having asked for that to happen.

The fix is to either upgrade MySQL to at least version 3.23.34 or, after
running @command{configure}, remove the line @code{#define HAVE_REALPATH} from
@code{config.h} before running @command{make}.

Note that this means that you can't symbolically link a database
directories to another database directory or symbolic link a table to
another database on BSDI.  (Making a symbolic link to another disk is okay).


@node Other Unix Notes, OS/2, BSD Notes, Operating System Specific Notes
@subsection Other Unix Notes

@menu
* HP-UX 10.20::                 HP-UX Version 10.20 Notes
* HP-UX 11.x::                  HP-UX Version 11.x Notes
* IBM-AIX::                     IBM-AIX notes
* SunOS::                       SunOS 4 Notes
* Alpha-DEC-UNIX::              Alpha-DEC-UNIX Notes (Tru64)
* Alpha-DEC-OSF1::              Alpha-DEC-OSF/1 Notes
* SGI-Irix::                    SGI Irix Notes
* SCO::                         SCO Notes
* SCO UnixWare::                SCO UnixWare Version 7.1.x Notes
@end menu

@c TODO: perhaps subsume the next two nodes under an HP-UX @subsection
@c (like the Mac OS X notes @subsubsections), and move it to before
@c "Other Unix Notes".

@node HP-UX 10.20, HP-UX 11.x, Other Unix Notes, Other Unix Notes
@subsubsection HP-UX Version 10.20 Notes

There are a couple of small problems when compiling MySQL on
HP-UX.  We recommend that you use @command{gcc} instead of the HP-UX native
compiler, because @command{gcc} produces better code.

We recommend using @command{gcc} 2.95 on HP-UX.  Don't use high optimization
flags (such as @code{-O6}) because they may not be safe on HP-UX.

The following @command{configure} line should work with @command{gcc} 2.95:

@example
CFLAGS="-I/opt/dce/include -fpic" \
CXXFLAGS="-I/opt/dce/include -felide-constructors -fno-exceptions \
-fno-rtti" \
CXX=gcc \
./configure --with-pthread \
    --with-named-thread-libs='-ldce' \
    --prefix=/usr/local/mysql --disable-shared
@end example

The following @command{configure} line should work with @command{gcc} 3.1:

@example
CFLAGS="-DHPUX -I/opt/dce/include -O3 -fPIC" CXX=gcc \
CXXFLAGS="-DHPUX -I/opt/dce/include -felide-constructors \
    -fno-exceptions -fno-rtti -O3 -fPIC" \
./configure --prefix=/usr/local/mysql \
    --with-extra-charsets=complex --enable-thread-safe-client \
    --enable-local-infile  --with-pthread \
    --with-named-thread-libs=-ldce --with-lib-ccflags=-fPIC
    --disable-shared
@end example

@node HP-UX 11.x, IBM-AIX, HP-UX 10.20, Other Unix Notes
@subsubsection HP-UX Version 11.x Notes

For HP-UX Version 11.x, we recommend MySQL 3.23.15 or later.

Because of some critical bugs in the standard HP-UX libraries, you should
install the following patches before trying to run MySQL on HP-UX 11.0:

@example
PHKL_22840 Streams cumulative
PHNE_22397 ARPA cumulative
@end example

This will solve the problem of getting @code{EWOULDBLOCK} from @code{recv()}
and @code{EBADF} from @code{accept()} in threaded applications.

If you are using @command{gcc} 2.95.1 on an unpatched HP-UX 11.x system,
you will get the error:

@example
In file included from /usr/include/unistd.h:11,
                 from ../include/global.h:125,
                 from mysql_priv.h:15,
                 from item.cc:19:
/usr/include/sys/unistd.h:184: declaration of C function ...
/usr/include/sys/pthread.h:440: previous declaration ...
In file included from item.h:306,
                 from mysql_priv.h:158,
                 from item.cc:19:
@end example

The problem is that HP-UX doesn't define @code{pthreads_atfork()} consistently.
It has conflicting prototypes in
@file{/usr/include/sys/unistd.h}:184 and
@file{/usr/include/sys/pthread.h}:440.

One solution is to copy @file{/usr/include/sys/unistd.h} into
@file{mysql/include} and edit @file{unistd.h} and change it to match
the definition in @file{pthread.h}.  Look for this line:

@example
extern int pthread_atfork(void (*prepare)(), void (*parent)(),
                                          void (*child)());
@end example

Change it to look like this:

@example
extern int pthread_atfork(void (*prepare)(void), void (*parent)(void),
                                          void (*child)(void));
@end example

After making the change, the following @command{configure} line should work:

@example
CFLAGS="-fomit-frame-pointer -O3 -fpic" CXX=gcc \
CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti -O3" \
./configure --prefix=/usr/local/mysql --disable-shared
@end example

If you are using MySQL 4.0.5 with the HP-UX compiler, you can use the following
command (which has been tested with @command{cc} B.11.11.04):

@example
CC=cc CXX=aCC CFLAGS=+DD64 CXXFLAGS=+DD64 ./configure \
    --with-extra-character-set=complex
@end example

You can ignore any errors of the following type:

@example
aCC: warning 901: unknown option: `-3': use +help for online
documentation
@end example

If you get the following error from @command{configure},
verify that you don't have the path to the K&R compiler before the path
to the HP-UX C and C++ compiler:

@example
checking for cc option to accept ANSI C... no
configure: error: MySQL requires an ANSI C compiler (and a C++ compiler).
Try gcc. See the Installation chapter in the Reference Manual.
@end example

Another reason for not being able to compile is that you didn't define
the @code{+DD64} flags as just described.

Another possibility for HP-UX 11 is to use MySQL binaries for HP-UX 10.20.
We have received reports from some users that these binaries work fine on
HP-UX 11.00. If you encounter problems, be sure to check your HP-UX patch
level.

@node IBM-AIX, SunOS, HP-UX 11.x, Other Unix Notes
@subsubsection IBM-AIX notes

@cindex problems, installing on IBM-AIX

Automatic detection of @code{xlC} is missing from Autoconf, so a number of
variables need to be set before running @command{configure}. The following
example uses the IBM compiler:

@example
export CC="xlc_r -ma -O3 -qstrict -qoptimize=3 -qmaxmem=8192 "
export CXX="xlC_r -ma -O3 -qstrict -qoptimize=3 -qmaxmem=8192"
export CFLAGS="-I /usr/local/include"
export LDFLAGS="-L /usr/local/lib"
export CPPFLAGS=$CFLAGS
export CXXFLAGS=$CFLAGS

./configure --prefix=/usr/local \
                --localstatedir=/var/mysql \
                --sbindir='/usr/local/bin' \
                --libexecdir='/usr/local/bin' \
                --enable-thread-safe-client \
                --enable-large-files
@end example

The preceding options are used to compile the MySQL distribution that
can be found at @uref{http://www-frec.bull.com/}.

If you change the @code{-O3} to @code{-O2} in the preceding @command{configure}
line, you must also remove the @code{-qstrict} option. This is a limitation in
the IBM C compiler.

If you are using @command{gcc} or @command{egcs} to compile MySQL, you
@emph{must} use the @code{-fno-exceptions} flag, because the exception
handling in @command{gcc}/@command{egcs} is not thread-safe!  (This is tested with
@command{egcs} 1.1.)  There are also some known problems with IBM's assembler
that may cause it to generate bad code when used with @command{gcc}.

We recommend the following @command{configure} line with @command{egcs} and
@command{gcc} 2.95 on AIX:

@example
CC="gcc -pipe -mcpu=power -Wa,-many" \
CXX="gcc -pipe -mcpu=power -Wa,-many" \
CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti" \
./configure --prefix=/usr/local/mysql --with-low-memory
@end example

The @code{-Wa,-many} option is necessary for the compile to be successful.
IBM is aware of this problem but is in no hurry to fix it because of the
workaround that is available.  We don't know if the @code{-fno-exceptions}
is required with @command{gcc} 2.95, but because MySQL doesn't use exceptions
and the option generates faster code, we recommend that you should always
use it with @command{egcs} / @command{gcc}.

If you get a problem with assembler code, try changing the @code{-mcpu=@var{xxx}}
option to match your CPU. Typically @code{power2}, @code{power}, or
@code{powerpc} may need to be used.  Alternatively, you might need to use
@code{604} or @code{604e}. We are not positive but suspect that
@code{power} would likely be safe most of the time, even on
a power2 machine.

If you don't know what your CPU is, execute a @code{uname -m} command.  It
will produce a string that looks like @code{000514676700}, with a format of
@code{xxyyyyyymmss} where @code{xx} and @code{ss} are always @code{00},
@code{yyyyyy} is a unique system ID and @code{mm} is the ID of the CPU Planar.
A chart of these values can be found at
@uref{http://www16.boulder.ibm.com/pseries/en_US/cmds/aixcmds5/uname.htm}.
@c older URL...
@c @uref{http://publib.boulder.ibm.com/doc_link/en_US/a_doc_lib/cmds/aixcmds5/uname.htm}.
This will give you a machine type and a machine model you can use to
determine what type of CPU you have.

If you have problems with signals (MySQL dies unexpectedly
under high load), you may have found an OS bug with threads and
signals.  In this case, you can tell MySQL not to use signals by
configuring as follows:

@example
CFLAGS=-DDONT_USE_THR_ALARM CXX=gcc \
CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti \
-DDONT_USE_THR_ALARM" \
./configure --prefix=/usr/local/mysql --with-debug \
    --with-low-memory
@end example

This doesn't affect the performance of MySQL, but has the side
effect that you can't kill clients that are ``sleeping'' on a connection with
@command{mysqladmin kill} or @command{mysqladmin shutdown}.  Instead, the client
will die when it issues its next command.

On some versions of AIX, linking with @code{libbind.a} makes
@code{getservbyname()} dump core.  This is an AIX bug and should be reported
to IBM.

For AIX 4.2.1 and @command{gcc}, you have to make the following changes.

After configuring, edit @file{config.h} and @file{include/my_config.h}
and change the line that says this:

@example
#define HAVE_SNPRINTF 1
@end example

to this:

@example
#undef HAVE_SNPRINTF
@end example

And finally, in @file{mysqld.cc}, you need to add a prototype for
@code{initgroups()}.

@example
#ifdef _AIX41
extern "C" int initgroups(const char *,int);
#endif
@end example

If you need to allocate a lot of memory to the @command{mysqld} process, it's not
enough to just use @command{ulimit -d unlimited}. You may also have to modify
@command{mysqld_safe} to add a line something like this:

@example
export LDR_CNTRL='MAXDATA=0x80000000'
@end example

You can find more information about using a lot of memory at
@uref{http://publib16.boulder.ibm.com/pseries/en_US/aixprggd/genprogc/lrg_prg_support.htm}.

@node SunOS, Alpha-DEC-UNIX, IBM-AIX, Other Unix Notes
@subsubsection SunOS 4 Notes

On SunOS 4, MIT-pthreads is needed to compile MySQL. This in turn
means you will need GNU @command{make}.

Some SunOS 4 systems have problems with dynamic libraries and @command{libtool}.
You can use the following @command{configure} line to avoid this problem:

@example
./configure --disable-shared --with-mysqld-ldflags=-all-static
@end example

When compiling @code{readline}, you may get warnings about duplicate defines.
These can be ignored.

When compiling @command{mysqld}, there will be some @code{implicit declaration
of function} warnings. These can be ignored.


@node Alpha-DEC-UNIX, Alpha-DEC-OSF1, SunOS, Other Unix Notes
@subsubsection Alpha-DEC-UNIX Notes (Tru64)

If you are using @command{egcs} 1.1.2 on Digital Unix, you should upgrade to
@command{gcc} 2.95.2, because @command{egcs} on DEC has some serious bugs!

When compiling threaded programs under Digital Unix, the documentation
recommends using the @code{-pthread} option for @command{cc} and @command{cxx} and
the @code{-lmach -lexc} libraries (in addition to @code{-lpthread}).  You
should run @command{configure} something like this:

@example
CC="cc -pthread" CXX="cxx -pthread -O" \
./configure --with-named-thread-libs="-lpthread -lmach -lexc -lc"
@end example

When compiling @command{mysqld}, you may see a couple of warnings like this:

@example
mysqld.cc: In function void handle_connections()':
mysqld.cc:626: passing long unsigned int *' as argument 3 of
accept(int,sockadddr *, int *)'
@end example

You can safely ignore these warnings.  They occur because @command{configure}
can detect only errors, not warnings.

If you start the server directly from the command line, you may have problems
with it dying when you log out.  (When you log out, your outstanding processes
receive a @code{SIGHUP} signal.)  If so, try starting the server like this:

@example
nohup mysqld [@var{options}] &
@end example

@code{nohup} causes the command following it to ignore any @code{SIGHUP}
signal sent from the terminal.  Alternatively, start the server by running
@command{mysqld_safe}, which invokes @command{mysqld} using @command{nohup} for you.
@xref{mysqld_safe, , @command{mysqld_safe}}.

If you get a problem when compiling @file{mysys/get_opt.c}, just remove the
@code{#define _NO_PROTO} line from the start of that file.

If you are using Compaq's CC compiler, the following @command{configure} line
should work:

@example
CC="cc -pthread"
CFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed all -arch host"
CXX="cxx -pthread"
CXXFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed all \
    -arch host -noexceptions -nortti"
export CC CFLAGS CXX CXXFLAGS
./configure \
    --prefix=/usr/local/mysql \
    --with-low-memory \
    --enable-large-files \
    --enable-shared=yes \
    --with-named-thread-libs="-lpthread -lmach -lexc -lc"
gnumake
@end example

If you get a problem with @command{libtool} when compiling with shared libraries
as just shown, when linking @command{mysql}, you should be able to get around
this by issuing these commands:

@example
cd mysql
/bin/sh ../libtool --mode=link cxx -pthread  -O3 -DDBUG_OFF \
    -O4 -ansi_alias -ansi_args -fast -inline speed \
    -speculate all \ -arch host  -DUNDEF_HAVE_GETHOSTBYNAME_R \
    -o mysql  mysql.o readline.o sql_string.o completion_hash.o \
    ../readline/libreadline.a -lcurses \
    ../libmysql/.libs/libmysqlclient.so  -lm
cd ..
gnumake
gnumake install
scripts/mysql_install_db
@end example


@node Alpha-DEC-OSF1, SGI-Irix, Alpha-DEC-UNIX, Other Unix Notes
@subsubsection Alpha-DEC-OSF/1 Notes

If you have problems compiling and have DEC @command{CC} and @command{gcc}
installed, try running @command{configure} like this:

@example
CC=cc CFLAGS=-O CXX=gcc CXXFLAGS=-O3 \
./configure --prefix=/usr/local/mysql
@end example

If you get problems with the @file{c_asm.h} file, you can create and use
a 'dummy' @file{c_asm.h} file with:

@example
touch include/c_asm.h
CC=gcc CFLAGS=-I./include \
CXX=gcc CXXFLAGS=-O3 \
./configure --prefix=/usr/local/mysql
@end example

Note that the following problems with the @code{ld} program can be fixed
by downloading the latest DEC (Compaq) patch kit from:
@uref{http://ftp.support.compaq.com/public/unix/}.

On OSF/1 V4.0D and compiler "DEC C V5.6-071 on Digital Unix V4.0 (Rev. 878),"
the compiler had some strange behavior (undefined @code{asm} symbols).
@code{/bin/ld} also appears to be broken (problems with @code{_exit
undefined} errors occurring while linking @command{mysqld}).  On this system, we
have managed to compile MySQL with the following @command{configure}
line, after replacing @code{/bin/ld} with the version from OSF 4.0C:

@example
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
@end example

With the Digital compiler "C++ V6.1-029," the following should work:

@example
CC=cc -pthread
CFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed \
       -speculate all -arch host
CXX=cxx -pthread
CXXFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed \
         -speculate all -arch host -noexceptions -nortti
export CC CFLAGS CXX CXXFLAGS
./configure --prefix=/usr/mysql/mysql \
            --with-mysqld-ldflags=-all-static --disable-shared \
            --with-named-thread-libs="-lmach -lexc -lc"
@end example

In some versions of OSF/1, the @code{alloca()} function is broken. Fix
this by removing the line in @file{config.h} that defines @code{'HAVE_ALLOCA'}.

The @code{alloca()} function also may have an incorrect prototype in
@code{/usr/include/alloca.h}.  This warning resulting from this can be ignored.

@command{configure} will use the following thread libraries automatically:
@code{--with-named-thread-libs="-lpthread -lmach -lexc -lc"}.

When using @command{gcc}, you can also try running @command{configure} like this:

@example
CFLAGS=-D_PTHREAD_USE_D4 CXX=gcc CXXFLAGS=-O3 ./configure ...
@end example

If you have problems with signals (MySQL dies unexpectedly
under high load), you may have found an OS bug with threads and
signals. In this case, you can tell MySQL not to use signals by
configuring with:

@example
CFLAGS=-DDONT_USE_THR_ALARM \
CXXFLAGS=-DDONT_USE_THR_ALARM \
./configure ...
@end example

This doesn't affect the performance of MySQL, but has the side
effect that you can't kill clients that are ``sleeping'' on a connection with
@command{mysqladmin kill} or @command{mysqladmin shutdown}.  Instead, the client
will die when it issues its next command.

With @command{gcc} 2.95.2, you will probably run into the following compile error:

@example
sql_acl.cc:1456: Internal compiler error in `scan_region',
at except.c:2566
Please submit a full bug report.
@end example

To fix this, you should change to the @code{sql} directory and do a
cut-and-paste of the last @command{gcc} line, but change @code{-O3} to
@code{-O0} (or add @code{-O0} immediately after @command{gcc} if you don't
have any @code{-O} option on your compile line).  After this is done, you
can just change back to the top-level directory and run @command{make}
again.


@node SGI-Irix, SCO, Alpha-DEC-OSF1, Other Unix Notes
@subsubsection SGI Irix Notes

If you are using Irix Version 6.5.3 or newer, @command{mysqld} will be able to
create threads only if you run it as a user that has @code{CAP_SCHED_MGT}
privileges (such as @code{root}) or give the @command{mysqld} server this privilege
with the following shell command:

@example
chcap "CAP_SCHED_MGT+epi" /opt/mysql/libexec/mysqld
@end example

You may have to undefine some symbols in @file{config.h} after running
@command{configure} and before compiling.

In some Irix implementations, the @code{alloca()} function is broken.  If the
@command{mysqld} server dies on some @code{SELECT} statements, remove the lines
from @file{config.h} that define @code{HAVE_ALLOC} and @code{HAVE_ALLOCA_H}.
If @command{mysqladmin create} doesn't work, remove the line from @file{config.h}
that defines @code{HAVE_READDIR_R}.  You may have to remove the
@code{HAVE_TERM_H} line as well.

SGI recommends that you install all the patches on this page as a set:
@uref{http://support.sgi.com/surfzone/patches/patchset/6.2_indigo.rps.html}

At the very minimum, you should install the latest kernel rollup, the
latest @code{rld} rollup, and the latest @code{libc} rollup.

You definitely need all the POSIX patches on this page, for pthreads support:

@uref{http://support.sgi.com/surfzone/patches/patchset/6.2_posix.rps.html}

If you get the something like the following error when compiling
@file{mysql.cc}:

@example
"/usr/include/curses.h", line 82: error(1084):
invalid combination of type
@end example

Type the following in the top-level directory of your MySQL source
tree:

@example
extra/replace bool curses_bool < /usr/include/curses.h > include/curses.h
make
@end example

There have also been reports of scheduling problems.  If only one thread is
running, performance is slow.  Avoid this by starting another client.  This may
lead to a two-to-tenfold increase in execution speed thereafter for the other
thread.  This is a poorly understood problem with Irix threads; you may have
to improvise to find solutions until this can be fixed.

If you are compiling with @command{gcc}, you can use the following
@command{configure} command:

@example
CC=gcc CXX=gcc CXXFLAGS=-O3 \
./configure --prefix=/usr/local/mysql --enable-thread-safe-client \
    --with-named-thread-libs=-lpthread
@end example

On Irix 6.5.11 with native Irix C and C++ compilers ver. 7.3.1.2, the
following is reported to work

@example
CC=cc CXX=CC CFLAGS='-O3 -n32 -TARG:platform=IP22 -I/usr/local/include \
-L/usr/local/lib' CXXFLAGS='-O3 -n32 -TARG:platform=IP22 \
-I/usr/local/include -L/usr/local/lib' \
./configure --prefix=/usr/local/mysql --with-innodb --with-berkeley-db \
    --with-libwrap=/usr/local \
    --with-named-curses-libs=/usr/local/lib/libncurses.a
@end example


@node SCO, SCO UnixWare, SGI-Irix, Other Unix Notes
@subsubsection SCO Notes

The current port is tested only on ``sco3.2v5.0.5,'' ``sco3.2v5.0.6,'' 
and ``sco3.2v5.0.7'' systems. There has also been a lot of progress on a 
port to ``sco 3.2v4.2.''  Open Server 5.0.8(Legend) will have native 
threads and allow files greater than 2GB.  The current maximum file size 
is 2GB.

We have been able to compile MySQL with the following @command{configure}
command on on OpenServer with @command{gcc} 2.95.3.

@example
CC=gcc CXX=gcc ./configure --prefix=/usr/local/mysql \
    --enable-thread-safe-client --with-innodb \
    --with-openssl --with-vio --with-extra-charsets=complex
@end example

@command{gcc} is available at
@uref{ftp://ftp.sco.com/pub/openserver5/opensrc/gnutools-5.0.7Kj}.

This development system requires the OpenServer Execution 
Enviroment Supplement oss646B on OpenServer 5.0.6 and oss656B
and The OpenSource libraries found in gwxlibs.  All OpenSource tools are 
in the @file{opensrc} directory.  They are available at
@uref{ftp://ftp.sco.com/pub/openserver5/opensrc/}.

We recommend using the latest production release of MySQL.  Currently
MySQL-4.0.x is the latest production release.  There were some problems
with MySQL 4.0.17 and MySQL 4.0.18, but they have now been fixed.

SCO provides operating system patches at 
@uref{ftp://ftp.sco.com/pub/openserver5} for OpenServer 5.0.[0-6] and
@uref{ftp://ftp.sco.com/pub/openserverv5/507} for OpenServer 5.0.7.

SCO provides information about security fixes at 
@uref{ftp://ftp.sco.com/pub/security/OpenServer} for OpenServer 5.0.x.

The maximum file size on an OpenSever 5.0.x system is 2GB.

The total memory which could be allocated for streams buffers, clists and 
lock records cannot exceed 60MB on OpenServer 5.0.x.

Streams buffers are allocated in units of 4096 byte pages, clists are 70 
bytes each, and lock records are 64 bytes each, so:

@example
(NSTRPAGES * 4096) + (NCLIST * 70) + (MAX_FLCKREC * 64) <= 62914560 
@end example

Follow this procedure to configure the Database Services option. If you 
are unsure whether an application requires this, see the documentation 
provided with the application.

@enumerate
@item
Log in as @code{root}.

@item
Enable the SUDS driver by editing the @file{/etc/conf/sdevice.d/suds} file. 
Change the @code{N} in the second field to a @code{Y}.

@item
Use @code{mkdev aio} or the Hardware/Kernel Manager to enable support for 
asynchronous I/O and relink the kernel. To allow users to lock down memory 
for use with this type of I/O, update the aiomemlock(F) file. This file 
should be updated to include the names of users that can use AIO and the 
maximum amounts of memory they can lock down.

@item
Many applications use setuid binaries so that you need to specify only a
single user. See the documentation provided with the application to see if
this is the case for your application.
@end enumerate

After you complete this process, reboot the system to create a new kernel 
incorporating these changes.

By default, the entries in @file{/etc/conf/cf.d/mtune} are set as follows:

@example
Value           Default         Min             Max
-----           -------         ---             ---
NBUF            0               24              450000
NHBUF           0               32              524288
NMPBUF          0               12              512
MAX_INODE       0               100             64000
MAX_FILE        0               100             64000
CTBUFSIZE       128             0               256
MAX_PROC        0               50              16000
MAX_REGION      0               500             160000
NCLIST          170             120             16640
MAXUP           100             15              16000
NOFILES         110             60              11000
NHINODE         128             64              8192
NAUTOUP         10              0               60
NGROUPS         8               0               128
BDFLUSHR        30              1               300
MAX_FLCKREC     0               50              16000
PUTBUFSZ        8000            2000            20000
MAXSLICE        100             25              100
ULIMIT          4194303         2048            4194303
* Streams Parameters
NSTREAM         64              1               32768
NSTRPUSH        9               9               9
NMUXLINK        192             1               4096
STRMSGSZ        16384           4096            524288
STRCTLSZ        1024            1024            1024
STRMAXBLK       524288          4096            524288
NSTRPAGES       500             0               8000
STRSPLITFRAC    80              50              100
NLOG            3               3               3
NUMSP           64              1               256
NUMTIM          16              1               8192
NUMTRW          16              1               8192
* Semaphore Parameters
SEMMAP          10              10              8192
SEMMNI          10              10              8192
SEMMNS          60              60              8192
SEMMNU          30              10              8192
SEMMSL          25              25              150
SEMOPM          10              10              1024
SEMUME          10              10              25
SEMVMX          32767           32767           32767
SEMAEM          16384           16384           16384
* Shared Memory Parameters
SHMMAX          524288          131072          2147483647
SHMMIN          1               1               1
SHMMNI          100             100             2000
FILE            0               100             64000
NMOUNT          0               4               256
NPROC           0               50              16000
NREGION         0               500             160000
@end example

We recommend setting these values as follows:

@code{NOFILES} should be 4096 or 2048.

@code{MAXUP} should be 2048.

To make changes to the kernel, @code{cd} to @file{/etc/conf/bin} and
use @command{./idtune} @var{name parameter} to make the changes. For example,
to change @code{SEMMS} to @code{200}, execute these commands as @code{root}:

@example
# cd /etc/conf/bin
# ./idtune SEMMNS 200
@end example

We recommend tuning the system, but the proper parameter values to use
depend on the number of users accessing the application or database
and size the of the database (that is, the used buffer pool). The
following will affect the following kernel parameters defined in
@file{/etc/conf/cf.d/stune}:

@code{SHMMAX} (recommended setting: 128MB) and @code{SHMSEG} (recommended
setting: 15). 
These parameters have influence on the MySQL database engine to create
user buffer pools.

@code{NOFILES} and @code{MAXUP} should be at to at least 2048.

@code{MAXPROC} should be set to at least 3000/4000 (depends on number of users) 
or more.

Also is recommended to use following formula to count value for @code{SEMMSL},
@code{SEMMNS} and @code{SEMMNU}:

@example
SEMMSL = 13
@end example

The 13 is what has been found to be the best for both Progress and MySQL.  

@code{SEMMNS} = @code{SEMMSL} * number of db servers to be run on the system.

Set @code{SEMMNS} to the value of @code{SEMMSL} multiplied by the number of
db servers (maximum) that you will be running on the system at one time.

@example
SEMMNU = SEMMNS
@end example

Set the value of @code{SEMMNU} to equal the value of @code{SEMMNS}. You
could probably set this to 75% of @code{SEMMNS}, but this is a conservative
estimate.

You need to at least install the "SCO OpenServer Linker and Application
Development Libraries" or the OpenServer Development System to use @command{gcc}.
You cannot just use the GCC Dev system without installing one of these.

You should get the FSU Pthreads package and install it first. This can be
found at @uref{http://moss.csc.ncsu.edu/~mueller/ftp/pub/PART/pthreads.tar.gz}.
You can also get a precompiled package from 
@uref{ftp://ftp.zenez.com/pub/zenez/prgms/FSU-threads-3.14.tar.gz}.

FSU Pthreads can be compiled with SCO Unix 4.2 with tcpip, or using
OpenServer 3.0 or Open Desktop 3.0 (OS 3.0 ODT 3.0) with the SCO
Development System installed using a good port of GCC 2.5.x. For ODT or OS
3.0, you will need a good port of GCC 2.5.x. There are a lot of problems
without a good port. The port for this product requires the SCO Unix
Development system. Without it, you are missing the libraries and the
linker that is needed.  You will also need
@file{SCO-3.2v4.2-includes.tar.gz}. This file contains the changes to the
SCO Development include files that are needed to get MySQL to build.  You
need to replace the existing system include files with these modified header
files.  They can be obtained from
@uref{ftp://ftp.zenez.com/pub/zenez/prgms/SCO-3.2v4.2-includes.tar.gz}.


To build FSU Pthreads on your system,
all you should need to do is run GNU @command{make}.  The @file{Makefile} in 
FSU-threads-3.14.tar.gz is already set up to make FSU-threads.

You can run @command{./configure} in the @file{threads/src} directory and
select the SCO OpenServer option. This command copies @file{Makefile.SCO5} to
@file{Makefile}.  Then run @command{make}.

To install in the default @file{/usr/include} directory, log in as 
@code{root}, then @code{cd} to the @file{thread/src} directory and run
@command{make install}. 

Remember that you must use GNU @command{make} when making MySQL.

@strong{Note}: If you don't start @command{mysqld_safe} as @code{root}, you
probably will get only the default 110 open files per process. @command{mysqld}
will write a note about this in the log file.

With SCO 3.2V4.2, you should use FSU Pthreads version 3.14 or newer. 
The following @command{configure} command should work:

@example
CFLAGS="-D_XOPEN_XPG4" CXX=gcc CXXFLAGS="-D_XOPEN_XPG4" \
./configure \
    --prefix=/usr/local/mysql \
    --with-named-thread-libs="-lgthreads -lsocket -lgen -lgthreads" \
    --with-named-curses-libs="-lcurses"
@end example

You may get some problems with some include files. In this case, you can
find new SCO-specific include files at
@uref{ftp://ftp.zenez.com/pub/zenez/prgms/SCO-3.2v4.2-includes.tar.gz}.

You should unpack this file in the @file{include} directory of your MySQL
source tree.

SCO development notes:

@itemize bullet
@item
MySQL should automatically detect FSU Pthreads and link @command{mysqld} with 
@code{-lgthreads -lsocket -lgthreads}.

@item
The SCO development libraries are re-entrant in FSU Pthreads. SCO 
claims that its library functions are re-entrant, so they must be 
re-entrant with FSU Pthreads. FSU Pthreads on OpenServer tries to use the 
SCO scheme to make re-entrant libraries.

@item
FSU Pthreads (at least the version at @uref{ftp::/ftp.zenez.com}) comes
linked with GNU @code{malloc}. If you encounter problems with memory usage,
make sure that @file{gmalloc.o} is included in @file{libgthreads.a} and
@file{libgthreads.so}.

@item
In FSU Pthreads, the following system calls are pthreads-aware:
@code{read()}, @code{write()}, @code{getmsg()}, @code{connect()},
@code{accept(),} @code{select()}, and @code{wait()}.

@item
The CSSA-2001-SCO.35.2 (the patch is listed in custom as
erg711905-dscr_remap security patch (version 2.0.0)) breaks FSU threads and
makes @command{mysqld} unstable. You have to remove this one if you want to run
@command{mysqld} on an OpenServer 5.0.6 machine.

@item
SCO provides operating system patches at 
@uref{ftp://ftp.sco.com/pub/openserver5} for OpenServer 5.0.x.

@item
SCO provides security fixes and @code{libsocket.so.2} at 
@uref{ftp://ftp.sco.com/pub/security/OpenServer} and 
@uref{ftp://ftp.sco.com/pub/security/sse} for OpenServer 5.0.x.

@item
Pre-OSR506 security fixes. Also, the @code{telnetd} fix at
@uref{ftp://stage.caldera.com/pub/security/openserver/} or
@uref{ftp://stage.caldera.com/pub/security/openserver/CSSA-2001-SCO.10/} as
both @file{libsocket.so.2} and @file{libresolv.so.1} with instructions for
installing on pre-OSR506 systems.

It's probably a good idea to install these
patches before trying to compile/use MySQL.

@end itemize

Begining with Legend, OpenServer will have native threads and no 2GB file 
size limit.



@node SCO UnixWare,  , SCO, Other Unix Notes
@subsubsection SCO UnixWare Version 7.1.x Notes

We recommend using the latest production release of MySQL.  Currently this
is MySQL 4.0.x.  Should you choose to use an older release of MySQL on
UnixWare 7.1.x, you must use a version of MySQL at least as recent as
3.22.13 to get fixes for some portability and OS problems.

We have been able to compile MySQL with the following @command{configure}
command on UnixWare Version 7.1.x:

@example
CC="cc" CFLAGS="-I/usr/local/include" \
CXX="CC" CXXFLAGS="-I/usr/local/include" \
./configure --prefix=/usr/local/mysql \
    --enable-thread-safe-client --with-berkeley-db=./bdb \
    --with-innodb --with-openssl --with-extra-charsets=complex
@end example

If you want to use @command{gcc}, you must use @command{gcc} 2.95.3 or newer.

@example
CC=gcc CXX=g++ ./configure --prefix=/usr/local/mysql
@end example

SCO provides operating system patches at
@uref{ftp://ftp.sco.com/pub/unixware7} for UnixWare 7.1.1,
@uref{ftp://ftp.sco.com/pub/unixware7/713/} for UnixWare 7.1.3,
@uref{ftp://ftp.sco.com/pub/unixware7/714/} for UnixWare 7.1.4, and
@uref{ftp://ftp.sco.com/pub/openunix8} for OpenUNIX 8.0.0.

SCO provides information about security fixes at
@uref{ftp://ftp.sco.com/pub/security/OpenUNIX} for OpenUNIX and
@uref{ftp://ftp.sco.com/pub/security/UnixWare} for UnixWare.

By default, the maximum file size on a UnixWare 7 system is 1GB.
Many OS utilities have a limitation of 2GB.  The maximum possible file
size on UnixWare 7 is 1TB with VXFS.

To enable large file support on UnixWare 7.1.x, run @code{fsadm}.

@example
# fsadm -Fvxfs -o largefiles /
# fsadm /					* Note
# ulimit unlimited
# cd /etc/conf/bin
# ./idtune SFSZLIM 0x7FFFFFFF			** Note
# ./idtune HFSZLIM 0x7FFFFFFF			** Note
# ./idbuild -B

* This should report "largefiles".
** 0x7FFFFFFF represents infinity for these values.
@end example

Reboot the system using @code{shutdown}.

By default, the entries in @file{/etc/conf/cf.d/mtune} are set to:

@example
Value           Default         Min             Max
-----           -------         ---             ---
SVMMLIM         0x9000000       0x1000000       0x7FFFFFFF
HVMMLIM         0x9000000       0x1000000       0x7FFFFFFF
SSTKLIM         0x1000000       0x2000          0x7FFFFFFF
HSTKLIM         0x1000000       0x2000          0x7FFFFFFF
@end example

We recommend setting these values as follows:

@example
SDATLIM 0x7FFFFFFF
HDATLIM 0x7FFFFFFF
SSTKLIM 0x7FFFFFFF
HSTKLIM 0x7FFFFFFF
SVMMLIM 0x7FFFFFFF
HVMMLIM 0x7FFFFFFF
SFNOLIM 2048
HFNOLIM 2048
@end example

We recommend tuning the system, but the proper parameter values to use
depend on the number of users accessing the application or database
and size the of the database (that is, the used buffer pool). The
following will affect the following kernel parameters defined in
@file{/etc/conf/cf.d/stune}:

@code{SHMMAX} (recommended setting: 128MB) and @code{SHMSEG} (recommended
setting: 15).
These parameters have influence on the MySQL database engine to create
user buffer pools.

@code{SFNOLIM} and @code{HFNOLIM} should be at maximum 2048.

@code{NPROC} should be set to at least 3000/4000 (depends on number of users).

Also is recommended to use following formula to count value for @code{SEMMSL},
@code{SEMMNS}, and @code{SEMMNU}:

@example
SEMMSL = 13
@end example

13 is what has been found to be the best for both Progress and MySQL.

@code{SEMMNS} = @code{SEMMSL} * number of db servers to be run on the system.

Set @code{SEMMNS} to the value of @code{SEMMSL} multiplied by the number
of db servers (maximum) that you will be running on the system at one time.

@code{SEMMNU} = @code{SEMMNS}

Set the value of @code{SEMMNU} to equal the value of @code{SEMMNS}. You
could probably set this to 75% of @code{SEMMNS}, but this is a conservative estimate.


@node OS/2, BeOS, Other Unix Notes, Operating System Specific Notes
@subsection OS/2 Notes

MySQL uses quite a few open files. Because of this, you should add
something like the following to your @file{CONFIG.SYS} file:

@example
SET EMXOPT=-c -n -h1024
@end example

If you don't do this, you will probably run into the following error:

@example
File '@var{xxxx}' not found (Errcode: 24)
@end example

When using MySQL with OS/2 Warp 3, FixPack 29 or above is
required.  With OS/2 Warp 4, FixPack 4 or above is required. This is a
requirement of the Pthreads library.  MySQL must be installed
on a partition with a type that supports long filenames, such as HPFS, FAT32,
and so on.

The @file{INSTALL.CMD} script must be run from OS/2's own @file{CMD.EXE}
and may not work with replacement shells such as @file{4OS2.EXE}.

The @file{scripts/mysql-install-db} script has been renamed.  It is now called
@file{install.cmd} and is a REXX script, which will set up the default
MySQL security settings and create the WorkPlace Shell icons
for MySQL.

Dynamic module support is compiled in but not fully tested. Dynamic
modules should be compiled using the Pthreads runtime library.

@example
gcc -Zdll -Zmt -Zcrtdll=pthrdrtl -I../include -I../regex -I.. \
    -o example udf_example.cc -L../lib -lmysqlclient udf_example.def
mv example.dll example.udf
@end example

@strong{Note}: Due to limitations in OS/2, UDF module name stems must not
exceed eight characters. Modules are stored in the @file{/mysql2/udf}
directory; the @code{safe-mysqld.cmd} script will put this directory in
the @code{BEGINLIBPATH} environment variable. When using UDF modules,
specified extensions are ignored---it is assumed to be @file{.udf}.
For example, in Unix, the shared module might be named @file{example.so}
and you would load a function from it like this:

@example
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME 'example.so';
@end example

In OS/2, the module would be named @file{example.udf}, but you would not
specify the module extension:

@example
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME 'example';
@end example


@node BeOS,  , OS/2, Operating System Specific Notes
@subsection BeOS Notes

We have in the past talked with some BeOS developers who have said that
MySQL is 80% ported to BeOS, but we haven't heard from them
in a while.


@node Perl support,  , Operating System Specific Notes, Installing
@section Perl Installation Notes

@cindex Perl, installing
@cindex installing, Perl

Perl support for MySQL is provided by means of the @code{DBI}/@code{DBD}
client interface. The interface requires Perl Version 5.6.0 or later.
It @emph{will not work} if you have an older version of Perl.

If you want to use transactions with Perl DBI, you need to have
@code{DBD::mysql} version 1.2216 or newer. Version 2.9003 or newer
is recommended.

If you are using the MySQL 4.1 client library, you must use
@code{DBD::mysql} 2.9003 or newer.

As of MySQL 3.22.8, Perl support is no longer included with MySQL
distributions. You can obtain the necessary modules from
@uref{http://search.cpan.org} for Unix, or by using the ActiveState
@code{ppm} program on Windows. The following sections describe how to do
this.

Perl support for MySQL must be installed if you want to run the MySQL
benchmark scripts.
@xref{MySQL Benchmarks}.

@menu
* Perl installation::           Installing Perl on Unix
* ActiveState Perl::            Installing ActiveState Perl on Windows
* Perl support problems::       Problems Using the Perl @code{DBI}/@code{DBD} Interface
@end menu


@node Perl installation, ActiveState Perl, Perl support, Perl support
@subsection Installing Perl on Unix

MySQL Perl support requires that you've installed MySQL client programming
support (libraries and header files).  Most installation methods install
the necessary files. However, if you installed MySQL from RPM files
on Linux, be sure that you've installed the developer RPM.  The client
programs are in the client RPM, but client programming support is in
the developer RPM.

If you want to install Perl support, the files you will need can
be obtained from the CPAN (Comprehensive Perl Archive Network) at
@uref{http://search.cpan.org}.

The easiest way to install Perl modules on Unix is to use the @code{CPAN}
module. For example:

@example
shell> perl -MCPAN -e shell
cpan> install DBI
cpan> install DBD::mysql
@end example

The @code{DBD::mysql} installation runs a number of tests.
These tests require being able to connect to the local MySQL server
as the anonymous user with no password. If you have removed anonymous
accounts or assigned them passwords, the tests fail. You can use @code{force
install DBD::mysql} to ignore the failed tests.

@code{DBI} requires the @code{Data::Dumper} module. It may already be
installed; if not, you should install it before installing @code{DBI}.

It is also possible to download the module distributions in the form of
compressed @command{tar} archives and build the modules manually. For example,
to unpack and build a DBI distribution, use a procedure such as this:

@enumerate
@item
Unpack the distribution into the current directory:
@example
shell> gunzip < DBI-@var{VERSION}.tar.gz | tar xvf -
@end example
This command creates a directory named @file{DBI-@var{VERSION}}.

@item
Change location into the top-level directory of the unpacked distribution:
@example
shell> cd DBI-@var{VERSION}
@end example

@item
Build the distribution and compile everything:
@example
shell> perl Makefile.PL
shell> make
shell> make test
shell> make install
@end example
@end enumerate

The @command{make test} command is important because it verifies that the
module is working.  Note that when you run that command during the
@code{DBD::mysql} installation to exercise the interface code, the
MySQL server must be running or the test will fail.

It is a good idea to rebuild and reinstall the @code{DBD::mysql}
distribution whenever you install a new release of MySQL,
particularly if you notice symptoms such as that all your @code{DBI} scripts
fail after you upgrade MySQL.

If you don't have access rights to install Perl modules in the system directory
or if you want to install local Perl modules, the following reference may be
useful:
@uref{http://servers.digitaldaze.com/extensions/perl/modules.html#modules}

Look under the heading ``Installing New Modules that Require Locally
Installed Modules.''


@node ActiveState Perl, Perl support problems, Perl installation, Perl support
@subsection Installing ActiveState Perl on Windows

@cindex installing, Perl on Windows
@cindex Perl, installing on Windows
@cindex ActiveState Perl

On Windows, you should do the following to install the MySQL
@code{DBD} module with ActiveState Perl:

@itemize @bullet
@item
Get ActiveState Perl from
@uref{http://www.activestate.com/Products/ActivePerl/}
and install it.

@item
Open a console window (a ``DOS window'').

@item
If required, set the @code{HTTP_proxy} variable. For example, you might try:

@example
set HTTP_proxy=my.proxy.com:3128
@end example

@item
Start the PPM program:

@example
C:\> C:\perl\bin\ppm.pl
@end example

@item
If you have not already done so, install @code{DBI}:

@example
ppm> install DBI
@end example

@item
If this succeeds, run the following command:

@example
install \
ftp://ftp.de.uu.net/pub/CPAN/authors/id/JWIED/DBD-mysql-1.2212.x86.ppd
@end example
@end itemize

This procedure should work at least with ActiveState Perl Version 5.6.

If you can't get the procedure to work, you should instead install the
MyODBC driver and connect to the MySQL server through
ODBC:

@example
use DBI;
$dbh= DBI->connect("DBI:ODBC:$dsn",$user,$password) ||
  die "Got error $DBI::errstr when connecting to $dsn\n";
@end example


@node Perl support problems,  , ActiveState Perl, Perl support
@subsection Problems Using the Perl @code{DBI}/@code{DBD} Interface

@cindex problems, installing Perl
@cindex Perl DBI/DBD, installation problems

If Perl reports that it can't find the @file{../mysql/mysql.so} module,
then the problem is probably that Perl can't locate the shared library
@file{libmysqlclient.so}.

You should be able to fix this by one of the following methods:

@itemize @bullet
@item
Compile the @code{DBD::mysql} distribution with @code{perl
Makefile.PL -static -config} rather than @code{perl Makefile.PL}.

@item
Copy @file{libmysqlclient.so} to the directory where your other shared
libraries are located (probably @file{/usr/lib} or @file{/lib}).

@item
Modify the @code{-L} options used to compile @code{DBD::mysql} to reflect
the actual location of @file{libmysqlclient.so}.

@item
On Linux, you can add the pathname of the directory where
@file{libmysqlclient.so} is located to the @file{/etc/ld.so.conf} file.

@tindex LD_RUN_PATH environment variable
@tindex Environment variable, LD_RUN_PATH
@tindex LD_LIBRARY_PATH environment variable
@tindex Environment variable, LD_LIBRARY_PATH
@item
Add the pathname of the directory where @file{libmysqlclient.so} is located
to the @code{LD_RUN_PATH} environment variable. Some systems use
@code{LD_LIBRARY_PATH} instead.
@end itemize

Note that you may also need to modify the @code{-L} options if there are
other libraries that the linker fails to find. For example, if the linker
cannot find @code{libc} because it is in @file{/lib} and the link command
specifies @code{-L/usr/lib}, change the @code{-L} option to @code{-L/lib}
or add @code{-L/lib} to the existing link command.

If you get the following errors from @code{DBD::mysql},
you are probably using @command{gcc} (or using an old binary compiled with
@command{gcc}):

@example
/usr/bin/perl: can't resolve symbol '__moddi3'
/usr/bin/perl: can't resolve symbol '__divdi3'
@end example

Add @code{-L/usr/lib/gcc-lib/... -lgcc} to the link command when the
@file{mysql.so} library gets built (check the output from @command{make} for
@file{mysql.so} when you compile the Perl client).  The @code{-L} option
should specify the pathname of the directory where @file{libgcc.a} is located
on your system.

Another cause of this problem may be that Perl and MySQL aren't both
compiled with @command{gcc}.  In this case, you can solve the mismatch by
compiling both with @command{gcc}.

You may see the following error from @code{DBD::mysql}
when you run the tests:

@example
t/00base............install_driver(mysql) failed:
Can't load '../blib/arch/auto/DBD/mysql/mysql.so' for module DBD::mysql:
../blib/arch/auto/DBD/mysql/mysql.so: undefined symbol:
uncompress at /usr/lib/perl5/5.00503/i586-linux/DynaLoader.pm line 169.
@end example

This means that you need to include the @code{-lz} compression library on the
link line. That can be done by changing the following line in the file
@file{lib/DBD/mysql/Install.pm}:

@example
$sysliblist .= " -lm";
@end example

Change that line to:

@example
$sysliblist .= " -lm -lz";
@end example

After this, you @emph{must} run @command{make realclean} and then
proceed with the installation from the beginning.

If you want to install DBI on SCO, you have to edit the
@file{Makefile} in DBI-@var{xxx} and each subdirectory.
Note that the following assumes @command{gcc} 2.95.2 or newer:

@example
OLD:                                  NEW:
CC = cc                               CC = gcc
CCCDLFLAGS = -KPIC -W1,-Bexport       CCCDLFLAGS = -fpic
CCDLFLAGS = -wl,-Bexport              CCDLFLAGS =

LD = ld                               LD = gcc -G -fpic
LDDLFLAGS = -G -L/usr/local/lib       LDDLFLAGS = -L/usr/local/lib
LDFLAGS = -belf -L/usr/local/lib      LDFLAGS = -L/usr/local/lib

LD = ld                               LD = gcc -G -fpic
OPTIMISE = -Od                        OPTIMISE = -O1

OLD:
CCCFLAGS = -belf -dy -w0 -U M_XENIX -DPERL_SCO5 -I/usr/local/include

NEW:
CCFLAGS = -U M_XENIX -DPERL_SCO5 -I/usr/local/include
@end example

These changes are necessary
because the Perl dynaloader will not load the @code{DBI} modules
if they were compiled with @command{icc} or @command{cc}.

If you want to use the Perl module on a system that doesn't support
dynamic linking (such as SCO), you can generate a static version of
Perl that includes @code{DBI} and @code{DBD::mysql}.  The way this works
is that you generate a version of Perl with the @code{DBI} code linked
in and install it on top of your current Perl.  Then you use that to
build a version of Perl that additionally has the @code{DBD} code linked
in, and install that.

On SCO, you must have the following environment variables set:

@example
LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib:/usr/progressive/lib
@end example

Or:

@example
LD_LIBRARY_PATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib:\
    /usr/progressive/lib:/usr/skunk/lib
LIBPATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib:\
    /usr/progressive/lib:/usr/skunk/lib
MANPATH=scohelp:/usr/man:/usr/local1/man:/usr/local/man:\
    /usr/skunk/man:
@end example

First, create a Perl that includes a statically linked @code{DBI} module by
running these commands in the directory where your @code{DBI} distribution is
located:

@example
shell> perl Makefile.PL -static -config
shell> make
shell> make install
shell> make perl
@end example

Then you must install the new Perl. The output of @command{make perl} will
indicate the exact @command{make} command you will need to execute to perform
the installation.  On SCO, this is
@command{make -f Makefile.aperl inst_perl MAP_TARGET=perl}.

Next, use the just-created Perl to create another Perl that also includes a
statically linked @code{DBD::mysql} by running these commands in the
directory where your @code{DBD::mysql} distribution is located:

@example
shell> perl Makefile.PL -static -config
shell> make
shell> make install
shell> make perl
@end example

Finally, you should install this new Perl.  Again, the output of @command{make
perl} indicates the command to use.




@node Tutorial, Using MySQL Programs, Installing, Top
@chapter MySQL Tutorial

@cindex tutorial
@cindex terminal monitor, defined
@cindex monitor, terminal
@cindex options, provided by MySQL

@menu
* Connecting-disconnecting::    Connecting to and Disconnecting from the Server
* Entering queries::            Entering Queries
* Database use::                Creating and Using a Database
* Getting information::         Getting Information About Databases and Tables
* Batch mode::                  Using @command{mysql} in Batch Mode
* Examples::                    Examples of Common Queries
* Twin::                        Queries from the Twin Project
* Apache::                      Using MySQL with Apache
@end menu

This chapter provides a tutorial introduction to MySQL by showing
how to use the @command{mysql} client program to create and use a simple
database.  @command{mysql} (sometimes referred to as the ``terminal monitor'' or
just ``monitor'') is an interactive program that allows you to connect to a
MySQL server, run queries, and view the results.  @command{mysql} may
also be used in batch mode: you place your queries in a file beforehand, then
tell @command{mysql} to execute the contents of the file.  Both ways of using
@command{mysql} are covered here.

To see a list of options provided by @command{mysql}, invoke it with
the @code{--help} option:

@example
shell> mysql --help
@end example

This chapter assumes that @command{mysql} is installed on your machine and that
a MySQL server is available to which you can connect.  If this is
not true, contact your MySQL administrator.  (If @strong{you} are the
administrator, you will need to consult other sections of this manual.)

This chapter describes the entire process of setting up and using a
database.  If you are interested only in accessing an already-existing
database, you may want to skip over the sections that describe how to
create the database and the tables it contains.

Because this chapter is tutorial in nature, many details are necessarily
omitted.  Consult the relevant sections of the manual for more
information on the topics covered here.


@node Connecting-disconnecting, Entering queries, Tutorial, Tutorial
@section Connecting to and Disconnecting from the Server

@cindex connecting, to the server
@cindex disconnecting, from the server
@cindex server, connecting
@cindex server, disconnecting

To connect to the server, you'll usually need to provide a MySQL
username when you invoke @command{mysql} and, most likely, a password.  If the
server runs on a machine other than the one where you log in, you'll also
need to specify a hostname.  Contact your administrator to find out what
connection parameters you should use to connect (that is, what host, username,
and password to use).  Once you know the proper parameters, you should be
able to connect like this:

@example
shell> mysql -h @var{host} -u @var{user} -p
Enter password: ********
@end example

@code{host} and @code{user} represent the hostname where your MySQL server is
running and the username of your MySQL account.  Substitute appropriate values
for your setup.
The @code{********} represents your password; enter it when @command{mysql}
displays the @code{Enter password:} prompt.

If that works, you should see some introductory information followed by a
@code{mysql>} prompt:


@example
shell> mysql -h @var{host} -u @var{user} -p
Enter password: ********
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 25338 to server version: 4.0.14-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql>
@end example

The prompt tells you that @command{mysql} is ready for you to enter commands.

Some MySQL installations allow users to connect as the anonymous
(unnamed) user to the server running on the local host.  If this is the case
on your machine, you should be able to connect to that server by invoking
@command{mysql} without any options:

@example
shell> mysql
@end example

After you have connected successfully, you can disconnect any time by typing
@code{QUIT} (or @code{\q}) at the @code{mysql>} prompt:

@example
mysql> QUIT
Bye
@end example

On Unix, you can also disconnect by pressing Control-D.

Most examples in the following sections assume that you are connected to the
server.  They indicate this by the @code{mysql>} prompt.


@node Entering queries, Database use, Connecting-disconnecting, Tutorial
@section Entering Queries

@cindex running, queries
@cindex queries, entering
@cindex entering, queries

Make sure that you are connected to the server, as discussed in the previous
section.  Doing so will not in itself select any database to work with, but
that's okay.  At this point, it's more important to find out a little about
how to issue queries than to jump right in creating tables, loading data
into them, and retrieving data from them.  This section describes the basic
principles of entering commands, using several queries you can try out to
familiarize yourself with how @command{mysql} works.

Here's a simple command that asks the server to tell you its version number
and the current date.  Type it in as shown here following the @code{mysql>}
prompt and press Enter:

@example
mysql> SELECT VERSION(), CURRENT_DATE;
+--------------+--------------+
| VERSION()    | CURRENT_DATE |
+--------------+--------------+
| 3.22.20a-log | 1999-03-19   |
+--------------+--------------+
1 row in set (0.01 sec)
mysql>
@end example

This query illustrates several things about @command{mysql}:

@itemize @bullet
@item
A command normally consists of an SQL statement followed by a semicolon.
(There are some exceptions where a semicolon may be omitted.  @code{QUIT},
mentioned earlier, is one of them.  We'll get to others later.)

@item
When you issue a command, @command{mysql} sends it to the server for execution
and displays the results, then prints another @code{mysql>} prompt to indicate
that it is ready for another command.

@item
@command{mysql} displays query output in tabular form (rows and columns).  The
first row contains labels for the columns.  The rows following are the query
results.  Normally, column labels are the names of the columns you fetch from
database tables.  If you're retrieving the value of an expression rather than
a table column (as in the example just shown), @command{mysql} labels the column
using the expression itself.

@item
@command{mysql} shows how many rows were returned and how long the query took
to execute, which gives you a rough idea of server performance.  These values
are imprecise because they represent wall clock time (not CPU or machine
time), and because they are affected by factors such as server load and
network latency.  (For brevity, the ``rows in set'' line is not shown in
the remaining examples in this chapter.)
@end itemize

Keywords may be entered in any lettercase.  The following queries are
equivalent:

@example
mysql> SELECT VERSION(), CURRENT_DATE;
mysql> select version(), current_date;
mysql> SeLeCt vErSiOn(), current_DATE;
@end example

Here's another query.  It demonstrates that you can use @command{mysql} as a
simple calculator:

@example
mysql> SELECT SIN(PI()/4), (4+1)*5;
+-------------+---------+
| SIN(PI()/4) | (4+1)*5 |
+-------------+---------+
|    0.707107 |      25 |
+-------------+---------+
@end example

The queries shown thus far have been relatively short, single-line
statements.  You can even enter multiple statements on a single line.
Just end each one with a semicolon:

@example
mysql> SELECT VERSION(); SELECT NOW();
+--------------+
| VERSION()    |
+--------------+
| 3.22.20a-log |
+--------------+

+---------------------+
| NOW()               |
+---------------------+
| 1999-03-19 00:15:33 |
+---------------------+
@end example

A command need not be given all on a single line, so lengthy commands that
require several lines are not a problem.  @command{mysql} determines where your
statement ends by looking for the terminating semicolon, not by looking for
the end of the input line.  (In other words, @command{mysql}
accepts free-format input:  it collects input lines but does not execute them
until it sees the semicolon.)

Here's a simple multiple-line statement:

@example
mysql> SELECT
    -> USER()
    -> ,
    -> CURRENT_DATE;
+--------------------+--------------+
| USER()             | CURRENT_DATE |
+--------------------+--------------+
| joesmith@@localhost | 1999-03-18   |
+--------------------+--------------+
@end example

In this example, notice how the prompt changes from @code{mysql>} to
@code{->} after you enter the first line of a multiple-line query.  This is
how @command{mysql} indicates that it hasn't seen a complete statement and is
waiting for the rest.  The prompt is your friend, because it provides
valuable feedback.  If you use that feedback, you will always be aware of
what @command{mysql} is waiting for.

If you decide you don't want to execute a command that you are in the
process of entering, cancel it by typing @code{\c}:

@example
mysql> SELECT
    -> USER()
    -> \c
mysql>
@end example

Here, too, notice the prompt.  It switches back to @code{mysql>} after you
type @code{\c}, providing feedback to indicate that @command{mysql} is ready
for a new command.

The following table shows each of the prompts you may see and summarizes what
they mean about the state that @command{mysql} is in:

@cindex prompts, meanings
@multitable @columnfractions .10 .80
@item @strong{Prompt} @tab @strong{Meaning}
@item @code{mysql>} @tab Ready for new command.
@item @code{@ @ @ @ ->} @tab Waiting for next line of multiple-line command.
@item @code{@ @ @ @ '>} @tab Waiting for next line, collecting a string that begins with a single quote (@samp{'}).
@item @code{@ @ @ @ ">} @tab Waiting for next line, collecting a string that begins with a double quote (@samp{"}).
@item @code{@ @ @ @ `>} @tab Waiting for next line, collecting an identifier that begins with a backtick (@samp{`}).
@end multitable

Multiple-line statements commonly occur by accident when you intend to
issue a command on a single line, but forget the terminating semicolon.  In
this case, @command{mysql} waits for more input:

@example
mysql> SELECT USER()
    ->
@end example

If this happens to you (you think you've entered a statement but the only
response is a @code{->} prompt), most likely @command{mysql} is waiting for the
semicolon.  If you don't notice what the prompt is telling you, you might sit
there for a while before realising what you need to do.  Enter a semicolon to
complete the statement, and @command{mysql} will execute it:

@example
mysql> SELECT USER()
    -> ;
+--------------------+
| USER()             |
+--------------------+
| joesmith@@localhost |
+--------------------+
@end example

The @code{'>} and @code{">} prompts occur during string collection.
In MySQL, you can write strings surrounded by either @samp{'}
or @samp{"} characters (for example, @code{'hello'} or @code{"goodbye"}),
and @command{mysql} lets you enter strings that span multiple lines.  When you
see a @code{'>} or @code{">} prompt, it means that you've entered a line
containing a string that begins with a @samp{'} or @samp{"} quote character,
but have not yet entered the matching quote that terminates the string.
That's fine if you really are entering a multiple-line string, but how likely
is that?  Not very.  More often, the @code{'>} and @code{">} prompts indicate
that you've inadvertantly left out a quote character.  For example:

@example
mysql> SELECT * FROM my_table WHERE name = 'Smith AND age < 30;
    '>
@end example

If you enter this @code{SELECT} statement, then press Enter and wait for the
result, nothing will happen.  Instead of wondering why this
query takes so long, notice the clue provided by the @code{'>} prompt.  It
tells you that @command{mysql} expects to see the rest of an unterminated
string.  (Do you see the error in the statement?  The string @code{'Smith} is
missing the second quote.)

At this point, what do you do?  The simplest thing is to cancel the command.
However, you cannot just type @code{\c} in this case, because @command{mysql}
interprets it as part of the string that it is collecting!  Instead, enter
the closing quote character (so @command{mysql} knows you've finished the
string), then type @code{\c}:

@example
mysql> SELECT * FROM my_table WHERE name = 'Smith AND age < 30;
    '> '\c
mysql>
@end example

The prompt changes back to @code{mysql>}, indicating that @command{mysql}
is ready for a new command.

The @code{`>} prompt is similar to th @code{'>} and @code{">} prompts,
but indicates that you have begun but not completed a backtick-quoted
identifier.

It's important to know what the @code{'>}, @code{">}, and @code{`>} prompts signify,
because if you mistakenly enter an unterminated string, any further lines you
type will appear to be ignored by @command{mysql}---including a line
containing @code{QUIT}!  This can be quite confusing, especially if you
don't know that you need to supply the terminating quote before you can
cancel the current command.


@node Database use, Getting information, Entering queries, Tutorial
@section Creating and Using a Database

@cindex databases, creating
@cindex databases, using
@cindex creating, databases

@menu
* Creating database::           Creating and Selecting a Database
* Creating tables::             Creating a Table
* Loading tables::              Loading Data into a Table
* Retrieving data::             Retrieving Information from a Table
@end menu

Now that you know how to enter commands, it's time to access a database.

Suppose that you have several pets in your home (your menagerie) and you'd
like to keep track of various types of information about them.  You can do so
by creating tables to hold your data and loading them with the desired
information.  Then you can answer different sorts of questions about your
animals by retrieving data from the tables.  This section shows you how to:

@itemize @bullet
@item
Create a database
@item
Create a table
@item
Load data into the table
@item
Retrieve data from the table in various ways
@item
Use multiple tables
@end itemize

The menagerie database will be simple (deliberately), but it is not difficult
to think of real-world situations in which a similar type of database might
be used.  For example, a database like this could be used by a farmer to keep
track of livestock, or by a veterinarian to keep track of patient records.
A menagerie distribution containing some of the queries and sample data used
in the following sections can be obtained from the MySQL Web site.
It's available in either compressed @command{tar} format
(@uref{http://www.mysql.com/Downloads/Contrib/Examples/menagerie.tar.gz})
or Zip format
(@uref{http://www.mysql.com/Downloads/Contrib/Examples/menagerie.zip}).

Use the @code{SHOW} statement to find out what databases currently exist
on the server:

@example
mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql    |
| test     |
| tmp      |
+----------+
@end example

The list of databases is probably different on your machine, but the
@code{mysql} and @code{test} databases are likely to be among them.  The
@code{mysql} database is required because it describes user access
privileges.  The @code{test} database is often provided as a workspace for
users to try things out.

Note that you may not see all databases if you don't have the
@code{SHOW DATABASES} privilege. @xref{GRANT, , @code{GRANT}}.

If the @code{test} database exists, try to access it:

@example
mysql> USE test
Database changed
@end example

Note that @code{USE}, like @code{QUIT}, does not require a semicolon.  (You
can terminate such statements with a semicolon if you like; it does no harm.)
The @code{USE} statement is special in another way, too:  it must be given on
a single line.

You can use the @code{test} database (if you have access to it) for the
examples that follow, but anything you create in that database can be
removed by anyone else with access to it.  For this reason, you should
probably ask your MySQL administrator for permission to use a
database of your own.  Suppose that you want to call yours @code{menagerie}.  The
administrator needs to execute a command like this:

@example
mysql> GRANT ALL ON menagerie.* TO 'your_mysql_name'@@'your_client_host';
@end example

where @code{your_mysql_name} is the MySQL username assigned to
you and @code{your_client_host} is the host from which you connect to the
server.


@node Creating database, Creating tables, Database use, Database use
@subsection Creating and Selecting a Database

@cindex selecting, databases
@cindex databases, selecting

If the administrator creates your database for you when setting up your
permissions, you can begin using it.  Otherwise, you need to create it
yourself:

@example
mysql> CREATE DATABASE menagerie;
@end example

Under Unix, database names are case sensitive (unlike SQL keywords), so you
must always refer to your database as @code{menagerie}, not as
@code{Menagerie}, @code{MENAGERIE}, or some other variant.  This is also true
for table names.  (Under Windows, this restriction does not apply, although
you must refer to databases and tables using the same lettercase throughout a
given query.)

Creating a database does not select it for use; you must do that explicitly.
To make @code{menagerie} the current database, use this command:

@example
mysql> USE menagerie
Database changed
@end example

Your database needs to be created only once, but you must select it for use
each time you begin a @command{mysql} session.  You can do this by issuing a
@code{USE} statement as shown in the example.  Alternatively, you can select the
database on the command line when you invoke @command{mysql}.  Just specify its
name after any connection parameters that you might need to provide.  For
example:

@example
shell> mysql -h @var{host} -u @var{user} -p menagerie
Enter password: ********
@end example

Note that @code{menagerie} is not your password on the command just shown.
If you want to supply your password on the command line after the @code{-p}
option, you must do so with no intervening space (for example, as
@code{-pmypassword}, not as @code{-p mypassword}).  However, putting your
password on the command line is not recommended, because doing so exposes it
to snooping by other users logged in on your machine.


@node Creating tables, Loading tables, Creating database, Database use
@subsection Creating a Table

@cindex tables, creating
@cindex creating, tables

Creating the database is the easy part, but at this point it's empty, as
@code{SHOW TABLES} will tell you:

@example
mysql> SHOW TABLES;
Empty set (0.00 sec)
@end example

The harder part is deciding what the structure of your database should be:
what tables you will need and what columns will be in each of them.

You'll want a table that contains a record for each of your pets.  This can
be called the @code{pet} table, and it should contain, as a bare minimum,
each animal's name.  Because the name by itself is not very interesting, the
table should contain other information.  For example, if more than one person
in your family keeps pets, you might want to list each animal's owner.  You
might also want to record some basic descriptive information such as species
and sex.

How about age?  That might be of interest, but it's not a good thing to store
in a database.  Age changes as time passes, which means you'd have to update
your records often.  Instead, it's better to store a fixed value such as
date of birth.  Then, whenever you need age, you can calculate it as the
difference between the current date and the birth date.  MySQL
provides functions for doing date arithmetic, so this is not difficult.
Storing birth date rather than age has other advantages, too:

@itemize @bullet
@item
You can use the database for tasks such as generating reminders for upcoming
pet birthdays.  (If you think this type of query is somewhat silly, note that
it is the same question you might ask in the context of a business database
to identify clients to whom you'll soon need to send out birthday greetings,
for that computer-assisted personal touch.)

@item
You can calculate age in relation to dates other than the current date.  For
example, if you store death date in the database, you can easily calculate
how old a pet was when it died.
@end itemize

You can probably think of other types of information that would be useful in
the @code{pet} table, but the ones identified so far are sufficient for now:
name, owner, species, sex, birth, and death.

Use a @code{CREATE TABLE} statement to specify the layout of your table:

@example
mysql> CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20),
    -> species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);
@end example

@code{VARCHAR} is a good choice for the @code{name}, @code{owner}, and
@code{species} columns because the column values will vary in length.  The
lengths of those columns need not all be the same, and need not be
@code{20}.  You can pick any length from @code{1} to @code{255}, whatever
seems most reasonable to you.  (If you make a poor choice and it turns
out later that you need a longer field, MySQL provides an
@code{ALTER TABLE} statement.)

Several types of values can be chosen to represent sex in animal records,
such as @code{'m'}
and @code{'f'}, or perhaps @code{'male'} and @code{'female'}.  It's simplest
to use the single characters @code{'m'} and @code{'f'}.

The use of the @code{DATE} data type for the @code{birth} and @code{death}
columns is a fairly obvious choice.

Now that you have created a table, @code{SHOW TABLES} should produce some
output:

@example
mysql> SHOW TABLES;
+---------------------+
| Tables in menagerie |
+---------------------+
| pet                 |
+---------------------+
@end example

To verify that your table was created the way you expected, use
a @code{DESCRIBE} statement:

@example
mysql> DESCRIBE pet;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| name    | varchar(20) | YES  |     | NULL    |       |
| owner   | varchar(20) | YES  |     | NULL    |       |
| species | varchar(20) | YES  |     | NULL    |       |
| sex     | char(1)     | YES  |     | NULL    |       |
| birth   | date        | YES  |     | NULL    |       |
| death   | date        | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+
@end example

You can use @code{DESCRIBE} any time, for example, if you forget the names of
the columns in your table or what types they have.


@node Loading tables, Retrieving data, Creating tables, Database use
@subsection Loading Data into a Table

@cindex loading, tables
@cindex tables, loading data
@cindex data, loading into tables

After creating your table, you need to populate it.  The @code{LOAD DATA} and
@code{INSERT} statements are useful for this.

Suppose that your pet records can be described as shown here.
(Observe that MySQL expects dates in @code{'YYYY-MM-DD'} format;
this may be different from what you are used to.)

@multitable @columnfractions .10 .10 .10 .05 .20 .20
@item @strong{name} @tab @strong{owner} @tab @strong{species} @tab @strong{sex} @tab @strong{birth} @tab @strong{death}
@item Fluffy @tab Harold @tab cat @tab f @tab 1993-02-04 @tab
@item Claws @tab Gwen @tab cat @tab m @tab 1994-03-17 @tab
@item Buffy @tab Harold @tab dog @tab f @tab 1989-05-13 @tab
@item Fang @tab Benny @tab dog @tab m @tab 1990-08-27 @tab
@item Bowser @tab Diane @tab dog @tab m @tab 1979-08-31 @tab 1995-07-29
@item Chirpy @tab Gwen @tab bird @tab f @tab 1998-09-11 @tab
@item Whistler @tab Gwen @tab bird @tab @tab 1997-12-09 @tab
@item Slim @tab Benny @tab snake @tab m @tab 1996-04-29 @tab
@end multitable

Because you are beginning with an empty table, an easy way to populate it is to
create a text file containing a row for each of your animals, then load the
contents of the file into the table with a single statement.

You could create a text file @file{pet.txt} containing one record per line,
with values separated by tabs, and given in the order in which the columns
were listed in the @code{CREATE TABLE} statement.  For missing values (such
as unknown sexes or death dates for animals that are still living), you can
use @code{NULL} values.  To represent these in your text file, use
@code{\N} (backslash, capital-N).  For example, the record for Whistler the
bird would look like
this (where the whitespace between values is a single tab character):

@multitable @columnfractions .10 .10 .10 .05 .20 .20
@item @strong{name} @tab @strong{owner} @tab @strong{species} @tab @strong{sex} @tab @strong{birth} @tab @strong{death}
@item @code{Whistler} @tab @code{Gwen} @tab @code{bird} @tab @code{\N} @tab @code{1997-12-09} @tab @code{\N}
@end multitable

To load the text file @file{pet.txt} into the @code{pet} table, use this
command:

@example
mysql> LOAD DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet;
@end example

Note that if you created the file on Windows with an editor that uses
@code{\r\n} as a line terminator, you should use:

@example
mysql> LOAD DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet
    -> LINES TERMINATED BY '\r\n';
@end example

You can specify the column value separator and end of line marker explicitly
in the @code{LOAD DATA} statement if you wish, but the defaults are tab and
linefeed.  These are sufficient for the statement to read the file
@file{pet.txt} properly.

If the statement fails, it is likely that your MySQL installation does not
have local file capability enabled by default.  See
@ref{LOAD DATA LOCAL, , @code{LOAD DATA LOCAL}} for information on how to
change this.

When you want to add new records one at a time, the @code{INSERT} statement
is useful.  In its simplest form, you supply values for each column, in the
order in which the columns were listed in the @code{CREATE TABLE} statement.
Suppose that Diane gets a new hamster named Puffball.  You could add a new record
using an @code{INSERT} statement like this:

@example
mysql> INSERT INTO pet
    -> VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);
@end example

Note that string and date values are specified as quoted strings here.  Also,
with @code{INSERT}, you can insert @code{NULL} directly to represent a
missing value.  You do not use @code{\N} like you do with @code{LOAD DATA}.

From this example, you should be able to see that there would be a lot more
typing involved to load
your records initially using several @code{INSERT} statements rather
than a single @code{LOAD DATA} statement.


@node Retrieving data,  , Loading tables, Database use
@subsection Retrieving Information from a Table

@cindex data, retrieving
@cindex tables, retrieving data
@cindex retrieving, data from tables
@cindex unloading, tables

@menu
* Selecting all::               Selecting All Data
* Selecting rows::              Selecting Particular Rows
* Selecting columns::           Selecting Particular Columns
* Sorting rows::                Sorting Rows
* Date calculations::           Date Calculations
* Working with NULL::           Working with @code{NULL} Values
* Pattern matching::            Pattern Matching
* Counting rows::               Counting Rows
* Multiple tables::             Using More Than one Table
@end menu

The @code{SELECT} statement is used to pull information from a table.
The general form of the statement is:

@example
SELECT what_to_select
FROM which_table
WHERE conditions_to_satisfy;
@end example

@code{what_to_select} indicates what you want to see.  This can be a list of
columns, or @code{*} to indicate ``all columns.'' @code{which_table}
indicates the table from which you want to retrieve data.  The @code{WHERE}
clause is optional.  If it's present, @code{conditions_to_satisfy} specifies
conditions that rows must satisfy to qualify for retrieval.


@node Selecting all, Selecting rows, Retrieving data, Retrieving data
@subsubsection Selecting All Data

The simplest form of @code{SELECT} retrieves everything from a table:

@example
mysql> SELECT * FROM pet;
+----------+--------+---------+------+------------+------------+
| name     | owner  | species | sex  | birth      | death      |
+----------+--------+---------+------+------------+------------+
| Fluffy   | Harold | cat     | f    | 1993-02-04 | NULL       |
| Claws    | Gwen   | cat     | m    | 1994-03-17 | NULL       |
| Buffy    | Harold | dog     | f    | 1989-05-13 | NULL       |
| Fang     | Benny  | dog     | m    | 1990-08-27 | NULL       |
| Bowser   | Diane  | dog     | m    | 1979-08-31 | 1995-07-29 |
| Chirpy   | Gwen   | bird    | f    | 1998-09-11 | NULL       |
| Whistler | Gwen   | bird    | NULL | 1997-12-09 | NULL       |
| Slim     | Benny  | snake   | m    | 1996-04-29 | NULL       |
| Puffball | Diane  | hamster | f    | 1999-03-30 | NULL       |
+----------+--------+---------+------+------------+------------+
@end example

This form of @code{SELECT} is useful if you want to review your entire table,
for example, after you've just loaded it with your initial dataset.  For
example, you may happen to think that the birth date for Bowser doesn't seem
quite right.  Consulting your original pedigree
papers, you find that the correct birth year should be 1989, not 1979.

There are least a couple of ways to fix this:

@itemize @bullet
@item
Edit the file @file{pet.txt} to correct the error, then empty the table
and reload it using @code{DELETE} and @code{LOAD DATA}:

@example
@c I cannot determine what purpose messing with AUTOCOMMIT has in a simple
@c tutorial example like this; I've commented it out -- pd
@c mysql> SET AUTOCOMMIT=1;  # Used for quick re-create of the table
mysql> DELETE FROM pet;
mysql> LOAD DATA LOCAL INFILE 'pet.txt' INTO TABLE pet;
@end example

However, if you do this, you must also re-enter the record for Puffball.

@item
Fix only the erroneous record with an @code{UPDATE} statement:

@example
mysql> UPDATE pet SET birth = '1989-08-31' WHERE name = 'Bowser';
@end example

The @code{UPDATE} changes only the record in question and does not require you
to reload the table.
@end itemize


@node Selecting rows, Selecting columns, Selecting all, Retrieving data
@subsubsection Selecting Particular Rows

@cindex rows, selecting
@cindex tables, selecting rows

As shown in the preceding section, it is easy to retrieve an entire table.
Just omit the @code{WHERE} clause from the @code{SELECT} statement.
But typically you don't want
to see the entire table, particularly when it becomes large.  Instead,
you're usually more interested in answering a particular question, in which
case you specify some constraints on the information you want.  Let's look at
some selection queries in terms of questions about your pets that they
answer.

You can select only particular rows from your table.  For example, if you want
to verify the change that you made to Bowser's birth date, select Bowser's
record like this:

@example
mysql> SELECT * FROM pet WHERE name = 'Bowser';
+--------+-------+---------+------+------------+------------+
| name   | owner | species | sex  | birth      | death      |
+--------+-------+---------+------+------------+------------+
| Bowser | Diane | dog     | m    | 1989-08-31 | 1995-07-29 |
+--------+-------+---------+------+------------+------------+
@end example

The output confirms that the year is correctly recorded now as 1989, not 1979.

String comparisons normally are case-insensitive, so you can specify the
name as @code{'bowser'}, @code{'BOWSER'}, etc.  The query result will be
the same.

You can specify conditions on any column, not just @code{name}.  For example,
if you want to know which animals were born after 1998, test the @code{birth}
column:

@example
mysql> SELECT * FROM pet WHERE birth >= '1998-1-1';
+----------+-------+---------+------+------------+-------+
| name     | owner | species | sex  | birth      | death |
+----------+-------+---------+------+------------+-------+
| Chirpy   | Gwen  | bird    | f    | 1998-09-11 | NULL  |
| Puffball | Diane | hamster | f    | 1999-03-30 | NULL  |
+----------+-------+---------+------+------------+-------+
@end example

You can combine conditions, for example, to locate female dogs:

@example
mysql> SELECT * FROM pet WHERE species = 'dog' AND sex = 'f';
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+
@end example

The preceding query uses the @code{AND} logical operator.  There is also an
@code{OR} operator:

@example
mysql> SELECT * FROM pet WHERE species = 'snake' OR species = 'bird';
+----------+-------+---------+------+------------+-------+
| name     | owner | species | sex  | birth      | death |
+----------+-------+---------+------+------------+-------+
| Chirpy   | Gwen  | bird    | f    | 1998-09-11 | NULL  |
| Whistler | Gwen  | bird    | NULL | 1997-12-09 | NULL  |
| Slim     | Benny | snake   | m    | 1996-04-29 | NULL  |
+----------+-------+---------+------+------------+-------+
@end example

@code{AND} and @code{OR} may be intermixed, although @code{AND} has higher
precedence than @code{OR}.  If you use both operators, it's a good idea
to use parentheses to indicate explicitly how conditions should be grouped:

@example
mysql> SELECT * FROM pet WHERE (species = 'cat' AND sex = 'm')
    -> OR (species = 'dog' AND sex = 'f');
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+
@end example


@node Selecting columns, Sorting rows, Selecting rows, Retrieving data
@subsubsection Selecting Particular Columns

@cindex columns, selecting
@cindex tables, selecting columns

If you don't want to see entire rows from your table, just name the columns
in which you're interested, separated by commas.  For example, if you want to
know when your animals were born, select the @code{name} and @code{birth}
columns:

@example
mysql> SELECT name, birth FROM pet;
+----------+------------+
| name     | birth      |
+----------+------------+
| Fluffy   | 1993-02-04 |
| Claws    | 1994-03-17 |
| Buffy    | 1989-05-13 |
| Fang     | 1990-08-27 |
| Bowser   | 1989-08-31 |
| Chirpy   | 1998-09-11 |
| Whistler | 1997-12-09 |
| Slim     | 1996-04-29 |
| Puffball | 1999-03-30 |
+----------+------------+
@end example

To find out who owns pets, use this query:

@example
mysql> SELECT owner FROM pet;
+--------+
| owner  |
+--------+
| Harold |
| Gwen   |
| Harold |
| Benny  |
| Diane  |
| Gwen   |
| Gwen   |
| Benny  |
| Diane  |
+--------+
@end example

@findex DISTINCT
However, notice that the query simply retrieves the @code{owner} field from
each record, and some of them appear more than once.  To minimize the output,
retrieve each unique output record just once by adding the keyword
@code{DISTINCT}:

@example
mysql> SELECT DISTINCT owner FROM pet;
+--------+
| owner  |
+--------+
| Benny  |
| Diane  |
| Gwen   |
| Harold |
+--------+
@end example

You can use a @code{WHERE} clause to combine row selection with column
selection.  For example, to get birth dates for dogs and cats only,
use this query:

@example
mysql> SELECT name, species, birth FROM pet
    -> WHERE species = 'dog' OR species = 'cat';
+--------+---------+------------+
| name   | species | birth      |
+--------+---------+------------+
| Fluffy | cat     | 1993-02-04 |
| Claws  | cat     | 1994-03-17 |
| Buffy  | dog     | 1989-05-13 |
| Fang   | dog     | 1990-08-27 |
| Bowser | dog     | 1989-08-31 |
+--------+---------+------------+
@end example


@node Sorting rows, Date calculations, Selecting columns, Retrieving data
@subsubsection Sorting Rows

@findex ORDER BY
@cindex rows, sorting
@cindex sorting, table rows
@cindex sorting, data
@cindex tables, sorting rows

You may have noticed in the preceding examples that the result rows are
displayed in no particular order.  It's often easier to examine
query output when the rows are sorted in some meaningful way.  To sort a
result, use an @code{ORDER BY} clause.

Here are animal birthdays, sorted by date:

@example
mysql> SELECT name, birth FROM pet ORDER BY birth;
+----------+------------+
| name     | birth      |
+----------+------------+
| Buffy    | 1989-05-13 |
| Bowser   | 1989-08-31 |
| Fang     | 1990-08-27 |
| Fluffy   | 1993-02-04 |
| Claws    | 1994-03-17 |
| Slim     | 1996-04-29 |
| Whistler | 1997-12-09 |
| Chirpy   | 1998-09-11 |
| Puffball | 1999-03-30 |
+----------+------------+
@end example

On character type columns, sorting---like all other comparison
operations---is normally performed in a case-insensitive fashion.
This means that the order will be undefined for columns that are identical
except for their case. You can force a case-sensitive sort for a column
by using the @code{BINARY} cast: @code{ORDER BY BINARY col_name}.

The default sort order is ascending, with smallest values first.
To sort in reverse (descending) order, add the @code{DESC} keyword to the
name of the column you are sorting by:

@example
mysql> SELECT name, birth FROM pet ORDER BY birth DESC;
+----------+------------+
| name     | birth      |
+----------+------------+
| Puffball | 1999-03-30 |
| Chirpy   | 1998-09-11 |
| Whistler | 1997-12-09 |
| Slim     | 1996-04-29 |
| Claws    | 1994-03-17 |
| Fluffy   | 1993-02-04 |
| Fang     | 1990-08-27 |
| Bowser   | 1989-08-31 |
| Buffy    | 1989-05-13 |
+----------+------------+
@end example

You can sort on multiple columns, and you can sort columns in different
directions.  For example, to sort by type of
animal in ascending order, then by birth date within animal type in descending
order (youngest animals first), use the following query:

@example
mysql> SELECT name, species, birth FROM pet
    -> ORDER BY species, birth DESC;
+----------+---------+------------+
| name     | species | birth      |
+----------+---------+------------+
| Chirpy   | bird    | 1998-09-11 |
| Whistler | bird    | 1997-12-09 |
| Claws    | cat     | 1994-03-17 |
| Fluffy   | cat     | 1993-02-04 |
| Fang     | dog     | 1990-08-27 |
| Bowser   | dog     | 1989-08-31 |
| Buffy    | dog     | 1989-05-13 |
| Puffball | hamster | 1999-03-30 |
| Slim     | snake   | 1996-04-29 |
+----------+---------+------------+
@end example

Note that the @code{DESC} keyword applies only to the column name immediately
preceding it (@code{birth}); it does not affect the @code{species} column sort
order.


@node Date calculations, Working with NULL, Sorting rows, Retrieving data
@subsubsection Date Calculations

@cindex date calculations
@cindex calculating, dates
@cindex extracting, dates
@cindex age, calculating

MySQL provides several functions that you can use to perform
calculations on dates, for example, to calculate ages or extract
parts of dates.

To determine how many years old each of your pets is, compute the
difference in the year part of the current date and the birth date, then
subtract one if the current date occurs earlier in the calendar year than
the birth date.  The following query shows, for each pet, the birth date,
the current date, and the age in years.

@example
mysql> SELECT name, birth, CURDATE(),
    -> (YEAR(CURDATE())-YEAR(birth))
    -> - (RIGHT(CURDATE(),5)<RIGHT(birth,5))
    -> AS age
    -> FROM pet;
+----------+------------+------------+------+
| name     | birth      | CURDATE()  | age  |
+----------+------------+------------+------+
| Fluffy   | 1993-02-04 | 2003-08-19 |   10 |
| Claws    | 1994-03-17 | 2003-08-19 |    9 |
| Buffy    | 1989-05-13 | 2003-08-19 |   14 |
| Fang     | 1990-08-27 | 2003-08-19 |   12 |
| Bowser   | 1989-08-31 | 2003-08-19 |   13 |
| Chirpy   | 1998-09-11 | 2003-08-19 |    4 |
| Whistler | 1997-12-09 | 2003-08-19 |    5 |
| Slim     | 1996-04-29 | 2003-08-19 |    7 |
| Puffball | 1999-03-30 | 2003-08-19 |    4 |
+----------+------------+------------+------+
@end example

Here, @code{YEAR()} pulls out the year part of a date and @code{RIGHT()}
pulls off the rightmost five characters that represent the @code{MM-DD}
(calendar year) part of the date.  The part of the expression that
compares the @code{MM-DD} values evaluates to 1 or 0, which adjusts the
year difference down a year if @code{CURDATE()} occurs earlier in
the year than @code{birth}.  The full expression is somewhat ungainly,
so an alias (@code{age}) is used to make the output column label more
meaningful.

The query works, but the result could be scanned more easily if the rows
were presented in some order.  This can be done by adding an @code{ORDER
BY name} clause to sort the output by name:

@example
mysql> SELECT name, birth, CURDATE(),
    -> (YEAR(CURDATE())-YEAR(birth))
    -> - (RIGHT(CURDATE(),5)<RIGHT(birth,5))
    -> AS age
    -> FROM pet ORDER BY name;
+----------+------------+------------+------+
| name     | birth      | CURDATE()  | age  |
+----------+------------+------------+------+
| Bowser   | 1989-08-31 | 2003-08-19 |   13 |
| Buffy    | 1989-05-13 | 2003-08-19 |   14 |
| Chirpy   | 1998-09-11 | 2003-08-19 |    4 |
| Claws    | 1994-03-17 | 2003-08-19 |    9 |
| Fang     | 1990-08-27 | 2003-08-19 |   12 |
| Fluffy   | 1993-02-04 | 2003-08-19 |   10 |
| Puffball | 1999-03-30 | 2003-08-19 |    4 |
| Slim     | 1996-04-29 | 2003-08-19 |    7 |
| Whistler | 1997-12-09 | 2003-08-19 |    5 |
+----------+------------+------------+------+
@end example

To sort the output by @code{age} rather than @code{name}, just use a
different @code{ORDER BY} clause:

@example
mysql> SELECT name, birth, CURDATE(),
    -> (YEAR(CURDATE())-YEAR(birth))
    -> - (RIGHT(CURDATE(),5)<RIGHT(birth,5))
    -> AS age
    -> FROM pet ORDER BY age;
+----------+------------+------------+------+
| name     | birth      | CURDATE()  | age  |
+----------+------------+------------+------+
| Chirpy   | 1998-09-11 | 2003-08-19 |    4 |
| Puffball | 1999-03-30 | 2003-08-19 |    4 |
| Whistler | 1997-12-09 | 2003-08-19 |    5 |
| Slim     | 1996-04-29 | 2003-08-19 |    7 |
| Claws    | 1994-03-17 | 2003-08-19 |    9 |
| Fluffy   | 1993-02-04 | 2003-08-19 |   10 |
| Fang     | 1990-08-27 | 2003-08-19 |   12 |
| Bowser   | 1989-08-31 | 2003-08-19 |   13 |
| Buffy    | 1989-05-13 | 2003-08-19 |   14 |
+----------+------------+------------+------+
@end example

A similar query can be used to determine age at death for animals that have
died.  You determine which animals these are by checking whether the
@code{death} value is @code{NULL}.  Then, for those with non-@code{NULL}
values, compute the difference between the @code{death} and @code{birth}
values:

@example
mysql> SELECT name, birth, death,
    -> (YEAR(death)-YEAR(birth)) - (RIGHT(death,5)<RIGHT(birth,5))
    -> AS age
    -> FROM pet WHERE death IS NOT NULL ORDER BY age;
+--------+------------+------------+------+
| name   | birth      | death      | age  |
+--------+------------+------------+------+
| Bowser | 1989-08-31 | 1995-07-29 |    5 |
+--------+------------+------------+------+
@end example

The query uses @code{death IS NOT NULL} rather than @code{death <> NULL}
because @code{NULL} is a special value that cannot be compared using the usual
comparison operators.  This is discussed later.
@xref{Working with NULL,  , Working with @code{NULL}}.

What if you want to know which animals have birthdays next month?  For this
type of calculation, year and day are irrelevant; you simply want to extract
the month part of the @code{birth} column.  MySQL provides several
date-part extraction functions, such as @code{YEAR()}, @code{MONTH()}, and
@code{DAYOFMONTH()}.  @code{MONTH()} is the appropriate function here.  To
see how it works, run a simple query that displays the value of both
@code{birth} and @code{MONTH(birth)}:

@example
mysql> SELECT name, birth, MONTH(birth) FROM pet;
+----------+------------+--------------+
| name     | birth      | MONTH(birth) |
+----------+------------+--------------+
| Fluffy   | 1993-02-04 |            2 |
| Claws    | 1994-03-17 |            3 |
| Buffy    | 1989-05-13 |            5 |
| Fang     | 1990-08-27 |            8 |
| Bowser   | 1989-08-31 |            8 |
| Chirpy   | 1998-09-11 |            9 |
| Whistler | 1997-12-09 |           12 |
| Slim     | 1996-04-29 |            4 |
| Puffball | 1999-03-30 |            3 |
+----------+------------+--------------+
@end example

Finding animals with birthdays in the upcoming month is easy, too.  Suppose
that the current month is April.  Then the month value is @code{4} and you look
for animals born in May (month @code{5}) like this:

@example
mysql> SELECT name, birth FROM pet WHERE MONTH(birth) = 5;
+-------+------------+
| name  | birth      |
+-------+------------+
| Buffy | 1989-05-13 |
+-------+------------+
@end example

There is a small complication if the current month is December.
You don't just add one to the month number (@code{12}) and look for animals
born in month @code{13}, because there is no such month.  Instead, you look for
animals born in January (month @code{1}).

You can even write the query so that it works no matter what the current
month is.  That way you don't have to use a particular month number
in the query.  @code{DATE_ADD()} allows you to add a time interval to a
given date.  If you add a month to the value of @code{CURDATE()}, then extract
the month part with @code{MONTH()}, the result produces the month in which to
look for birthdays:

@example
mysql> SELECT name, birth FROM pet
    -> WHERE MONTH(birth) = MONTH(DATE_ADD(CURDATE(),INTERVAL 1 MONTH));
@end example

A different way to accomplish the same task is to add @code{1} to get the
next month after the current one (after using the modulo function (@code{MOD})
to wrap around the month value to @code{0} if it is currently
@code{12}):

@example
mysql> SELECT name, birth FROM pet
    -> WHERE MONTH(birth) = MOD(MONTH(CURDATE()), 12) + 1;
@end example

Note that @code{MONTH} returns a number between @code{1} and @code{12}. And
@code{MOD(something,12)} returns a number between @code{0} and @code{11}. So the
addition has to be after the @code{MOD()}, otherwise we would go from
November (@code{11}) to January (@code{1}).


@node Working with NULL, Pattern matching, Date calculations, Retrieving data
@subsubsection Working with @code{NULL} Values

@findex NULL
@cindex NULL value

The @code{NULL} value can be surprising until you get used to it.
Conceptually, @code{NULL} means missing value or unknown value and it
is treated somewhat differently than other values.  To test for @code{NULL},
you cannot use the arithmetic comparison operators such as @code{=}, @code{<},
or @code{<>}.  To demonstrate this for yourself, try the following query:

@example
mysql> SELECT 1 = NULL, 1 <> NULL, 1 < NULL, 1 > NULL;
+----------+-----------+----------+----------+
| 1 = NULL | 1 <> NULL | 1 < NULL | 1 > NULL |
+----------+-----------+----------+----------+
|     NULL |      NULL |     NULL |     NULL |
+----------+-----------+----------+----------+
@end example

Clearly you get no meaningful results from these comparisons.  Use
the @code{IS NULL} and @code{IS NOT NULL} operators instead:

@example
mysql> SELECT 1 IS NULL, 1 IS NOT NULL;
+-----------+---------------+
| 1 IS NULL | 1 IS NOT NULL |
+-----------+---------------+
|         0 |             1 |
+-----------+---------------+
@end example

Note that in MySQL, @code{0} or @code{NULL} means false and anything else means
true. The default truth value from a boolean operation is @code{1}.

This special treatment of @code{NULL} is why, in the previous section, it
was necessary to determine which animals are no longer alive using
@code{death IS NOT NULL} instead of @code{death <> NULL}.

Two @code{NULL} values are regarded as equal in a @code{GROUP BY}.

When doing an @code{ORDER BY}, @code{NULL} values are presented first if you
do @code{ORDER BY ... ASC} and last if you do @code{ORDER BY ... DESC}.

Note that MySQL 4.0.2 to 4.0.10 incorrectly always sorts @code{NULL} values
first regardless of the sort direction.


@node Pattern matching, Counting rows, Working with NULL, Retrieving data
@subsubsection Pattern Matching

@cindex pattern matching
@cindex matching, patterns
@cindex expressions, extended

MySQL provides standard SQL pattern matching as well as a form of
pattern matching based on extended regular expressions similar to those used
by Unix utilities such as @code{vi}, @code{grep}, and @code{sed}.

SQL pattern matching allows you to use @samp{_} to match any single
character and @samp{%} to match an arbitrary number of characters (including
zero characters).  In MySQL, SQL patterns are case-insensitive by
default.  Some examples are shown here.  Note that you do not use @code{=}
or @code{<>} when you use SQL patterns; use the @code{LIKE} or @code{NOT
LIKE} comparison operators instead.

To find names beginning with @samp{b}:

@example
mysql> SELECT * FROM pet WHERE name LIKE 'b%';
+--------+--------+---------+------+------------+------------+
| name   | owner  | species | sex  | birth      | death      |
+--------+--------+---------+------+------------+------------+
| Buffy  | Harold | dog     | f    | 1989-05-13 | NULL       |
| Bowser | Diane  | dog     | m    | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+
@end example

To find names ending with @samp{fy}:

@example
mysql> SELECT * FROM pet WHERE name LIKE '%fy';
+--------+--------+---------+------+------------+-------+
| name   | owner  | species | sex  | birth      | death |
+--------+--------+---------+------+------------+-------+
| Fluffy | Harold | cat     | f    | 1993-02-04 | NULL  |
| Buffy  | Harold | dog     | f    | 1989-05-13 | NULL  |
+--------+--------+---------+------+------------+-------+
@end example

To find names containing a @samp{w}:

@example
mysql> SELECT * FROM pet WHERE name LIKE '%w%';
+----------+-------+---------+------+------------+------------+
| name     | owner | species | sex  | birth      | death      |
+----------+-------+---------+------+------------+------------+
| Claws    | Gwen  | cat     | m    | 1994-03-17 | NULL       |
| Bowser   | Diane | dog     | m    | 1989-08-31 | 1995-07-29 |
| Whistler | Gwen  | bird    | NULL | 1997-12-09 | NULL       |
+----------+-------+---------+------+------------+------------+
@end example

To find names containing exactly five characters, use five instances of
the @samp{_} pattern character:

@example
mysql> SELECT * FROM pet WHERE name LIKE '_____';
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+
@end example

The other type of pattern matching provided by MySQL uses extended
regular expressions.  When you test for a match for this type of pattern, use
the @code{REGEXP} and @code{NOT REGEXP} operators (or @code{RLIKE} and
@code{NOT RLIKE}, which are synonyms).

Some characteristics of extended regular expressions are:

@itemize @bullet
@item
@samp{.} matches any single character.

@item
A character class @samp{[...]} matches any character within the brackets.
For example, @samp{[abc]} matches @samp{a}, @samp{b}, or @samp{c}.  To name a
range of characters, use a dash.  @samp{[a-z]} matches any letter,
whereas @samp{[0-9]} matches any digit.

@item
@samp{*} matches zero or more instances of the thing preceding it.  For
example, @samp{x*} matches any number of @samp{x} characters,
@samp{[0-9]*} matches any number of digits, and @samp{.*} matches any
number of anything.

@item
A @code{REGEXP} pattern match succeed if
the pattern matches anywhere in the value being tested.
(This differs from a @code{LIKE} pattern match, which succeeds only if the
pattern matches the entire value.)

@item
To anchor a pattern so that it must match the beginning or end of the value
being tested, use @samp{^} at the beginning or @samp{$} at the end of the
pattern.
@end itemize

To demonstrate how extended regular expressions work, the @code{LIKE} queries
shown previously are rewritten here to use @code{REGEXP}.

To find names beginning with @samp{b}, use @samp{^} to match the beginning of
the name:

@example
mysql> SELECT * FROM pet WHERE name REGEXP '^b';
+--------+--------+---------+------+------------+------------+
| name   | owner  | species | sex  | birth      | death      |
+--------+--------+---------+------+------------+------------+
| Buffy  | Harold | dog     | f    | 1989-05-13 | NULL       |
| Bowser | Diane  | dog     | m    | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+
@end example

Prior to MySQL Version 3.23.4, @code{REGEXP} is case sensitive,
and the previous query will return no rows. In this case, to match either
lowercase or uppercase @samp{b}, use this query instead:

@example
mysql> SELECT * FROM pet WHERE name REGEXP '^[bB]';
@end example

From MySQL 3.23.4 on, if you really want to force a @code{REGEXP} comparison to
be case sensitive, use the @code{BINARY} keyword to make one of the
strings a binary string. This query will match only lowercase @samp{b}
at the beginning of a name:

@example
mysql> SELECT * FROM pet WHERE name REGEXP BINARY '^b';
@end example

To find names ending with @samp{fy}, use @samp{$} to match the end of the
name:

@example
mysql> SELECT * FROM pet WHERE name REGEXP 'fy$';
+--------+--------+---------+------+------------+-------+
| name   | owner  | species | sex  | birth      | death |
+--------+--------+---------+------+------------+-------+
| Fluffy | Harold | cat     | f    | 1993-02-04 | NULL  |
| Buffy  | Harold | dog     | f    | 1989-05-13 | NULL  |
+--------+--------+---------+------+------------+-------+
@end example

To find names containing a @samp{w}, use this query:

@example
mysql> SELECT * FROM pet WHERE name REGEXP 'w';
+----------+-------+---------+------+------------+------------+
| name     | owner | species | sex  | birth      | death      |
+----------+-------+---------+------+------------+------------+
| Claws    | Gwen  | cat     | m    | 1994-03-17 | NULL       |
| Bowser   | Diane | dog     | m    | 1989-08-31 | 1995-07-29 |
| Whistler | Gwen  | bird    | NULL | 1997-12-09 | NULL       |
+----------+-------+---------+------+------------+------------+
@end example

Because a regular expression pattern matches if it occurs anywhere in the
value, it is not necessary in the previous query to put a wildcard on either
side of the pattern to get it to match the entire value like it would be if
you used an SQL pattern.

To find names containing exactly five characters, use @samp{^} and @samp{$}
to match the beginning and end of the name, and five instances of @samp{.}
in between:

@example
mysql> SELECT * FROM pet WHERE name REGEXP '^.....$';
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+
@end example

You could also write the previous query using the @samp{@{n@}}
``repeat-@code{n}-times'' operator:

@example
mysql> SELECT * FROM pet WHERE name REGEXP '^.@{5@}$';
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+
@end example


@node Counting rows, Multiple tables, Pattern matching, Retrieving data
@subsubsection Counting Rows

@cindex rows, counting
@cindex tables, counting rows
@cindex counting, table rows

Databases are often used to answer the question, ``How often does a certain
type of data occur in a table?''  For example, you might want to know how
many pets you have, or how many pets each owner has, or you might want to
perform various kinds of census operations on your animals.

Counting the total number of animals you have is the same question as ``How
many rows are in the @code{pet} table?'' because there is one record per pet.
@code{COUNT(*)} counts the number of rows, so
the query to count your animals looks like this:

@example
mysql> SELECT COUNT(*) FROM pet;
+----------+
| COUNT(*) |
+----------+
|        9 |
+----------+
@end example

Earlier, you retrieved the names of the people who owned pets.  You can
use @code{COUNT()} if you want to find out how many pets each owner has:

@example
mysql> SELECT owner, COUNT(*) FROM pet GROUP BY owner;
+--------+----------+
| owner  | COUNT(*) |
+--------+----------+
| Benny  |        2 |
| Diane  |        2 |
| Gwen   |        3 |
| Harold |        2 |
+--------+----------+
@end example

Note the use of @code{GROUP BY} to group together all records for each
@code{owner}.  Without it, all you get is an error message:

@example
mysql> SELECT owner, COUNT(*) FROM pet;
ERROR 1140: Mixing of GROUP columns (MIN(),MAX(),COUNT()...)
with no GROUP columns is illegal if there is no GROUP BY clause
@end example

@code{COUNT()} and @code{GROUP BY} are useful for characterizing your
data in various ways.  The following examples show different ways to
perform animal census operations.

Number of animals per species:

@example
mysql> SELECT species, COUNT(*) FROM pet GROUP BY species;
+---------+----------+
| species | COUNT(*) |
+---------+----------+
| bird    |        2 |
| cat     |        2 |
| dog     |        3 |
| hamster |        1 |
| snake   |        1 |
+---------+----------+
@end example

Number of animals per sex:

@example
mysql> SELECT sex, COUNT(*) FROM pet GROUP BY sex;
+------+----------+
| sex  | COUNT(*) |
+------+----------+
| NULL |        1 |
| f    |        4 |
| m    |        4 |
+------+----------+
@end example

(In this output, @code{NULL} indicates that the sex is unknown.)

Number of animals per combination of species and sex:

@example
mysql> SELECT species, sex, COUNT(*) FROM pet GROUP BY species, sex;
+---------+------+----------+
| species | sex  | COUNT(*) |
+---------+------+----------+
| bird    | NULL |        1 |
| bird    | f    |        1 |
| cat     | f    |        1 |
| cat     | m    |        1 |
| dog     | f    |        1 |
| dog     | m    |        2 |
| hamster | f    |        1 |
| snake   | m    |        1 |
+---------+------+----------+
@end example

You need not retrieve an entire table when you use @code{COUNT()}.  For
example, the previous query, when performed just on dogs and cats, looks like
this:

@example
mysql> SELECT species, sex, COUNT(*) FROM pet
    -> WHERE species = 'dog' OR species = 'cat'
    -> GROUP BY species, sex;
+---------+------+----------+
| species | sex  | COUNT(*) |
+---------+------+----------+
| cat     | f    |        1 |
| cat     | m    |        1 |
| dog     | f    |        1 |
| dog     | m    |        2 |
+---------+------+----------+
@end example

Or, if you wanted the number of animals per sex only for known-sex animals:

@example
mysql> SELECT species, sex, COUNT(*) FROM pet
    -> WHERE sex IS NOT NULL
    -> GROUP BY species, sex;
+---------+------+----------+
| species | sex  | COUNT(*) |
+---------+------+----------+
| bird    | f    |        1 |
| cat     | f    |        1 |
| cat     | m    |        1 |
| dog     | f    |        1 |
| dog     | m    |        2 |
| hamster | f    |        1 |
| snake   | m    |        1 |
+---------+------+----------+
@end example


@node Multiple tables,  , Counting rows, Retrieving data
@subsubsection Using More Than one Table

@cindex tables, multiple

The @code{pet} table keeps track of which pets you have.  If you want to
record other information about them, such as events in their lives like
visits to the vet or when litters are born, you need another table.  What
should this table look like? It needs:

@itemize @bullet
@item
To contain the pet name so you know which animal each event pertains
to.

@item
A date so you know when the event occurred.

@item
A field to describe the event.

@item
An event type field, if you want to be able to categorize events.
@end itemize

Given these considerations, the @code{CREATE TABLE} statement for the
@code{event} table might look like this:

@example
mysql> CREATE TABLE event (name VARCHAR(20), date DATE,
    -> type VARCHAR(15), remark VARCHAR(255));
@end example

As with the @code{pet} table, it's easiest to load the initial records
by creating a tab-delimited text file containing the information:

@multitable @columnfractions .15 .15 .15 .35
@item @strong{name} @tab @strong{date} @tab @strong{type} @tab @strong{remark}
@item Fluffy @tab 1995-05-15 @tab litter @tab 4 kittens, 3 female, 1 male
@item Buffy @tab 1993-06-23 @tab litter @tab 5 puppies, 2 female, 3 male
@item Buffy @tab 1994-06-19 @tab litter @tab 3 puppies, 3 female
@item Chirpy @tab 1999-03-21 @tab vet @tab needed beak straightened
@item Slim @tab 1997-08-03 @tab vet @tab broken rib
@item Bowser @tab 1991-10-12 @tab kennel @tab
@item Fang @tab 1991-10-12 @tab kennel @tab
@item Fang @tab 1998-08-28 @tab birthday @tab Gave him a new chew toy
@item Claws @tab 1998-03-17 @tab birthday @tab Gave him a new flea collar
@item Whistler @tab 1998-12-09 @tab birthday @tab First birthday
@end multitable

Load the records like this:

@example
mysql> LOAD DATA LOCAL INFILE 'event.txt' INTO TABLE event;
@end example

Based on what you've learned from the queries you've run on the @code{pet}
table, you should be able to perform retrievals on the records in the
@code{event} table; the principles are the same.  But when is the
@code{event} table by itself insufficient to answer questions you might ask?

Suppose that you want to find out the ages at which each pet had its
litters. We saw earlier how to calculate ages from two dates.
The litter date of the mother is in the
@code{event} table, but to calculate her age on that date you need her
birth date, which is stored in the @code{pet} table.
This means the query requires both tables:

@example
mysql> SELECT pet.name,
    -> (YEAR(date)-YEAR(birth)) - (RIGHT(date,5)<RIGHT(birth,5)) AS age,
    -> remark
    -> FROM pet, event
    -> WHERE pet.name = event.name AND type = 'litter';
+--------+------+-----------------------------+
| name   | age  | remark                      |
+--------+------+-----------------------------+
| Fluffy |    2 | 4 kittens, 3 female, 1 male |
| Buffy  |    4 | 5 puppies, 2 female, 3 male |
| Buffy  |    5 | 3 puppies, 3 female         |
+--------+------+-----------------------------+
@end example

There are several things to note about this query:

@itemize @bullet
@item
The @code{FROM} clause lists two tables because the query needs to pull
information from both of them.

@item
When combining (joining) information from multiple tables, you need to
specify how records in one table can be matched to records in the other.
This is easy because they both have a @code{name} column.  The query uses
@code{WHERE} clause to match up records in the two tables based on the
@code{name} values.

@item
Because the @code{name} column occurs in both tables, you must be specific
about which table you mean when referring to the column.  This is done
by prepending the table name to the column name.
@end itemize

You need not have two different tables to perform a join.  Sometimes it is
useful to join a table to itself, if you want to compare records in a table
to other records in that same table.  For example, to find breeding pairs
among your pets, you can join the @code{pet} table with itself to produce
candidate pairs of males and females of like species:

@example
mysql> SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species
    -> FROM pet AS p1, pet AS p2
    -> WHERE p1.species = p2.species AND p1.sex = 'f' AND p2.sex = 'm';
+--------+------+--------+------+---------+
| name   | sex  | name   | sex  | species |
+--------+------+--------+------+---------+
| Fluffy | f    | Claws  | m    | cat     |
| Buffy  | f    | Fang   | m    | dog     |
| Buffy  | f    | Bowser | m    | dog     |
+--------+------+--------+------+---------+
@end example

In this query, we specify aliases for the table name in order
to refer to the columns and keep straight which instance of the table
each column reference is associated with.


@node Getting information, Batch mode, Database use, Tutorial
@section Getting Information About Databases and Tables

@cindex databases, information about
@cindex tables, information about
@findex DESCRIBE

What if you forget the name of a database or table, or what the structure of
a given table is (for example, what its columns are called)?  MySQL
addresses this problem through several statements that provide information
about the databases and tables it supports.

You have already seen @code{SHOW DATABASES}, which lists the databases
managed by the server.  To find out which database is currently selected,
use the @code{DATABASE()} function:

@example
mysql> SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| menagerie  |
+------------+
@end example

If you haven't selected any database yet, the result is @code{NULL}
(or the empty string before MySQL 4.1.1).

To find out what tables the current database contains (for example, when
you're not sure about the name of a table), use this command:

@example
mysql> SHOW TABLES;
+---------------------+
| Tables in menagerie |
+---------------------+
| event               |
| pet                 |
+---------------------+
@end example

If you want to find out about the structure of a table, the @code{DESCRIBE}
command is useful; it displays information about each of a table's columns:

@example
mysql> DESCRIBE pet;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| name    | varchar(20) | YES  |     | NULL    |       |
| owner   | varchar(20) | YES  |     | NULL    |       |
| species | varchar(20) | YES  |     | NULL    |       |
| sex     | char(1)     | YES  |     | NULL    |       |
| birth   | date        | YES  |     | NULL    |       |
| death   | date        | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+
@end example

@code{Field} indicates the column name, @code{Type} is the data type for
the column, @code{NULL} indicates whether the column can contain
@code{NULL} values, @code{Key} indicates whether the column is
indexed, and @code{Default} specifies the column's default value.

If you have indexes on a table,
@code{SHOW INDEX FROM @var{tbl_name}} produces information about them.


@node Batch mode, Examples, Getting information, Tutorial
@section Using @command{mysql} in Batch Mode

@cindex modes, batch
@cindex batch mode
@cindex running, batch mode
@cindex script files
@cindex files, script

In the previous sections, you used @command{mysql} interactively to enter
queries and view the results.  You can also run @command{mysql} in batch
mode.  To do this, put the commands you want to run in a file, then
tell @command{mysql} to read its input from the file:

@example
shell> mysql < @var{batch-file}
@end example

If you are running @command{mysql} under Windows and have some special
characters in the file that cause problems, you can do this:

@example
C:\> mysql -e "source @var{batch-file}"
@end example

If you need to specify connection parameters on the command line, the
command might look like this:

@example
shell> mysql -h @var{host} -u @var{user} -p < @var{batch-file}
Enter password: ********
@end example

When you use @command{mysql} this way, you are creating a script file, then
executing the script.

If you want the script to continue even if some of the statements in it
produce errors, you should
use the @code{--force} command-line option.

Why use a script?  Here are a few reasons:

@itemize @bullet
@item
If you run a query repeatedly (say, every day or every week), making it a
script allows you to avoid retyping it each time you execute it.

@item
You can generate new queries from existing ones that are similar by copying
and editing script files.

@item
Batch mode can also be useful while you're developing a query, particularly
for multiple-line commands or multiple-statement sequences of commands.  If
you make a mistake, you don't have to retype everything.  Just edit your
script to correct the error, then tell @command{mysql} to execute it again.

@item
If you have a query that produces a lot of output, you can run the output
through a pager rather than watching it scroll off the top of your screen:

@example
shell> mysql < @var{batch-file} | more
@end example

@item
You can catch the output in a file for further processing:

@example
shell> mysql < @var{batch-file} > mysql.out
@end example

@item
You can distribute your script to other people so they can run the commands,
too.

@item
Some situations do not allow for interactive use, for example, when you run
a query from a @command{cron} job.  In this case, you must use batch mode.
@end itemize

The default output format is different (more concise) when you run
@command{mysql} in batch mode than when you use it interactively.  For
example, the output of @code{SELECT DISTINCT species FROM pet} looks like
this when @command{mysql} is run interactively:

@example
+---------+
| species |
+---------+
| bird    |
| cat     |
| dog     |
| hamster |
| snake   |
+---------+
@end example

In batch mode, the output looks like this instead:

@example
species
bird
cat
dog
hamster
snake
@end example

If you want to get the interactive output format in batch mode, use
@code{mysql -t}.  To echo to the output the commands that are executed, use
@code{mysql -vvv}.

You can also use scripts from the @command{mysql} prompt by
using the @code{source} or @code{\.} command:

@example
mysql> source filename;
mysql> \. filename
@end example


@node Examples, Twin, Batch mode, Tutorial
@section Examples of Common Queries

@cindex queries, examples
@cindex examples, queries

Here are examples of how to solve some common problems with
MySQL.

Some of the examples use the table @code{shop} to hold the price of each
article (item number) for certain traders (dealers).  Supposing that each
trader has a single fixed price per article, then (@code{article},
@code{dealer}) is a primary key for the records.

Start the command-line tool @command{mysql} and select a database:

@example
shell> mysql your-database-name
@end example

(In most MySQL installations, you can use the database name @code{test}).

You can create and populate the example table with these statements:

@example
mysql> CREATE TABLE shop (
    -> article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
    -> dealer  CHAR(20)                 DEFAULT ''     NOT NULL,
    -> price   DOUBLE(16,2)             DEFAULT '0.00' NOT NULL,
    -> PRIMARY KEY(article, dealer));
mysql> INSERT INTO shop VALUES
    -> (1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),
    -> (3,'C',1.69),(3,'D',1.25),(4,'D',19.95);
@end example

After issuing the statements, the table should have the following contents:

@example
mysql> SELECT * FROM shop;
+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
|    0001 | A      |  3.45 |
|    0001 | B      |  3.99 |
|    0002 | A      | 10.99 |
|    0003 | B      |  1.45 |
|    0003 | C      |  1.69 |
|    0003 | D      |  1.25 |
|    0004 | D      | 19.95 |
+---------+--------+-------+
@end example

@menu
* example-Maximum-column::      The Maximum Value for a Column
* example-Maximum-row::         The Row Holding the Maximum of a Certain Column
* example-Maximum-column-group::  Maximum of Column per Group
* example-Maximum-column-group-row::  The Rows Holding the Group-wise Maximum of a Certain Field
* example-user-variables::      Using User Variables
* example-Foreign keys::        Using Foreign Keys
* Searching on two keys::       Searching on Two Keys
* Calculating days::            Calculating Visits Per Day
* example-AUTO_INCREMENT::      Using @code{AUTO_INCREMENT}
@end menu


@node example-Maximum-column, example-Maximum-row, Examples, Examples
@subsection The Maximum Value for a Column

``What's the highest item number?''

@example
SELECT MAX(article) AS article FROM shop;

+---------+
| article |
+---------+
|       4 |
+---------+
@end example


@node example-Maximum-row, example-Maximum-column-group, example-Maximum-column, Examples
@subsection The Row Holding the Maximum of a Certain Column

``Find number, dealer, and price of the most expensive article.''

In standard SQL (and as of MySQL 4.1), this is easily done with a subquery:

@example
SELECT article, dealer, price
FROM   shop
WHERE  price=(SELECT MAX(price) FROM shop);
@end example

In MySQL versions prior to 4.1, just do it in two steps:

@enumerate
@item
Get the maximum price value from the table with a @code{SELECT} statement.
@example
mysql> SELECT MAX(price) FROM shop;
+------------+
| MAX(price) |
+------------+
|      19.95 |
+------------+
@end example
@item
Using the value 19.95 shown by the previous query to be the maximum
article price, write a query to locate and display the corresponding record:
@example
mysql> SELECT article, dealer, price
    -> FROM   shop
    -> WHERE  price=19.95;
+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
|    0004 | D      | 19.95 |
+---------+--------+-------+
@end example
@end enumerate

Another solution is to sort all rows descending by price and only
get the first row using the MySQL-specific @code{LIMIT} clause:

@example
SELECT article, dealer, price
FROM   shop
ORDER BY price DESC
LIMIT 1;
@end example

Note:  If there were several most expensive articles, each with a
price of 19.95, the @code{LIMIT} solution would show only one of them!


@node example-Maximum-column-group, example-Maximum-column-group-row, example-Maximum-row, Examples
@subsection Maximum of Column per Group

``What's the highest price per article?''

@example
SELECT article, MAX(price) AS price
FROM   shop
GROUP BY article

+---------+-------+
| article | price |
+---------+-------+
|    0001 |  3.99 |
|    0002 | 10.99 |
|    0003 |  1.69 |
|    0004 | 19.95 |
+---------+-------+
@end example


@node example-Maximum-column-group-row, example-user-variables, example-Maximum-column-group, Examples
@subsection The Rows Holding the Group-wise Maximum of a Certain Field

``For each article, find the dealer or dealers with the most expensive price.''

In standard SQL (and as of MySQL 4.1), the problem can be solved
with a subquery like this:

@example
SELECT article, dealer, price
FROM   shop s1
WHERE  price=(SELECT MAX(s2.price)
              FROM shop s2
              WHERE s1.article = s2.article);
@end example

In MySQL versions prior to 4.1, it's best do it in several steps:

@enumerate
@item
Get the list of (article,maxprice) pairs.
@item
For each article, get the corresponding rows that have the stored maximum
price.
@end enumerate

This can easily be done with a temporary table and a join:

@example
CREATE TEMPORARY TABLE tmp (
        article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
        price   DOUBLE(16,2)             DEFAULT '0.00' NOT NULL);

LOCK TABLES shop READ;

INSERT INTO tmp SELECT article, MAX(price) FROM shop GROUP BY article;

SELECT shop.article, dealer, shop.price FROM shop, tmp
WHERE shop.article=tmp.article AND shop.price=tmp.price;

UNLOCK TABLES;

DROP TABLE tmp;
@end example

If you don't use a @code{TEMPORARY} table, you must also lock the @code{tmp}
table.

``Can it be done with a single query?''

Yes, but only by using a quite inefficient trick called the
``MAX-CONCAT trick'':

@example
SELECT article,
       SUBSTRING( MAX( CONCAT(LPAD(price,6,'0'),dealer) ), 7) AS dealer,
  0.00+LEFT(      MAX( CONCAT(LPAD(price,6,'0'),dealer) ), 6) AS price
FROM   shop
GROUP BY article;

+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
|    0001 | B      |  3.99 |
|    0002 | A      | 10.99 |
|    0003 | C      |  1.69 |
|    0004 | D      | 19.95 |
+---------+--------+-------+
@end example

The last example can be made a bit more efficient by doing the
splitting of the concatenated column in the client.


@node example-user-variables, example-Foreign keys, example-Maximum-column-group-row, Examples
@subsection Using User Variables

You can use MySQL user variables to remember results without
having to store them in temporary variables in the client.
@xref{Variables}.

For example, to find the articles with the highest and lowest price you
can do this:

@example
mysql> SELECT @@min_price:=MIN(price),@@max_price:=MAX(price) FROM shop;
mysql> SELECT * FROM shop WHERE price=@@min_price OR price=@@max_price;
+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
|    0003 | D      |  1.25 |
|    0004 | D      | 19.95 |
+---------+--------+-------+
@end example


@node example-Foreign keys, Searching on two keys, example-user-variables, Examples
@subsection Using Foreign Keys

@cindex foreign keys
@cindex keys, foreign

In MySQL 3.23.44 and up, @code{InnoDB} tables support checking of
foreign key constraints. @xref{InnoDB, , @code{InnoDB}}.
See also @ref{ANSI diff Foreign Keys}.

You don't actually need foreign keys to join two tables.
For table types other than @code{InnoDB},
the only things MySQL currently doesn't do are 1)
@code{CHECK} to make sure that the keys you use
really exist in the table or tables you're referencing and 2)
automatically delete rows from a table with a foreign key
definition. Using your keys to join tables will work just fine:

@example
CREATE TABLE person (
    id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
    name CHAR(60) NOT NULL,
    PRIMARY KEY (id)
);

CREATE TABLE shirt (
    id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
    style ENUM('t-shirt', 'polo', 'dress') NOT NULL,
    color ENUM('red', 'blue', 'orange', 'white', 'black') NOT NULL,
    owner SMALLINT UNSIGNED NOT NULL REFERENCES person(id),
    PRIMARY KEY (id)
);

INSERT INTO person VALUES (NULL, 'Antonio Paz');

SELECT @@last := LAST_INSERT_ID();

INSERT INTO shirt VALUES
(NULL, 'polo', 'blue', @@last),
(NULL, 'dress', 'white', @@last),
(NULL, 't-shirt', 'blue', @@last);

INSERT INTO person VALUES (NULL, 'Lilliana Angelovska');

SELECT @@last := LAST_INSERT_ID();

INSERT INTO shirt VALUES
(NULL, 'dress', 'orange', @@last),
(NULL, 'polo', 'red', @@last),
(NULL, 'dress', 'blue', @@last),
(NULL, 't-shirt', 'white', @@last);

SELECT * FROM person;
+----+---------------------+
| id | name                |
+----+---------------------+
|  1 | Antonio Paz         |
|  2 | Lilliana Angelovska |
+----+---------------------+

SELECT * FROM shirt;
+----+---------+--------+-------+
| id | style   | color  | owner |
+----+---------+--------+-------+
|  1 | polo    | blue   |     1 |
|  2 | dress   | white  |     1 |
|  3 | t-shirt | blue   |     1 |
|  4 | dress   | orange |     2 |
|  5 | polo    | red    |     2 |
|  6 | dress   | blue   |     2 |
|  7 | t-shirt | white  |     2 |
+----+---------+--------+-------+


SELECT s.* FROM person p, shirt s
 WHERE p.name LIKE 'Lilliana%'
   AND s.owner = p.id
   AND s.color <> 'white';

+----+-------+--------+-------+
| id | style | color  | owner |
+----+-------+--------+-------+
|  4 | dress | orange |     2 |
|  5 | polo  | red    |     2 |
|  6 | dress | blue   |     2 |
+----+-------+--------+-------+
@end example


@node Searching on two keys, Calculating days, example-Foreign keys, Examples
@subsection Searching on Two Keys

@findex OR
@findex UNION
@cindex searching, two keys
@cindex keys, searching on two

An @code{OR} using a single key is well optimized, as is the handling
of @code{AND}.

The one tricky case is that of searching on two different keys
combined with @code{OR}:

@example
SELECT field1_index, field2_index FROM test_table
WHERE field1_index = '1' OR  field2_index = '1'
@end example

This case is optimized from MySQL 5.0.0.
@xref{Index Merge optimization}.

In MySQL 4.0 and up, you can also solve the problem efficiently by
using a @code{UNION} that combines the output of two separate
@code{SELECT} statements.
@xref{UNION}.

Each @code{SELECT} searches only one key and can be optimized:

@example
SELECT field1_index, field2_index
    FROM test_table WHERE field1_index = '1'
UNION
SELECT field1_index, field2_index
    FROM test_table WHERE field2_index = '1';
@end example

Prior to MySQL 4.0, you can achieve the same effect by using a
@code{TEMPORARY} table and separate @code{SELECT} statements.
This type of optimization is also very good if
you are using very complicated queries where the SQL server does the
optimizations in the wrong order.

@example
CREATE TEMPORARY TABLE tmp
SELECT field1_index, field2_index
    FROM test_table WHERE field1_index = '1';
INSERT INTO tmp
SELECT field1_index, field2_index
    FROM test_table WHERE field2_index = '1';
SELECT * from tmp;
DROP TABLE tmp;
@end example

This method of solving the problem is in effect a @code{UNION} of two queries.

@node Calculating days, example-AUTO_INCREMENT, Searching on two keys, Examples
@subsection Calculating Visits Per Day

@findex BIT_OR
@findex BIT_COUNT
@findex <<
@cindex bit_functions, example

The following example shows how you can use the bit group functions
to calculate the number of days per month a user has visited a Web page.

@example
CREATE TABLE t1 (year YEAR(4), month INT(2) UNSIGNED ZEROFILL,
             day INT(2) UNSIGNED ZEROFILL);
INSERT INTO t1 VALUES(2000,1,1),(2000,1,20),(2000,1,30),(2000,2,2),
            (2000,2,23),(2000,2,23);
@end example

The example table contains year-month-day values representing visits by users
to the page. To determine how many different days in each month these visits
occur, use this query:

@example
SELECT year,month,BIT_COUNT(BIT_OR(1<<day)) AS days FROM t1
       GROUP BY year,month;
@end example

Which returns:

@example
+------+-------+------+
| year | month | days |
+------+-------+------+
| 2000 |    01 |    3 |
| 2000 |    02 |    2 |
+------+-------+------+
@end example

The query calculates how many different days appear in the table for each
year/month combination, with automatic removal of duplicate entries.


@node example-AUTO_INCREMENT,  , Calculating days, Examples
@subsection Using @code{AUTO_INCREMENT}

@c help_category Column Types

@cindex AUTO_INCREMENT
@cindex SEQUENCE
@cindex sequences
@c description_for_help_topic AUTO_INCREMENT   SERIAL DEFAULT VALUE
The @code{AUTO_INCREMENT} attribute can be used to generate a unique
identity for new rows:
@c end_description_for_help_topic

@c example_for_help_topic AUTO_INCREMENT
@example
CREATE TABLE animals (
             id MEDIUMINT NOT NULL AUTO_INCREMENT,
             name CHAR(30) NOT NULL,
             PRIMARY KEY (id)
             );
INSERT INTO animals (name) VALUES ('dog'),('cat'),('penguin'),
                                  ('lax'),('whale'),('ostrich');
SELECT * FROM animals;
@end example

Which returns:

@example
+----+---------+
| id | name    |
+----+---------+
|  1 | dog     |
|  2 | cat     |
|  3 | penguin |
|  4 | lax     |
|  5 | whale   |
|  6 | ostrich |
+----+---------+
@end example

You can retrieve the most recent @code{AUTO_INCREMENT} value with the
@code{LAST_INSERT_ID()} SQL function or the @code{mysql_insert_id()} C API
function. These functions are connection-specific, so their return value
is not affected by another connection also doing inserts.

Note: For a multiple-row insert,
@code{LAST_INSERT_ID()}/@code{mysql_insert_id()} will actually return the
@code{AUTO_INCREMENT} key from the @strong{first} of the inserted rows.
This allows multiple-row inserts to be reproduced correctly on other servers
in a replication setup.

For @code{MyISAM} and @code{BDB} tables you can specify @code{AUTO_INCREMENT}
on a secondary column in a multiple-column index.  In this case, the generated
value for the @code{AUTO_INCREMENT} column is calculated as
@code{MAX(auto_increment_column)+1 WHERE prefix=given-prefix}.  This is
useful when you want to put data into ordered groups.

@example
CREATE TABLE animals (
             grp ENUM('fish','mammal','bird') NOT NULL,
             id MEDIUMINT NOT NULL AUTO_INCREMENT,
             name CHAR(30) NOT NULL,
             PRIMARY KEY (grp,id)
             );
INSERT INTO animals (grp,name) VALUES('mammal','dog'),('mammal','cat'),
                  ('bird','penguin'),('fish','lax'),('mammal','whale'),
                  ('bird','ostrich');
SELECT * FROM animals ORDER BY grp,id;
@end example

Which returns:

@example
+--------+----+---------+
| grp    | id | name    |
+--------+----+---------+
| fish   |  1 | lax     |
| mammal |  1 | dog     |
| mammal |  2 | cat     |
| mammal |  3 | whale   |
| bird   |  1 | penguin |
| bird   |  2 | ostrich |
+--------+----+---------+
@end example

Note that in this case (when the @code{AUTO_INCREMENT} column is part of a
multiple-column index), @code{AUTO_INCREMENT} values will be reused if you
delete the row with the biggest @code{AUTO_INCREMENT} value in any group.
This happens even for @code{MyISAM} tables, for which @code{AUTO_INCREMENT}
values normally are not reused.)

@node Twin, Apache, Examples, Tutorial
@section Queries from the Twin Project

@cindex Twin Studies, queries
@cindex queries, Twin Studies project

At Analytikerna and Lentus, we have been doing the systems and field work
for a big research project. This project is a collaboration between the
Institute of Environmental Medicine at Karolinska Institutet Stockholm
and the Section on Clinical Research in Aging and Psychology at the
University of Southern California.

The project involves a screening part where all twins in Sweden older
than 65 years are interviewed by telephone. Twins who meet certain
criteria are passed on to the next stage. In this latter stage, twins who
want to participate are visited by a doctor/nurse team. Some of the
examinations include physical and neuropsychological examination,
laboratory testing, neuroimaging, psychological status assessment, and family
history collection. In addition, data are collected on medical and
environmental risk factors.

More information about Twin studies can be found at:
@uref{http://www.mep.ki.se/twinreg/index_en.html}

The latter part of the project is administered with a Web interface
written using Perl and MySQL.

Each night all data from the interviews is moved into a MySQL
database.

@menu
* Twin pool::                   Find All Non-distributed Twins
* Twin event::                  Show a Table of Twin Pair Status
@end menu


@node Twin pool, Twin event, Twin, Twin
@subsection Find All Non-distributed Twins

The following query is used to determine who goes into the second part of the
project:

@example
SELECT
    CONCAT(p1.id, p1.tvab) + 0 AS tvid,
    CONCAT(p1.christian_name, ' ', p1.surname) AS Name,
    p1.postal_code AS Code,
    p1.city AS City,
    pg.abrev AS Area,
    IF(td.participation = 'Aborted', 'A', ' ') AS A,
    p1.dead AS dead1,
    l.event AS event1,
    td.suspect AS tsuspect1,
    id.suspect AS isuspect1,
    td.severe AS tsevere1,
    id.severe AS isevere1,
    p2.dead AS dead2,
    l2.event AS event2,
    h2.nurse AS nurse2,
    h2.doctor AS doctor2,
    td2.suspect AS tsuspect2,
    id2.suspect AS isuspect2,
    td2.severe AS tsevere2,
    id2.severe AS isevere2,
    l.finish_date
FROM
    twin_project AS tp
    /* For Twin 1 */
    LEFT JOIN twin_data AS td ON tp.id = td.id
              AND tp.tvab = td.tvab
    LEFT JOIN informant_data AS id ON tp.id = id.id
              AND tp.tvab = id.tvab
    LEFT JOIN harmony AS h ON tp.id = h.id
              AND tp.tvab = h.tvab
    LEFT JOIN lentus AS l ON tp.id = l.id
              AND tp.tvab = l.tvab
    /* For Twin 2 */
    LEFT JOIN twin_data AS td2 ON p2.id = td2.id
              AND p2.tvab = td2.tvab
    LEFT JOIN informant_data AS id2 ON p2.id = id2.id
              AND p2.tvab = id2.tvab
    LEFT JOIN harmony AS h2 ON p2.id = h2.id
              AND p2.tvab = h2.tvab
    LEFT JOIN lentus AS l2 ON p2.id = l2.id
              AND p2.tvab = l2.tvab,
    person_data AS p1,
    person_data AS p2,
    postal_groups AS pg
WHERE
    /* p1 gets main twin and p2 gets his/her twin. */
    /* ptvab is a field inverted from tvab */
    p1.id = tp.id AND p1.tvab = tp.tvab AND
    p2.id = p1.id AND p2.ptvab = p1.tvab AND
    /* Just the sceening survey */
    tp.survey_no = 5 AND
    /* Skip if partner died before 65 but allow emigration (dead=9) */
    (p2.dead = 0 OR p2.dead = 9 OR
     (p2.dead = 1 AND
      (p2.death_date = 0 OR
       (((TO_DAYS(p2.death_date) - TO_DAYS(p2.birthday)) / 365)
        >= 65))))
    AND
    (
    /* Twin is suspect */
    (td.future_contact = 'Yes' AND td.suspect = 2) OR
    /* Twin is suspect - Informant is Blessed */
    (td.future_contact = 'Yes' AND td.suspect = 1
                               AND id.suspect = 1) OR
    /* No twin - Informant is Blessed */
    (ISNULL(td.suspect) AND id.suspect = 1
                        AND id.future_contact = 'Yes') OR
    /* Twin broken off - Informant is Blessed */
    (td.participation = 'Aborted'
     AND id.suspect = 1 AND id.future_contact = 'Yes') OR
    /* Twin broken off - No inform - Have partner */
    (td.participation = 'Aborted' AND ISNULL(id.suspect)
                                  AND p2.dead = 0))
    AND
    l.event = 'Finished'
    /* Get at area code */
    AND SUBSTRING(p1.postal_code, 1, 2) = pg.code
    /* Not already distributed */
    AND (h.nurse IS NULL OR h.nurse=00 OR h.doctor=00)
    /* Has not refused or been aborted */
    AND NOT (h.status = 'Refused' OR h.status = 'Aborted'
    OR h.status = 'Died' OR h.status = 'Other')
ORDER BY
    tvid;
@end example

Some explanations:
@table @asis
@item @code{CONCAT(p1.id, p1.tvab) + 0 AS tvid}
We want to sort on the concatenated @code{id} and @code{tvab} in
numerical order. Adding @code{0} to the result causes MySQL to
treat the result as a number.
@item column @code{id}
This identifies a pair of twins. It is a key in all tables.
@item column @code{tvab}
This identifies a twin in a pair. It has a value of @code{1} or @code{2}.
@item column @code{ptvab}
This is an inverse of @code{tvab}. When @code{tvab} is @code{1} this is
@code{2}, and vice versa. It exists to save typing and to make it easier for
MySQL to optimize the query.
@end table

This query demonstrates, among other things, how to do lookups on a table
from the same table with a join (@code{p1} and @code{p2}). In the example,
this is used to check whether a twin's partner died before the age of 65. If
so, the row is not returned.

All of the above exist in all tables with twin-related information. We
have a key on both @code{id,tvab} (all tables), and @code{id,ptvab}
(@code{person_data}) to make queries faster.

On our production machine (A 200MHz UltraSPARC), this query returns
about 150-200 rows and takes less than one second.

The current number of records in the tables used in the query:
@multitable @columnfractions .25 .10
@item @strong{Table}            @tab @strong{Rows}
@item @code{person_data}        @tab 71074
@item @code{lentus}             @tab 5291
@item @code{twin_project}       @tab 5286
@item @code{twin_data}          @tab 2012
@item @code{informant_data}     @tab 663
@item @code{harmony}            @tab 381
@item @code{postal_groups}      @tab 100
@end multitable


@node Twin event,  , Twin pool, Twin
@subsection Show a Table of Twin Pair Status

Each interview ends with a status code called @code{event}. The query
shown here is used to display a table over all twin pairs combined by
event. This indicates in how many pairs both twins are finished, in how many
pairs one twin is finished and the other refused, and so on.

@example
SELECT
        t1.event,
        t2.event,
        COUNT(*)
FROM
        lentus AS t1,
        lentus AS t2,
        twin_project AS tp
WHERE
        /* We are looking at one pair at a time */
        t1.id = tp.id
        AND t1.tvab=tp.tvab
        AND t1.id = t2.id
        /* Just the sceening survey */
        AND tp.survey_no = 5
        /* This makes each pair only appear once */
        AND t1.tvab='1' AND t2.tvab='2'
GROUP BY
        t1.event, t2.event;

@end example


@node Apache,  , Twin, Tutorial
@section Using MySQL with Apache

@cindex Apache

There are programs that let you authenticate your users from a MySQL
database and also let you write your log files into a MySQL table.

You can change the Apache logging format to be easily readable by
MySQL by putting the following into the Apache configuration file:

@example
LogFormat \
        "\"%h\",%@{%Y%m%d%H%M%S@}t,%>s,\"%b\",\"%@{Content-Type@}o\",  \
        \"%U\",\"%@{Referer@}i\",\"%@{User-Agent@}i\""
@end example

To load a log file in that format into MySQL, you can use a statement
something like this:

@example
LOAD DATA INFILE '@var{/local/access_log}' INTO TABLE @var{tbl_name}
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\'
@end example

The named table should be created to have columns that correspond to those
that the @code{LogFormat} line writes to the log file.


@node Using MySQL Programs, MySQL Database Administration, Tutorial, Top
@chapter Using MySQL Programs

This chapter provides a brief overview of the programs provided by MySQL AB
and discusses how to specify options when you run these programs.
Most programs have options that are specific to their own operation, but the
syntax for specifying options is similar for all of them. Later chapters
provide more detailed descriptions of individual programs, including which
options they recognize.

@menu
* Program Overview::            Overview of MySQL Programs
* Invoking Programs::           Invoking MySQL Programs
* Program Options::             Specifying Program Options
@end menu

@node Program Overview, Invoking Programs, Using MySQL Programs, Using MySQL Programs
@section Overview of MySQL Programs

@c TODO: maybe mention (or xref) third-party programs

MySQL AB provides several types of programs:

@table @asis

@item The MYSQL server and server startup scripts:

@itemize @bullet
@item
@command{mysqld} is the MySQL server
@item
@command{mysqld_safe}, @command{mysql.server}, and @command{mysqld_multi} are server
startup scripts
@item
@command{mysql_install_db} initializes the data directory and the initial
databases
@end itemize

These programs are discussed further in @ref{MySQL Database Administration}.

@item Client programs that access the server:

@itemize @bullet
@item
@command{mysql} is a command-line client for executing SQL statements interactively
or in batch mode
@item
@command{mysqlcc} (MySQL Control Center) is an interactive graphical tool for
executing SQL statements and administration
@item
@command{mysqladmin} is an administrative client
@item
@command{mysqlcheck} performs table maintenance operations
@item
@command{mysqldump} and @command{mysqlhotcopy} make database backups
@item
@command{mysqlimport} imports data files
@item
@command{mysqlshow} displays information about databases and tables
@end itemize

These programs are discussed further in @ref{Client-Side Scripts}.

@item Utility programs that operate independently of the server:

@itemize @bullet
@item
@command{myisamchk} performs table maintenance operations
@item
@command{myisampack} produces compressed, read-only tables
@item
@command{mysqlbinlog} is a tool for processing binary log files
@item
@command{perror} displays error code meanings
@end itemize

@c TODO: this table is missing some programs (e.g., replace).
@c TODO: not all programs named here have their own entries in the following
@c chapters (e.g., mysql_install_db)

@command{myisamchk} is discussed further in @ref{MySQL Database Administration}.
The other programs are further in @ref{Client-Side Scripts}.

@end table

Most MySQL distributions include all of these programs, except for those
programs that are platform-specific. (For example, the server startup
scripts are not used on Windows.) The exception is that RPM distributions
are more specialized. There is one RPM for the server, another for the
client programs, and so forth. If you appear to be missing one or more
programs, see @ref{Installing} for information on types of distributions
and what they contain.  It may be that you need to install something else.

@node Invoking Programs, Program Options, Program Overview, Using MySQL Programs
@section Invoking MySQL Programs

To invoke a MySQL program at the command line (that is, from your shell or
command prompt), enter the program name followed by any options or other
arguments needed to instruct the program what you want it to do. The following
commands show some sample program invocations. ``@code{shell>}'' represents
the prompt for your command interpreter; it is not part of what you type.
The particular prompt you will see depends on your command interpreter.
Typical prompts are @code{$} for @command{sh} or @command{bash}, @code{%} for
@command{csh} or @command{tcsh}, and @code{C:\>} for Windows 
@command{command.com} or @command{cmd.exe}.

@example
shell> mysql test
shell> mysqladmin extended-status variables
shell> mysqlshow --help
shell> mysqldump --user=root personnel
@end example

Arguments that begin with a dash are option arguments. They typically specify
the type of connection a program should make to the server or affect its
operational mode. Options have a syntax that is described in
@ref{Program Options}.

Non-option arguments (arguments with no leading dash) provide additional
information to the program. For example, the @command{mysql} program interprets
the first non-option argument as a database name, so the command
@code{mysql test} indicates that you want to use the @code{test} database.

Later sections that describe individual programs indicate which options a
program understands and describe the meaning of any additional non-option
arguments.

Some options are common to a number of programs. The most common of these are
the @code{--host}, @code{--user}, and @code{--password} options that specify
connection parameters. They indicate the host where the MySQL server is
running, and the username and password of your MySQL account. All MySQL client
programs understand these options; they allow you to specify which server to
connect to and the account to use on that server.

@cindex PATH environment variable
@cindex environment varible, PATH

You may find it necessary to invoke MySQL programs using the
pathname to the @file{bin} directory in which they are installed. This is
likely to be the case if you get a ``program not found'' error whenever
you attempt to run a MySQL program from any directory other than the
@file{bin} directory.  To make it more convenient to use MySQL, you
can add the pathname of the @file{bin} directory to your @code{PATH}
environment variable setting. Then to run a program you need only type
its name, not its entire pathname.

Consult the documentation for your command interpreter for instructions on
setting your @code{PATH}. The syntax for setting environment variables is
interpreter-specific.


@node Program Options,  , Invoking Programs, Using MySQL Programs
@section Specifying Program Options

You can provide options for MySQL programs in several ways:

@itemize @bullet

@item
On the command line following the program name. This is most common for
options that apply to a specific invocation of the program.

@item
In an option file that the program reads when it starts. This is common for
options that you want the program to use each time it runs.

@item
In environment variables. These are useful for options that you want to apply
each time the program runs, although in practice option files are used more
commonly for this purpose.
(@ref{Multiple Unix servers} discusses one situation in which environment
variables can be very helpful. It describes a handy technique that uses such
variables to specify the TCP/IP port number and Unix socket file for both
the server and client programs.)

@end itemize

MySQL programs determine which options are given first by examining environment
variables, then option files, and then the command line.
If an option is specified multiple times, the last occurrence takes
precedence.
This means that environment variables have the lowest precedence and
command-line options the highest.

You can take advantage of the way that MySQL programs process options by
specifying the default values for a program's options in an option file. Then
you need not type them each time you run the program, but can override the
defaults if necessary by using command-line options.

@menu
* Command-line options::        Using Options on the Command Line
* Option files::                Using Option Files
* Environment variable options::  Using Environment Variables to Specify Options
* Program variables::           Using Options to Set Program Variables
@end menu

@node Command-line options, Option files, Program Options, Program Options
@subsection Using Options on the Command Line

Program options specified on the command line follow these rules:

@itemize @bullet

@item
Options are given after the command name.

@item
An option argument begins with one dash or two dashes, depending on whether
it has a short name or a long name. Many options have both forms.
For example, @code{-?} and @code{--help} are the short and long forms
of the option that instructs a MySQL program to display a help message.

@item
Option names are case sensitive.  @code{-v} and @code{-V} are both legal and
have different meanings. (They are the corresponding short forms of the
@code{--verbose} and @code{--version} options.)

@item
Some options take a value following the option name.
For example, @code{-h localhost} or @code{--host=localhost} indicate
the MySQL server host to a client program.  The option value
tells the program the name of the host where the MySQL server is running.

@item
For a long option that takes a value, separate the option name and the value by an @samp{=} sign.
For a short option that takes a value, the option value can immediately follow the option letter,
or there can be a space between.
(@code{-hlocalhost} and @code{-h localhost} are equivalent.)
An exception to this rule is the option for specifying your MySQL password.
This option can be given in long form as @code{--password=pass_val} or as
@code{--password}. In the latter case (with no password value given), the
program will prompt you for the password.
The password option also may be given in short form as @code{-ppass_val} or as
@code{-p}. However, for the short form, if the password value is given, it
must follow the option letter with @emph{no intervening space}. The reason for
this is that if a space follows the option letter, the program has no way to
tell whether a following argument is supposed to be the password value or some
other kind of argument.  Consequently, the following two commands have two
completely different meanings:

@example
shell> mysql -ptest
shell> mysql -p test
@end example

The first command instructs @command{mysql} to use a password value of
@code{test}, but specifies no default database.
The second instructs @command{mysql} to prompt for the password value
and to use @code{test} as the default database.

@end itemize

MySQL 4.0 introduced some additional flexibility in the way you specify
options. These changes were made in MySQL 4.0.2. Some of them relate to the way
you specify options that have ``enabled'' and ``disabled'' states, and to the
use of options that might be present in one version of MySQL but not another.
Those capabilities are discussed in this section.
Another change pertains to the way you use options to set program variables.
@ref{Program variables} discusses that topic further.

@c TODO: also: can specify unambigious prefix of option -- hm, but that's
@c not 4.0.2 (?), so it should be mentioned earlier.

Some options control behavior that can be turned on or off. For example,
the @command{mysql} client supports a @code{--column-names} option that
determines whether or not to display a row of column names at the beginning
of query results. By default, this option is enabled. However, you may
want to disable it in some instances, such as when sending the output
of @command{mysql} into another program that expects to see only data and
not an initial header line.

To disable column names, you can specify the option using any of these forms:

@example
--disable-column-names
--skip-column-names
--column-names=0
@end example

The @code{--disable} and @code{--skip} prefixes and the @code{=0} suffix
all have the same effect: They turn the option off.

The ``enabled'' form of the option may be specified in any of these ways:

@example
--column-names
--enable-column-names
--column-names=1
@end example

Another change to option processing introduced in MySQL 4.0 is that you
can use the @code{--loose} prefix for command-line options. If an option
is prefixed by @code{--loose}, the program will not exit with
an error if it does not recognize the option, but instead will issue
only a warning:

@example
shell> mysql --loose-no-such-option
mysql: WARNING: unknown option '--no-such-option'
@end example

The @code{--loose} prefix can be useful when you run programs from
multiple installations of MySQL on the same machine, at least if all the
versions are as recent as 4.0.2.  This prefix is particularly useful when you
list options in an option file.  An option that may not be recognized by all
versions of a program can be given using the @code{--loose}
prefix (or @code{loose} in an option file). Versions of the program that do
not recognize the option will issue a warning and ignore it. This
strategy requires that versions involved be 4.0.2 or later, because
earlier versions know nothing of the @code{--loose} convention.


@node Option files, Environment variable options, Command-line options, Program Options
@subsection Using Option Files

@cindex default options
@cindex option files
@cindex creating, default startup options
@cindex startup options, default

MySQL programs can read startup options from option
files (also sometimes called configuration files).
Option files provide a convenient way to specify commonly used options so that
they need not be entered on the command line each time you run a program.
Option file capability is available from MySQL 3.22 on.

The following programs support option files:
@command{myisamchk},
@command{myisampack},
@command{mysql},
@command{mysql.server},
@command{mysqladmin},
@command{mysqlbinlog},
@command{mysqlcc},
@command{mysqlcheck},
@command{mysqld_safe},
@command{mysqldump},
@command{mysqld},
@command{mysqlhotcopy},
@command{mysqlimport}, and
@command{mysqlshow}.

On Windows, MySQL programs read startup options from the following files:

@multitable @columnfractions .30 .70
@item @strong{Filename} @tab @strong{Purpose}
@item @code{@var{WINDIR}\my.ini} @tab Global options
@item @code{C:\my.cnf} @tab Global options
@end multitable

@var{WINDIR} represents the location of your Windows directory.  This is
commonly @file{C:\Windows} or @file{C:\WinNT}.  You can determine its
exact location from the value of the @code{WINDIR} environment variable
using the following command:

@example
C:\> echo %WINDIR%
@end example

On Unix, MySQL programs read startup options from the following files:

@tindex .my.cnf file
@multitable @columnfractions .30 .70
@item @strong{Filename} @tab @strong{Purpose}
@item @code{/etc/my.cnf} @tab Global options
@item @code{@var{DATADIR}/my.cnf} @tab Server-specific options
@item @code{defaults-extra-file} @tab The file specified with @code{--defaults-extra-file=@var{path}}, if any
@item @code{~/.my.cnf} @tab User-specific options
@end multitable

@var{DATADIR} represents the location of the MySQL data directory. Typically
this is @file{/usr/local/mysql/data} for a binary installation or
@file{/usr/local/var} for a source installation.  Note that this is the data
directory location that was specified at configuration time, not the
one specified with @code{--datadir} when @command{mysqld} starts.
Use of @code{--datadir} at runtime has no effect on where the server
looks for option files, because it looks for them before processing any
command-line arguments.

MySQL looks for option files in the order just described and reads any that
exist. If an option file that you want to use does not exist, create it
with a plain text editor.
If multiple option files exist, an option specified in a file read later takes
precedence over the same option specified in a file read earlier.

Any long option that may be given on the command line when running a
MySQL program can be given in an option file as well.  To get the list
of available options for a program, run it with the @code{--help} option.

The syntax for
specifying options in an option file is similar to command-line syntax, except
that you omit the leading two dashes. For example, @code{--quick} or
@code{--host=localhost} on the command line should be specified as
@code{quick} or @code{host=localhost} in an option file.
To specify an option of the form @code{--loose-opt_name}
in an option file, write it as @code{loose-opt_name}.

Empty lines in option files are ignored. Non-empty lines can take any
of the following forms:

@table @code
@item #@var{comment}
@itemx ;@var{comment}
Comment lines start with @samp{#} or @samp{;}. As of MySQL 4.0.14, 
a @samp{#}-comment can start in the middle of a line as well.

@item [@var{group}]
@var{group} is the name of the program or group for which you want to set
options.  After a group line, any @var{opt_name} or @code{set-variable} lines
apply to the named group until the end of the option file or another group
line is given.

@item @var{opt_name}
This is equivalent to @code{--@var{opt_name}} on the command line.

@item @var{opt_name}=@var{value}
This is equivalent to @code{--@var{opt_name}=@var{value}} on the command line.
In an option file, you can have spaces around the @samp{=} character,
something that is not true on the command line.
As of
MySQL 4.0.16, you can quote the value with double quotes or single quotes.
This is useful if the value contains a @samp{#} comment character or whitespace.

@item set-variable = @var{var_name}=@var{value}
Set the program variable @var{var_name} to the given value.
This is equivalent to @code{--set-variable=@var{var_name}=@var{value}} on the
command line.
Spaces are allowed around the first @samp{=} character but not around
the second.
This syntax is deprecated as of MySQL 4.0.
See @ref{Program variables} for more information on setting program variables.
@end table

Leading and trailing blanks are automatically deleted from option names and
values.  You may use the escape sequences @samp{\b}, @samp{\t}, @samp{\n},
@samp{\r}, @samp{\\}, and @samp{\s} in option values to represent the
backspace, tab, newline, carriage return, and space characters.

On Windows, if an option value represents a pathname, you should specify the
value using @samp{/} rather than @samp{\} as the pathname separator. If you
use @samp{\}, you must double it as @samp{\\},
because @samp{\} is the escape character in MySQL.

If an option group name is the same as a program name, options in the group
apply specifically to that program.

The @code{[client]} option group is read by all client programs (but not
by @command{mysqld}). This allows you to specify options that apply to every
client. For example, @code{[client]} is the perfect group to use to specify
the password that you use to connect to the server.  (But make sure that
the option file is readable and writable only by yourself, so that other
people cannot find out your password.) Be sure not to put an option in the
@code{[client]} group unless it is recognized by @emph{all} client programs
that you use. Programs that do not understand the option will quit after
displaying an error message if you try to run them.

As of MySQL 4.0.14, if you want to create option groups that should be
read only by one specific @command{mysqld} server release series, you can do this by
using groups with names of @code{[mysqld-4.0]}, @code{[mysqld-4.1]}, and so
forth. The following group indicates that the @code{--new} option should be
used only by MySQL servers with 4.0.x version numbers:

@example
[mysqld-4.0]
new
@end example

Here is a typical global option file:

@example
[client]
port=3306
socket=/tmp/mysql.sock

[mysqld]
port=3306
socket=/tmp/mysql.sock
key_buffer_size=16M
max_allowed_packet=8M

[mysqldump]
quick
@end example

The preceding option file uses @code{@var{var_name}=@var{value}} syntax for the
lines that set the @code{key_buffer_size} and @code{max_allowed_packet}
variables. Prior to MySQL 4.0.2, you would need to use @code{set-variable}
syntax instead (described earlier in this section).

Here is a typical user option file:

@example
[client]
# The following password will be sent to all standard MySQL clients
password="my_password"

[mysql]
no-auto-rehash
set-variable = connect_timeout=2

[mysqlhotcopy]
interactive-timeout

@end example

This option file uses @code{set-variable} syntax to set the
@code{connect_timeout} variable. For MySQL 4.0.2 and up, you can also set
the variable using just @code{connect_timeout=2}.

@tindex .my.cnf file
If you have a source distribution, you will find sample option
files named @file{my-@var{xxxx}.cnf} in the @file{support-files} directory.
If you have a binary distribution, look in the @file{support-files}
directory under your MySQL installation directory (typically @file{C:\mysql}
on Windows or @file{/usr/local/mysql} on Unix).  On Windows the sample option files
may also be located in the MySQL installation directory. Currently
there are sample option files for small, medium, large, and very
large systems. To experiment with one of these files, copy it to
@file{C:\my.cnf} on Windows or to @file{.my.cnf} in your home directory on
Unix.

@strong{Note}: On Windows, the @file{.cnf} option file extension might not
be displayed.

All MySQL programs that support option files handle the
following command-line options:

@table @code

@item --no-defaults
Don't read any option files.

@item --print-defaults
Print the program name and all options that it will get from option files.

@item --defaults-file=@var{path_name}
Use only the given option file. @var{path_name} is the full pathname
to the file.

@item --defaults-extra-file=@var{path_name}
Read this option file after the global option file but before the user
option file. @var{path_name} is the full pathname to the file.

@end table

To work properly, each of these options must immediately
follow the command name on the command line, with the exception
that @code{--print-defaults} may be used immediately after
@code{--defaults-file} or @code{--defaults-extra-file}.

@c TODO: next few paragraphs probably should go into API chapter.

In shell scripts, you can use the @command{my_print_defaults} program to parse
option files. The following example shows the output that
@command{my_print_defaults} might produce when asked to show the options found in
the @code{[client]} and @code{[mysql]} groups:

@example
shell> my_print_defaults client mysql
--port=3306
--socket=/tmp/mysql.sock
--no-auto-rehash
@end example

Note for developers:  Option file handling is implemented in the C client
library simply by
processing all matching options (that is, options in the appropriate group)
before any command-line arguments. This works nicely for programs that use
the last instance of an option that is specified multiple times. If you have
a C or C++ program that handles multiply specified options this way but doesn't
read option files, you need add only two lines to give it that capability.
Check the source code of any of the standard MySQL clients to see
how to do this.

Several other language interfaces to MySQL are based on the C client library,
and some of them provide a way to access option file contents. These include
Perl and Python. See the documentation for your preferred interface for
details.


@node Environment variable options, Program variables, Option files, Program Options
@subsection Using Environment Variables to Specify Options

@cindex environment variables

To specify an option using an environment variable, set the variable using the
syntax appropriate for your comment processor. For example, on Windows or
NetWare,
you can set the @code{USER} variable to specify your MySQL account name.
To do so, use this syntax:

@example
SET USER=@var{your_name}
@end example

The syntax on Unix depends on your shell. Suppose that you want to specify the
TCP/IP port number using the @code{MYSQL_TCP_PORT} variable. The syntax for
Bourne shell and variants (@command{sh}, @command{bash}, @command{zsh}, etc.) is:

@example
MYSQL_TCP_PORT=3306
@end example

For @command{csh} and @command{tcsh}, use this syntax:

@example
setenv MYSQL_TCP_PORT 3306
@end example

The commands to set environment variables can be executed at your command
prompt to take effect immediately. These settings persist until you log out.
To have the settings take effect each time you log in,
place the appropriate command or commands in a startup file that your
command interpreter reads each time it starts. Typical startup files are
@file{AUTOEXEC.BAT} for Windows, @file{.bash_profile} for @command{bash}, or
@file{.tcshrc} for @command{tcsh}. Consult the documentation for your command
interpreter for specific details.

@ref{Environment variables} lists all environment variables that affect MySQL
program operation.


@node Program variables,  , Environment variable options, Program Options
@subsection Using Options to Set Program Variables

@cindex program variables, setting
@cindex setting program variables

@c TODO: check whether program variables can be set by unique prefix.

Many MySQL programs have internal variables that can be set at runtime.
As of MySQL 4.0.2, program
variables are set the same way as any other long option that takes a value.
For example, @command{mysql} has a @code{max_allowed_packet} variable that
controls the maximum size of its communication buffer.
To set the @code{max_allowed_packet} variable for @command{mysql} to a value of
16MB, use either of the following commands:

@example
shell> mysql --max_allowed_packet=16777216
shell> mysql --max_allowed_packet=16M
@end example

The first command specifies the value in bytes. The second specifies the value
in megabytes. Variable values can have a suffix of @code{K}, @code{M}, or
@code{G} (either uppercase or lowercase) to indicate units of kilobytes,
megabytes, or gigabytes.

In an option file, the variable setting is given without the leading dashes:

@example
[mysql]
max_allowed_packet=16777216
@end example

Or:

@example
[mysql]
max_allowed_packet=16M
@end example

If you like, underscores in a variable name can be specified as dashes.

Prior to MySQL 4.0.2, program variable names are not recognized as option
names.
Instead, use the @code{--set-variable} option to assign a value to a variable:

@example
shell> mysql --set-variable=max_allowed_packet=16777216
shell> mysql --set-variable=max_allowed_packet=16M
@end example

In an option file, omit the leading dashes:

@example
[mysql]
set-variable = max_allowed_packet=16777216
@end example

Or:

@example
[mysql]
set-variable = max_allowed_packet=16M
@end example

With @code{--set-variable}, underscores in variable names cannot be given as
dashes for versions of MySQL older than 4.0.2.

The @code{--set-variable} option is still recognized in MySQL 4.0.2 and up,
but is deprecated.

Some server variables can be set at runtime. For details, see
@ref{Dynamic System Variables}.


@node MySQL Database Administration, Replication, Using MySQL Programs, Top
@chapter Database Administration

This chapter covers topics that deal with administering a MySQL installation,
such as configuring the server, managing user accounts, and performing backups.

@menu
* Server-Side Scripts::         The MySQL Server and Server Startup Scripts
* Configuring MySQL::           Configuring the MySQL Server
* Server Shutdown::             The MySQL Server Shutdown Process
* Security::                    General Security Issues
* Privilege system::            The MySQL Access Privilege System
* User Account Management::     MySQL User Account Management
* Disaster Prevention::         Disaster Prevention and Recovery
* Localisation::                MySQL Localization and International Usage
* Log Files::                   The MySQL Log Files
* Multiple servers::            Running Multiple MySQL Servers on the Same Machine
* Query Cache::                 The MySQL Query Cache
@end menu


@node Server-Side Scripts, Configuring MySQL, MySQL Database Administration, MySQL Database Administration
@section The MySQL Server and Server Startup Scripts

@c TODO: describe mysql_secure_installation, make_binary_distribution here


The MySQL server, @command{mysqld}, is the main program that does most of the
work in a MySQL installation. The server is accompanied by several related
scripts that perform setup operations when you install MySQL or that are
helper programs to assist you in starting and stopping the server.

This section provides an overview of the server and related programs, and
information about server startup scripts. Information about configuring the
server itself is given in @ref{Configuring MySQL}.

@menu
* Server-Side Overview::        Overview of the Server-Side Scripts and Utilities
* mysqld-max::                  The @command{mysqld-max} Extended MySQL Server
* mysqld_safe::                 The @command{mysqld_safe} Server Startup Script
* mysql.server::                The @command{mysql.server} Server Startup Script
* mysqld_multi::                The @command{mysqld_multi} Program for Managing Multiple MySQL Servers
@end menu


@node Server-Side Overview, mysqld-max, Server-Side Scripts, Server-Side Scripts
@subsection Overview of the Server-Side Scripts and Utilities

@cindex programs, list of

All MySQL programs take many different options. However, every
MySQL program provides a @code{--help} option that you can use
to get a description of the program's options. For example, try
@command{mysqld --help}.

You can override default options for all standard programs by specifying
options on the command line or in an option file.
@ref{Program Options}.

The following list briefly describes the MySQL server and server-related
programs:

@table @code

@item mysqld
@cindex @command{mysqld}
The SQL daemon (that is, the MySQL server). To use client programs, this
program must be running, because clients gain access to databases by
connecting to the server.
@xref{Configuring MySQL}.

@item mysqld-max
@cindex @command{mysqld-max}
A version of the server that includes additional features.
@xref{mysqld-max,  , @command{mysqld-max}}.

@item mysqld_safe
@cindex @command{mysqld_safe}
A server startup script.
@command{mysqld_safe} attempts to start @command{mysqld-max} if it exists, and
@command{mysqld} otherwise.
@xref{mysqld_safe,  , @command{mysqld_safe}}.

@item mysql.server
@cindex @command{mysql.server}
A server startup script.
This script is used on systems that use run directories containing scripts
that start system services for particular run levels. It invokes
@command{mysqld_safe} to start the MySQL server.
@xref{mysql.server,  , @command{mysql.server}}.

@item mysqld_multi
@cindex @command{mysqld_multi}
A server startup script that can start or stop multiple servers installed
on the system.
@xref{mysqld_multi,  , @command{mysqld_multi}}.

@item mysql_install_db
@cindex @command{mysql_install_db}
This script creates the MySQL grant tables with default privileges. It is
usually executed only once, when first installing MySQL on a system.

@item mysql_fix_privilege_tables
@cindex @command{mysql_fix_privilege_tables}
This script is used after an upgrade install operation, to update the grant
tables with any changes that have been made in newer versions of MySQL.

@end table

There are several other programs that also are run on the server host:

@c TODO: indicate where these are discussed

@table @code

@item myisamchk
@cindex @command{myisamchk}
A utility to describe, check, optimize, and repair @code{MyISAM} tables.
@command{myisamchk} is described in
@ref{Table maintenance}.

@item make_binary_distribution
@cindex @command{make_binary_distribution}
This program makes a binary release of a compiled MySQL. This could be sent
by FTP to @file{/pub/mysql/upload/} on @code{ftp.mysql.com} for the
convenience of other MySQL users.

@item mysqlbug
@cindex @command{mysqlbug}
The MySQL bug reporting script.  It can be used to
send a bug report to the MySQL mailing list. (You can also visit
@uref{http://bugs.mysql.com/} to file a bug report online.)

@end table


@node mysqld-max, mysqld_safe, Server-Side Overview, Server-Side Scripts
@subsection The @command{mysqld-max} Extended MySQL Server

@cindex @command{mysqld-max}

A MySQL-Max server is a version of the @command{mysqld} MySQL server that
has been built to include additional features.

The distribution to use depends on your platform:

@itemize @bullet
@item
For Windows, MySQL binary distributions include both the standard server
(@code{mysqld.exe}) and the MySQL-Max server (@command{mysqld-max.exe}), so you
need not get a special distribution. Just use a regular Windows
distribution, available at
@uref{http://dev.mysql.com/downloads/}.
@xref{Windows installation}.

@item
For Linux, if you install MySQL using RPM distributions, use the regular
@code{MySQL-server} RPM first to install a standard server named
@command{mysqld}.  Then use the @code{MySQL-Max} RPM to install a server named
@command{mysqld-max}.  The @code{MySQL-Max} RPM presupposes that you have
already installed the regular server RPM.  See @ref{Linux-RPM} for more
information on the Linux RPM packages.

@item
All other MySQL-Max distributions contain a single server that is named
@command{mysqld} but that has the additional features included.

@end itemize

You can find the MySQL-Max binaries on the MySQL AB Web site at
@uref{http://dev.mysql.com/downloads/mysql-4.0.html}.

MySQL AB builds the MySQL-Max servers by using the following
@command{configure} options:

@table @code

@item --with-server-suffix=-max
This option adds a @code{-max} suffix to the @command{mysqld} version string.

@item --with-innodb
This option enables support for the @code{InnoDB} storage engine.  MySQL-Max
servers always include @code{InnoDB} support, but this option actually is
needed only for MySQL 3.23.  From MySQL 4 on, @code{InnoDB} is included by
default in binary distributions, so you do not need a MySQL-Max server to
obtain @code{InnoDB} support.

@item --with-bdb
This option enables support for the Berkeley DB (@code{BDB}) storage engine.

@item CFLAGS=-DUSE_SYMDIR
This define enables symbolic link support for Windows.

@end table

MySQL-Max binary distributions are a convenience for those who wish to install
precompiled programs. If you build MySQL using a source distribution, you can
build your own Max-like server by enabling the same features at configuration
time that the MySQL-Max binary distributions are built with.

MySQL-Max servers include the BerkeleyDB (@code{BDB}) storage engine
whenever possible, but not all platforms support @code{BDB}.  The following
table shows which platforms allow MySQL-Max binaries to include @code{BDB}:

@multitable @columnfractions .20 .20
@item @strong{System}    @tab @code{BDB} @strong{Support}
@item AIX 4.3            @tab N
@item HP-UX 11.0         @tab N
@item Linux-Alpha        @tab N
@item Linux-IA-64        @tab N
@item Linux-Intel        @tab Y
@item Mac OS X           @tab N
@item NetWare            @tab N
@item SCO OSR5           @tab Y
@item Solaris-Intel      @tab N
@item Solaris-SPARC      @tab Y
@item UnixWare           @tab Y
@item Windows/NT         @tab Y
@end multitable

To find out which storage engines your server supports, issue the following
statement:

@example
mysql> SHOW ENGINES;
@end example

Before MySQL 4.1.2, @code{SHOW ENGINES} is unavailable. Use the following
statement instead and check the value of the variable for the storage engine
in which you are interested:

@example
mysql> SHOW VARIABLES LIKE 'have_%';
+------------------+----------+
| Variable_name    | Value    |
+------------------+----------+
| have_bdb         | NO       |
| have_crypt       | YES      |
| have_innodb      | YES      |
| have_isam        | NO       |
| have_raid        | NO       |
| have_symlink     | DISABLED |
| have_openssl     | NO       |
| have_query_cache | YES      |
+------------------+----------+
@end example

The values in the second column indicate the server's level of support for
each feature:

@multitable @columnfractions .15 .85
@item @strong{Value}  @tab @strong{Meaning}
@item @code{YES}      @tab The feature is supported and is active.
@item @code{NO}       @tab The feature is not supported.
@item @code{DISABLED} @tab The feature is supported but has been disabled.
@end multitable

A value of @code{NO} means that the server was compiled without support
for the feature, so it cannot be activated at runtime.

A value of @code{DISABLED} occurs either because the server was
started with an option that disables the feature, or because not
all options required to enable it were given. In the latter case, the
@code{@var{host_name}.err} error log file should contain a reason indicating why
the option is disabled.

One situation in which you might see @code{DISABLED} occurs with MySQL 3.23
when the @code{InnoDB} storage engine is compiled in. In MySQL 3.23, you
must supply at least the @code{innodb_data_file_path} option at runtime to
set up the @code{InnoDB} tablespace. Without this option, @code{InnoDB}
disables itself.
@xref{InnoDB in MySQL 3.23,  , @code{InnoDB} in MySQL 3.23}.
You can specify configuration options for the @code{BDB} storage engine, too,
but @code{BDB} will not disable itself if you do not provide them.
@xref{BDB start,  , @code{BDB} start}.

You might also see @code{DISABLED} for the @code{InnoDB}, @code{BDB}, or
@code{ISAM} storage engines if the server was compiled to support them, but
was started with the @code{--skip-innodb}, @code{--skip-bdb}, or
@code{--skip-isam} options at runtime.

As of Version 3.23, all MySQL servers support @code{MyISAM} tables, because
@code{MyISAM} is the default storage engine.


@node mysqld_safe, mysql.server, mysqld-max, Server-Side Scripts
@subsection The @command{mysqld_safe} Server Startup Script

@cindex tools, mysqld_safe
@cindex tools, safe_mysqld
@cindex scripts
@cindex @command{mysqld_safe}
@cindex @command{safe_mysqld}

@command{mysqld_safe} is the recommended way to start a @command{mysqld}
server on Unix and NetWare.  @command{mysqld_safe} adds some safety features
such as restarting the server when an error occurs and logging runtime
information to an error log file. NetWare-specific behaviors are listed
later in this section.

@strong{Note}:
Before MySQL 4.0, @command{mysqld_safe} is named @command{safe_mysqld}.
To preserve backward compatibility, MySQL binary distributions for
some time will include @command{safe_mysqld} as a symbolic link to
@command{mysqld_safe}.

By default, @command{mysqld_safe} tries to start an executable named
@command{mysqld-max} if it exists, or @command{mysqld} otherwise.
Be aware of the implications of this behavior:

@itemize @bullet

@item
On Linux, the @code{MySQL-Max} RPM relies on this @command{mysqld_safe}
behavior. The RPM installs an executable named @command{mysqld-max}, which
causes @command{mysqld_safe} to automatically use that executable from that
point on.

@item
If you install a MySQL-Max distribution that includes a server named
@command{mysqld-max}, then upgrade later to a non-Max version of MySQL,
@command{mysqld_safe} will still attempt to run the old @command{mysqld-max}
server.  If you perform such an upgrade, you should manually remove the old
@command{mysqld-max} server to ensure that @command{mysqld_safe} runs the new
@command{mysqld} server.

@end itemize

To override the default behavior and specify explicitly which server you
want to run, specify a @code{--mysqld} or @code{--mysqld-version} option to
@command{mysqld_safe}.

Many of the options to @command{mysqld_safe} are the same as the options to
@command{mysqld}. @xref{Server options}.

All options specified to @command{mysqld_safe} on the command line are
passed to @command{mysqld}.  If you want to use any options that are specific
to @command{mysqld_safe} and that @command{mysqld} doesn't support, do not specify
them on the command line. Instead, list them in the @code{[mysqld_safe]} group
of an option file.
@xref{Option files}.

@command{mysqld_safe} reads all options from the @code{[mysqld]},
@code{[server]}, and @code{[mysqld_safe]} sections in option files.
For backward compatibility, it also reads @code{[safe_mysqld]}
sections, although you should rename such sections to @code{[mysqld_safe]}
when you begin using MySQL 4.0 or later.

@command{mysqld_safe} supports the following options:

@c TODO: list the NetWare-specific --autoclose option

@table @code

@item --basedir=@var{path}
The path to the MySQL installation directory.

@item --core-file-size=@var{size}
The size of the core file @command{mysqld} should be able to create. The option
value is passed to @command{ulimit -c}.

@item --datadir=@var{path}
The path to the data directory.

@item --defaults-extra-file=@var{path}
The name of an option file to be read in addition to the usual option files.

@item --defaults-file=@var{path}
The name of an option file to be read instead of the usual option files.

@item --err-log=@var{path}
The old form of the @code{--log-error} option, to be used before MySQL 4.0.

@item --ledir=@var{path}
The path to the directory containing the @command{mysqld} program.
Use this option to explicitly indicate the location of the server.

@item --log-error=@var{path}
Write the error log to the given file. @xref{Error log}.

@item --mysqld=@var{prog_name}
The name of the server program (in the @code{ledir} directory) that you
want to start. This option is needed if you use the MySQL binary distribution
but have the data directory outside of the binary distribution.

@item --mysqld-version=@var{suffix}
This option is similar to the @code{--mysqld} option, but you specify only
the suffix for the server program name. The basename is assumed to be
@command{mysqld}.  For example, if you use @code{--mysqld-version=max},
@command{mysqld_safe} will start the @command{mysqld-max} program in the
@code{ledir} directory.  If the argument to @code{--mysqld-version} is
empty, @command{mysqld_safe} uses @command{mysqld} in the @code{ledir} directory.

@item --nice=@var{priority}
Use the @code{nice} program to set the server's scheduling priority to the
given value.  This option was added in MySQL 4.0.14.

@item --no-defaults
Do not read any option files.

@item --open-files-limit=@var{count}
The number of files @command{mysqld} should be able to open. The option value
is passed to @command{ulimit -n}. Note that you need to start
@command{mysqld_safe} as @code{root} for this to work properly!

@item --pid-file=@var{path}
The path to the process ID file.

@item --port=@var{port_num}
The port number to use when listening for TCP/IP connections.

@item --socket=@var{path}
The Unix socket file to use for local connections.

@item --timezone=@var{zone}
Set the @code{TZ} time zone environment variable to the given option value.
Consult your operating system documentation for legal time zone
specification formats.

@item --user=@{@var{user_name} | @var{user_id}@}
Run the @command{mysqld} server as the user having the name @var{user_name} or
the numeric user ID @var{user_id}.
(``User'' in this context refers to a system login account, not a MySQL user
listed in the grant tables.)

@end table

The @command{mysqld_safe} script is written so that it normally can start a
server that was installed from either a source or a binary distribution of
MySQL, even though these types of distributions typically install the server
in slightly different locations.
(@xref{Installation layouts}.)
@command{mysqld_safe} expects one of the following conditions to be true:

@itemize @bullet
@item
The server and databases can be found relative to the directory from which
@command{mysqld_safe} is invoked.  For binary distributions, @command{mysqld_safe}
looks under its working directory for @file{bin} and @file{data}
directories.  For source distributions, it looks for @file{libexec} and
@file{var} directories.  This condition should be met if you execute
@command{mysqld_safe} from your MySQL installation directory (for example,
@file{/usr/local/mysql} for a binary distribution).

@item
If the server and databases cannot be found relative to the working
directory, @command{mysqld_safe} attempts to locate them by absolute pathnames.
Typical locations are @file{/usr/local/libexec} and @file{/usr/local/var}.
The actual locations are determined from the values configured into the
distribution at the time it was built.  They should be correct if MySQL
is installed in the location specified at configuration time.
@end itemize

Because @command{mysqld_safe} will try to find the server and databases relative
to its own working directory, you can install a binary distribution of
MySQL anywhere, as long as you run @command{mysqld_safe} from the
MySQL installation directory:

@example
shell> cd mysql_installation_directory
shell> bin/mysqld_safe &
@end example

If @command{mysqld_safe} fails, even when invoked from the MySQL
installation directory, you can specify the @code{--ledir} and
@code{--datadir} options to indicate the directories in which the server and
databases are located on your system.

Normally, you should not edit the @command{mysqld_safe} script.  Instead,
configure @command{mysqld_safe} by using command-line options or options in the
@code{[mysqld_safe]} section of a @file{my.cnf} option file.  In rare cases,
it might be necessary to edit @command{mysqld_safe} to get it to start the server
properly. However, if you do this, your modified version of
@command{mysqld_safe} might be overwritten if you upgrade MySQL in the future, so
you should make a copy of your edited version that you can reinstall.

On NetWare, @command{mysqld_safe} is a NetWare Loadable Module (NLM) that is
ported from the original Unix shell script.  It does the following:

@enumerate
@item
Runs a number of system and option checks.

@item
Runs a check on @code{MyISAM} and @code{ISAM} tables.

@item
Provides a screen presence for the MySQL server.

@item
Starts @command{mysqld}, monitors it, and restarts it if it terminates in error.

@item
Sends error messages from @command{mysqld} to the @file{@var{host_name}.err} file in the
data directory.

@item
Sends @command{mysqld_safe} screen output to the @file{@var{host_name}.safe} file in the
data directory.

@end enumerate


@node mysql.server, mysqld_multi, mysqld_safe, Server-Side Scripts
@subsection The @command{mysql.server} Server Startup Script

MySQL distributions on Unix include a script named @command{mysql.server}.
It can be used on systems such as Linux and Solaris that use System V-style
run directories to start and stop system services. It is also used by the Mac
OS X Startup Item for MySQL.

@command{mysql.server} can be found in the @file{support-files} directory under
your MySQL installation directory or in a MySQL source tree.

If you use the Linux server RPM package (@code{MySQL-server-@var{VERSION}.rpm}),
the @command{mysql.server} script will already have been installed in the
@file{/etc/init.d} directory with the name @file{mysql}. You need not
install it manually. See @ref{Linux-RPM} for more information on the Linux
RPM packages.

Some vendors provide RPM packages that install a startup script under a
different name such as @command{mysqld}.

If you install MySQL from a source distribution or using a binary distribution
format that does not install @command{mysql.server} automatically, you can
install it manually. Instructions are provided in @ref{Automatic start}.

@command{mysql.server} reads options from the @code{[mysql.server]} and
@code{[mysqld]} sections of option files.  (For backward compatibility,
it also reads @code{[mysql_server]} sections, although you should rename such
sections to @code{[mysql.server]} when you begin using MySQL 4.0 or later.)


@node mysqld_multi,  , mysql.server, Server-Side Scripts
@subsection The @command{mysqld_multi} Program for Managing Multiple MySQL Servers

@cindex tools, mysqld_multi
@cindex scripts
@cindex multi mysqld
@cindex @command{mysqld_multi}

@command{mysqld_multi} is meant for managing several @command{mysqld}
processes that listen for connections on different Unix socket files and
TCP/IP ports.  It can start or stop servers, or report their current status.

The program searches for groups named @code{[mysqld#]} in @file{my.cnf} (or
in the file named by the @code{--config-file} option).  @code{#} can be any
positive integer.  This number is referred to in the following discussion as
the option group number, or @var{GNR}.  Group numbers distinguish option groups
from one another and are used as arguments to @command{mysqld_multi} to specify
which servers you want to start, stop, or obtain a status report for.
Options listed in these groups are the same that you would use in the
@code{[mysqld]} group used for starting @command{mysqld}.  (See, for example,
@ref{Automatic start}.) However, when using multiple servers it is necessary
that each one use its own value for options such as the Unix socket file and
TCP/IP port number. For more information on which options must be unique per
server in a multiple-server environment, see @ref{Multiple servers}.

To invoke @command{mysqld_multi}, use the following syntax:

@example
shell> mysqld_multi [@var{options}] @{start|stop|report@} [@var{GNR}[,@var{GNR}]...]
@end example

@code{start}, @code{stop}, and @code{report} indicate which operation you
want to perform. You can perform the designated operation on a single server
or multiple servers, depending on the @var{GNR} list that follows the option name.
If there is no list, @command{mysqld_multi} performs the operation for all
servers in the option file.

Each @var{GNR} value represents an option group number or range of group numbers.
The value should be the number at the end of the group name in the
option file.  For example, the @var{GNR} for a group named @code{[mysqld17]}
is @code{17}.  To specify a range of numbers, separate the first and last
numbers by a dash.  The @var{GNR} value @code{10-13} represents groups
@code{[mysqld10]} through @code{[mysqld13]}.  Multiple groups or group
ranges can be specified on the command line, separated by commas.  There
must be no whitespace characters (spaces or tabs) in the @var{GNR} list; anything
after a whitespace character is ignored.

This command starts a single server using option group @code{[mysqld17]}:

@example
shell> mysqld_multi start 17
@end example

This command stops several servers, using option groups @code{[mysql8]}
and @code{[mysqld10]} through @code{[mysqld13]}:

@example
shell> mysqld_multi stop 8,10-13
@end example

For an example of how you might set up an option file, use this command:

@example
shell> mysqld_multi --example
@end example

@command{mysqld_multi} supports the following options:

@table @code

@item --config-file=@var{name}
@cindex @code{config-file}, @command{mysqld_multi} option
Specify the name of an alternative option file. This affects where
@command{mysqld_multi} looks for @code{[mysqld#]} option groups.  Without this
option, all options are read from the usual @file{my.cnf} file.  The option
does not affect where @command{mysqld_multi} reads its own options, which are
always taken from the @code{[mysqld_multi]} group in the usual @file{my.cnf}
file.

@item --example
@cindex @code{example}, @command{mysqld_multi} option
Display a sample option file.

@item --help
@cindex @code{help}, @command{mysqld_multi} option
Display a help message and exit.

@item --log=@var{name}
@cindex @code{log}, @command{mysqld_multi} option
Specify the name of the log file. If the file exists, log output is appended
to it.

@item --mysqladmin=@var{prog_name}
@cindex @command{mysqladmin}, @command{mysqld_multi} option
The @command{mysqladmin} binary to be used to stop servers.

@item --mysqld=@var{prog_name}
@cindex @command{mysqld}, @command{mysqld_multi} option
The @command{mysqld} binary to be used. Note that you can specify
@command{mysqld_safe} as the value for this option also. The options are passed
to @command{mysqld}. Just make sure that you have the directory where @command{mysqld} is
located in your @code{PATH}
environment variable setting or fix @command{mysqld_safe}.

@item --no-log
@cindex @code{no-log}, @command{mysqld_multi} option
Print log information to stdout rather than to the log file. By default,
output goes to the log file.

@item --password=@var{password}
@cindex @code{password}, @command{mysqld_multi} option
The password of the MySQL account to use when invoking @command{mysqladmin}.
Note that the password value is not optional for this option, unlike for other
MySQL programs.

@item --silent
@cindex @code{silent}, @command{mysqld_multi} option
Disable warnings.  This option was added in MySQL 4.1.6.

@item --tcp-ip
@cindex @code{tcp-ip}, @command{mysqld_multi} option
Connect to each MySQL server via the TCP/IP port instead of the Unix socket
file.  (If a socket file is missing, the server might still be running,
but accessible only via the TCP/IP port.)  By default, connections are
made using the Unix socket file.  This option affects @code{stop} and
@code{report} operations.

@item --user=@var{user_name}
@cindex @code{user}, @command{mysqld_multi} option
The username of the MySQL account to use when invoking @command{mysqladmin}.

@item --verbose
@cindex @code{verbose}, @command{mysqld_multi} option
Be more verbose.  This option was added in MySQL 4.1.6.

@item --version
@cindex @code{version}, @command{mysqld_multi} option
Display version information and exit.

@end table

Some notes about @command{mysqld_multi}:

@itemize @bullet
@item
Make sure that the MySQL account used for stopping the @command{mysqld} servers
(with the @command{mysqladmin} program) has the same username and password for
each server. Also, make sure that the account has the @code{SHUTDOWN}
privilege. If the servers that you want to manage have many different
usernames or passwords for the administrative accounts, you might want to
create an account on each server that has the same username and password.
For example, you might set up a common @code{multi_admin} account by
executing the following commands for each server:

@example
shell> mysql -u root -S /tmp/mysql.sock -p@var{root_password}
mysql> GRANT SHUTDOWN ON *.*
    -> TO 'multi_admin'@@'localhost' IDENTIFIED BY 'multipass';
@end example

@xref{Privileges}.
You will have to do this for each @command{mysqld} server. Change the
connection parameters appropriately when connecting to each one.  Note that
the host part of the account name must allow you to connect as
@code{multi_admin} from the host where you want to run @command{mysqld_multi}.

@item
The
@code{--pid-file} option is very important if you are using @command{mysqld_safe}
to start @command{mysqld} (for example, @code{--mysqld=mysqld_safe}) Every
@command{mysqld} should have its own process ID file. The advantage of
using @command{mysqld_safe} instead of @command{mysqld} is
that @command{mysqld_safe} ``guards'' its @command{mysqld} process and will
restart it if the process terminates due to a signal
sent using @code{kill -9}, or for other reasons, such as a segmentation
fault. Please note that the
@command{mysqld_safe} script might require that you start it from a certain
place. This means that you might have to change location to a certain directory
before running @command{mysqld_multi}. If you have problems starting,
please see the @command{mysqld_safe} script. Check especially the lines:

@example
----------------------------------------------------------------
MY_PWD=`pwd`
# Check if we are starting this relative (for the binary release)
if test -d $MY_PWD/data/mysql -a -f ./share/mysql/english/errmsg.sys -a \
 -x ./bin/mysqld
----------------------------------------------------------------
@end example

@xref{mysqld_safe, , @command{mysqld_safe}}.
The test performed by these lines should be successful, or you might encounter
problems.

@item
The Unix socket file and the TCP/IP port number must be different for every
@command{mysqld}.

@item
You might want to use the @code{--user} option for @command{mysqld}, but in order
to do this you need to run the @command{mysqld_multi} script as the Unix
@code{root} user. Having the option in the option file doesn't matter; you
will just get a warning, if you are not the superuser and the @command{mysqld}
processes are started under your own Unix account.

@item
@strong{Important}: Make
sure that the data directory is fully accessible to the Unix account that
the specific @command{mysqld} process is started as. @emph{Do not} use the
Unix root account for this, unless you @emph{know} what you are doing.

@item
@strong{Most important}: Before using @command{mysqld_multi} be sure that you
understand the meanings of the options that are passed to the @command{mysqld}
servers and @emph{why} you would want to have separate @command{mysqld}
processes.  Beware of the dangers of using multiple @command{mysqld} servers
with the same data directory.  Use separate data directories, unless you
@emph{know} what you are doing.  Starting multiple servers with the same
data directory @emph{will not} give you extra performance in a threaded
system.
@xref{Multiple servers}.


@end itemize

The following example shows how you might set up an option file for use with
@command{mysqld_multi}.  The first and fifth @code{[mysqld#]} group were
intentionally left out from the example to illustrate that you can have
``gaps'' in the option file. This gives you more flexibility.  The order in
which the @command{mysqld} programs are started or stopped depends on the order
in which they appear in the option file.

@example
# This file should probably be in your home dir (~/.my.cnf)
# or /etc/my.cnf
# Version 2.1 by Jani Tolonen

[mysqld_multi]
mysqld     = /usr/local/bin/mysqld_safe
mysqladmin = /usr/local/bin/mysqladmin
user       = multi_admin
password   = multipass

[mysqld2]
socket     = /tmp/mysql.sock2
port       = 3307
pid-file   = /usr/local/mysql/var2/hostname.pid2
datadir    = /usr/local/mysql/var2
language   = /usr/local/share/mysql/english
user       = john

[mysqld3]
socket     = /tmp/mysql.sock3
port       = 3308
pid-file   = /usr/local/mysql/var3/hostname.pid3
datadir    = /usr/local/mysql/var3
language   = /usr/local/share/mysql/swedish
user       = monty

[mysqld4]
socket     = /tmp/mysql.sock4
port       = 3309
pid-file   = /usr/local/mysql/var4/hostname.pid4
datadir    = /usr/local/mysql/var4
language   = /usr/local/share/mysql/estonia
user       = tonu

[mysqld6]
socket     = /tmp/mysql.sock6
port       = 3311
pid-file   = /usr/local/mysql/var6/hostname.pid6
datadir    = /usr/local/mysql/var6
language   = /usr/local/share/mysql/japanese
user       = jani
@end example

@xref{Option files}.


@node Configuring MySQL, Server Shutdown, Server-Side Scripts, MySQL Database Administration
@section Configuring the MySQL Server

This section discusses MySQL server configuration topics:

@itemize @bullet
@item
Startup options that the server supports
@item
How to set the server SQL mode
@item
Server system variables
@item
Server status variables
@end itemize


@menu
* Server options::              @command{mysqld} Command-Line Options
* Server SQL mode::             The Server SQL Mode
* Server system variables::     Server System Variables
* Server status variables::     Server Status Variables
@end menu


@node Server options, Server SQL mode, Configuring MySQL, Configuring MySQL
@subsection @command{mysqld} Command-Line Options

@findex command-line options
@cindex options, command-line
@cindex mysqld options

When you start the @command{mysqld} server, you can specify program options
using any of the methods described in @ref{Program Options}. The most
common methods are to provide options in an option file or on the command
line. However, in most cases it is desirable to make sure that the server uses
the same options each time it runs. The best way to ensure this is to
list them in an option file.
@xref{Option files}.

@command{mysqld} reads options from the @code{[mysqld]} and @code{[server]}
groups.  @command{mysqld_safe} reads options from the @code{[mysqld]},
@code{[server]}, @code{[mysqld_safe]}, and @code{[safe_mysqld]}
groups.  @command{mysql.server} reads options from the @code{[mysqld]}
and @code{[mysql.server]} groups.  An embedded MySQL server usually reads
options from the @code{[server]}, @code{[embedded]}, and @code{[@var{xxxxx}_SERVER]}
groups, where @var{xxxxx} is the name of the application into which the
server is embedded.

@command{mysqld} accepts many command-line options.
For a list, execute @command{mysqld --help}. Before MySQL 4.1.1, @code{--help}
prints the full help message. As of 4.1.1, it prints a brief message; to see
the full list, use @command{mysqld --verbose --help}.

The following list shows some of the most common server options.
Additional options are described elsewhere:

@itemize @bullet

@item
Options that affect security:
See @ref{Privileges options}.

@item
SSL-related options:
See @ref{SSL options}.

@item
Binary log control options:
See @ref{Binary log}.

@item
Replication-related options:
See @ref{Replication Options}.

@item
Options specific to particular storage engines:
See @ref{MyISAM start,  , @code{MyISAM} start},
@ref{BDB start,  , @code{BDB} start},
@ref{InnoDB start,  , @code{InnoDB} start}.

@end itemize

You can also set the value of a server system variable by using the variable
name as an option, as described later in this section.

@table @code

@item --help, -?
Display a short help message and exit.
Before MySQL 4.1.1, @code{--help} displays the full help message.
As of 4.1.1, it displays an abbreviated message only.  Use both the
@code{--verbose} and @code{--help} options to see the full message.

@item --ansi
Use standard SQL syntax instead of MySQL syntax.  @xref{ANSI mode}.
For more precise control over the server SQL mode, use the @code{--sql-mode}
option instead.

@item --basedir=@var{path}, -b @var{path}
The path to the MySQL installation directory. All paths are usually resolved
relative to this.

@item --big-tables
Allow large result sets by saving all temporary sets in files.  This option
prevents most ``table full'' errors, but also slows down queries for which
in-memory tables would suffice.  Since MySQL 3.23.2, the server is able to
handle large result sets automatically by using memory for small temporary
tables and switching to disk tables where necessary.

@item --bind-address=@var{IP}
The IP address to bind to.

@item --console
Write the error log messages to stderr/stdout even if @code{--log-error}
is specified.  On Windows, @command{mysqld} will not close the console screen if
this option is used.

@item --character-sets-dir=@var{path}
The directory where character sets are installed.  @xref{Character sets}.

@item --chroot=@var{path}
Put the @command{mysqld} server in a closed environment during startup by using the
@code{chroot()} system call. This is a recommended security measure as of
MySQL 4.0. (MySQL 3.23 is not able to provide a @code{chroot()} jail that is
100% closed.)  Note that use of this option somewhat limits @code{LOAD
DATA INFILE} and @code{SELECT ... INTO OUTFILE}.

@item --character-set-server=@var{charset}
Use @var{charset} as the default server character set.
This option is available as of MySQL 4.1.3.
@xref{Character sets}.

@item --core-file
Write a core file if @command{mysqld} dies.  For some systems, you must also
specify the @code{--core-file-size} option to @command{mysqld_safe}.
@xref{mysqld_safe,  , @command{mysqld_safe}}.
Note that on some systems, such as Solaris, you will
not get a core file if you are also using the @code{--user} option.

@item --collation-server=@var{collation}
Use @var{collation} as the default server collation.
This option is available as of MySQL 4.1.3.
@xref{Character sets}.

@item --datadir=@var{path}, -h @var{path}
The path to the data directory.

@item --debug[=@var{debug_options}], -# [@var{debug_options}]
If MySQL is configured with @code{--with-debug}, you can use this
option to get a trace file of what @command{mysqld} is doing.
The @var{debug_options} string often is @code{'d:t:o,@var{file_name}'}.
@xref{Making trace files}.

@item --default-character-set=@var{charset}
Use @var{charset} as the default character set.  This option is deprecated
in favor of @code{--character-set-server} as of MySQL 4.1.3.
@xref{Character sets}.

@item --default-collation=@var{collation}
Use @var{collation} as the default collation.  This option is deprecated in
favor of @code{--collation-server} as of MySQL 4.1.3.
@xref{Character sets}.

@item --default-storage-engine=@var{type}
This option is a synonym for @code{--default-table-type}.
It is available as of MySQL 4.1.2.

@item --default-table-type=@var{type}
Set the default table type for tables.  @xref{Storage engines}.

@item --default-time-zone=@var{type}
Set the default server time zone.  This option sets the global
@code{time_zone} system variable.  If this option is not given, the default
time zone will be the same as the system time zone (given by the value of
the @code{system_time_zone} system variable.
This option is available as of MySQL 4.1.3.

@item --delay-key-write[= OFF | ON | ALL]
How the @code{DELAYED KEYS} option should be used.
Delayed key writing causes key buffers not to be flushed between writes for
@code{MyISAM} tables.
@code{OFF} disables delayed key writes.
@code{ON} enables delayed key writes for those tables that were created with
the @code{DELAYED KEYS} option.
@code{ALL} delays key writes for all @code{MyISAM} tables.
Available as of MySQL 4.0.3.
@xref{Server parameters}. @xref{MyISAM start}.

@strong{Note}: If you set this variable to @code{ALL}, you should not use
@code{MyISAM} tables from within another program (such as from another MySQL server or
with @command{myisamchk}) when the table is in use. Doing so will lead to index
corruption.

@item --delay-key-write-for-all-tables
Old form of @code{--delay-key-write=ALL} for use prior to MySQL 4.0.3.
As of 4.0.3, use @code{--delay-key-write} instead.

@item --des-key-file=@var{file_name}
Read the default keys used by @code{DES_ENCRYPT()} and @code{DES_DECRYPT()}
from this file.

@item --enable-named-pipe
Enable support for named pipes.
This option applies only on Windows NT, 2000, XP, and 2003 systems, and can be used
only with the @command{mysqld-nt} and @command{mysqld-max-nt} servers that support
named pipe connections.

@item --exit-info[=@var{flags}], -T [@var{flags}]
This is a bit mask of different flags you can use for debugging the
@command{mysqld} server. Do not use this option unless you know
exactly what it does!

@item --external-locking
Enable system locking.  Note that if you use this option on a system on
which @code{lockd} does not fully work (as on Linux), you will easily get
@command{mysqld} to deadlock.
This option previously was named @code{--enable-locking}.

@strong{Note}: If you use this option to enable updates to @code{MyISAM}
tables from many MySQL processes, you have to ensure that these conditions are
satisfied:

@itemize @bullet
@item
You should not use the query cache for queries that use tables that are
updated by another process.
@item
You should not use @code{--delay-key-write=ALL} or @code{DELAY_KEY_WRITE=1}
on any shared tables.
@end itemize

The easiest way to ensure this is to always use @code{--external-locking}
together with @code{--delay-key-write=OFF --query-cache-size=0}.

(This is not done by default because in many setups it's useful to have a
mixture of the above options.)

@item --flush
Flush all changes to disk after each SQL statement.  Normally MySQL
does a write of all changes to disk only after each SQL statement and lets
the operating system handle the synching to disk.
@xref{Crashing}.

@item --init-file=@var{file}
Read SQL statements from this file at startup.
Each statement must be on a single line and should not include comments.

@item --innodb-safe-binlog
Adds consistency guarantees between the content of @code{InnoDB} tables and
the binary log.
@xref{Binary log}.

@item --language=@var{lang_name}, -L @var{lang_name}
Client error messages in given language.  @var{lang_name} can be given as the
language name or as the full pathname to the directory where the language
files are installed.
@xref{Languages}.

@item --log[=@var{file}], -l [@var{file}]
Log connections and queries to this file. @xref{Query log}. If you don't
specify a filename, MySQL will use @code{@var{host_name}.log} as the filename.

@item --log-bin=[@var{file}]
The binary log file.
Log all queries that change data to this file. Used for backup and
replication.  @xref{Binary log}.  If you don't specify a filename,
MySQL will use @code{@var{host_name}-bin} as the log file basename.

@item --log-bin-index[=@var{file}]
The index file for binary log filenames. @xref{Binary log}.
If you don't specify a filename, MySQL will use @code{@var{host_name}-bin.index} as
the filename.

@item --log-error[=@var{file}]
Log errors and startup messages to this file. @xref{Error log}.
If you don't specify a filename, MySQL will use @code{@var{host_name}.err} as the filename.

@item --log-isam[=@var{file}]
Log all @code{ISAM}/@code{MyISAM} changes to this file (used only when
debugging @code{ISAM}/@code{MyISAM}).

@item --log-long-format
Log some extra information to the log files (update log, binary update log,
and slow queries log, whatever log has been activated). For example, 
username and timestamp are logged for queries. If you are using 
@code{--log-slow-queries} and @code{--log-long-format},
queries that are not using indexes also are logged to the slow query log.
Note that @code{--log-long-format} is deprecated as of MySQL version
4.1, when @code{--log-short-format} was introduced (the long log format
is the default setting since version 4.1). Also note that starting with 
MySQL 4.1, the @code{--log-queries-not-using-indexes} option is available 
for the purpose of logging queries that do not use indexes to the slow 
query log.

@item --log-queries-not-using-indexes
If you are using this option with @code{--log-slow-queries}, then
queries that are not using indexes also  are logged to the slow query log. This 
option is available as of MySQL 4.1. @xref{Slow query log}.

@item --log-short-format
Log less information to the log files (update log, binary update log, 
and slow queries log, whatever log has been activated). For example, 
username and timestamp are not logged for queries. This option was 
introduced in MySQL 4.1.

@item --log-slow-queries[=@var{file}]
Log all queries that have taken more than @code{long_query_time} seconds 
to execute to this file.
@xref{Slow query log}.
Note that the default for the amount of information 
logged has changed in MySQL 4.1. See the @code{--log-long-format} and 
@code{--log-short-format} options for details.

@item --log-update[=@var{file}]
Log updates to @var{file#} where @var{#} is a unique number if not
given. @xref{Update log}. The update log is deprecated and is
removed in MySQL 5.0.0; you should use the binary log instead
(@code{--log-bin}). @xref{Binary log}. Starting from version 5.0.0,
using @code{--log-update} will just turn on the binary log instead
(@pxref{News-5.0.0}).

@item --log-warnings, -W
Print out warnings such as @code{Aborted connection...} to the error log.
Enabling this option is recommended, for example, if you
use replication (you will get more information about what is happening,
such as messages about network failures and reconnections).
This option is enabled by default as of MySQL 4.0.19 and 4.1.2; to disable it,
use @code{--skip-log-warnings}.
As of MySQL 4.0.21 and 4.1.3, aborted connections are not logged to the error
log unless the value is greater than 1.
@xref{Communication errors}.

This option was named @code{--warnings} before MySQL 4.0.

@item --low-priority-updates
Table-modifying operations (@code{INSERT}, @code{REPLACE}, @code{DELETE}, @code{UPDATE})
will have lower priority than selects.  This can also be done via
@code{@{INSERT | REPLACE | DELETE | UPDATE@} LOW_PRIORITY ...} to lower
the priority of only one query, or by
@code{SET LOW_PRIORITY_UPDATES=1} to change the priority in one
thread.  @xref{Table locking}.

@item --memlock
Lock the @command{mysqld} process in memory.  This works on systems such as
Solaris that support the @code{mlockall()} system call.  This
might help if you have a problem where the operating system is causing
@command{mysqld} to swap on disk.
Note that use of this option requires that you run the server as @code{root},
which is normally not a good idea for security reasons.

@item --myisam-recover [=@var{option}[,@var{option}...]]]
Set the @code{MyISAM} storage engine recovery mode.
The option value is any combination of the values
of @code{DEFAULT}, @code{BACKUP}, @code{FORCE}, or @code{QUICK}.
If you specify multiple values, separate them by commas.
You can also use a value of @code{""} to disable this
option. If this option is used, @command{mysqld} will, when it opens a
@code{MyISAM} table, open check whether the
table is marked as crashed or wasn't closed properly.
(The last option works only if you are running with
@code{--skip-external-locking}.)  If this is the case, @command{mysqld} will run
a check on the table. If the table was corrupted, @command{mysqld} will
attempt to repair it.

The following options affect how the repair works:

@multitable @columnfractions .15 .7
@item @strong{Option} @tab @strong{Description}

@item @code{DEFAULT} @tab The same as not giving any option to
                    @code{--myisam-recover}.

@item @code{BACKUP} @tab If the data file was changed during recovery, save a
                    backup of the @file{@var{tbl_name}.MYD} file as
                    @file{@var{tbl_name-datetime}.BAK}.

@item @code{FORCE}  @tab Run recovery even if we will lose more than one row
                    from the @file{.MYD} file.

@item @code{QUICK}  @tab Don't check the rows in the table if there aren't any
                    delete blocks.

@end multitable

Before a table is automatically repaired, MySQL will add a note
about this in the error log.  If you want to be able to recover from most
problems without user intervention, you should use the options
@code{BACKUP,FORCE}.  This will force a repair of a table even if some rows
would be deleted, but it will keep the old data file as a backup so that
you can later examine what happened.

This option is available as of MySQL 3.23.25.

@item --ndb-connectstring=@var{connect_string}
When using the @code{NDB} storage engine, it is possible to point out the
management server that distributes the cluster configuration by setting the
connect string option. See @ref{MySQL Cluster Connectstring} for syntax.

@item --ndbcluster
If the binary includes support for the @code{NDB Cluster} storage engine 
(from version 4.1.3, the MySQL-Max binaries are built with @code{NDB Cluster} enabled)
the default disabling of support for the @code{NDB Cluster} storage engine can be
overruled by using this option. Using the @code{NDB Cluster} storage engine is
necessary for using MySQL Cluster.
@xref{NDBCluster}.

@item --new
The @code{--new} option can be used to make the server
behave as 4.1 in certain respects, easing a 4.0 to 4.1 upgrade:
@itemize @bullet
@item
Hexadecimal strings such as @code{0xFF} are treated as strings by
default rather than as numbers.  (Works in 4.0.12 and up.)
@item
@code{TIMESTAMP} is returned as a string with the format
@code{'YYYY-MM-DD HH:MM:SS'}.  (Works in 4.0.13 and up.)
@xref{Column types}.
@end itemize

This option can be used to help you see how your applications will behave in
MySQL 4.1, without actually upgrading to 4.1.

@item --pid-file=@var{path}
The path to the process ID file used by @command{mysqld_safe}.

@item --port=@var{port_num}, -P @var{port_num}
The port number to use when listening for TCP/IP connections.

@item --old-protocol, -o
Use the 3.20 protocol for compatibility with some very old clients.
@xref{Upgrading-from-3.20}.

@item --one-thread
Only use one thread (for debugging under Linux).
This option is available only if the server is built with debugging enabled.
@xref{Debugging server}.

@item --open-files-limit=@var{count}
To change the number of file descriptors available to @command{mysqld}.
If this is not set or set to 0, then @command{mysqld} will use this value
to reserve file descriptors to use with @code{setrlimit()}.  If this
value is 0 then @command{mysqld} will reserve @code{max_connections*5} or
@code{max_connections + table_cache*2} (whichever is larger) number of
files.  You should try increasing this if @command{mysqld} gives you the
error "Too many open files."

@item --safe-mode
Skip some optimization stages.

@item --safe-show-database
With this option, the @code{SHOW DATABASES} statement displays only the names
of those databases for which the user has some kind of privilege.
As of MySQL 4.0.2, this option is deprecated and doesn't do anything
(it is enabled by default), because there is now a @code{SHOW DATABASES}
privilege that can be used to control access to database
names on a per-account basis.
@xref{Privileges provided}.

@item --safe-user-create
If this is enabled, a user can't create new users with the @code{GRANT}
statement, if the user doesn't have the @code{INSERT} privilege for the
@code{mysql.user} table or any column in the table.

@item --secure-auth
Disallow authentication for accounts that have old (pre-4.1) passwords.
This option is available as of MySQL 4.1.1.

@item --shared-memory
Enable shared-memory connections by local clients. This option is available
only on Windows. It was added in MySQL 4.1.0.

@item --shared-memory-base-name=@var{name}
The name to use for shared-memory connections.  This option is available
only on Windows. It was added in MySQL 4.1.0.

@item --skip-bdb
Disable the @code{BDB} storage engine. This saves memory and might speed
up some operations.
Do not use this option if you require @code{BDB} tables.

@item --skip-concurrent-insert
Turn off the ability to select and insert at the same time on @code{MyISAM}
tables. (This is to be used only if you think you have found a bug in this
feature.)

@item --skip-delay-key-write
Ignore the @code{DELAY_KEY_WRITE} option for all tables.
As of MySQL 4.0.3, you should use @code{--delay-key-write=OFF} instead.
@xref{Server parameters}.

@item --skip-external-locking
Don't use system locking.  To use @command{isamchk} or @command{myisamchk},
you must shut down the server.  @xref{Stability}.  In MySQL 3.23, you
can use @code{CHECK TABLE} and @code{REPAIR TABLE} to check and repair
@code{MyISAM} tables.
This option previously was named @code{--skip-locking}.

@item --skip-grant-tables
This option causes the server not to use the privilege system at all. This
gives everyone @emph{full access} to all databases!  (You can tell a running
server to start using the grant tables again by executing a @command{mysqladmin
flush-privileges} or @command{mysqladmin reload} command, or by issuing a
@code{FLUSH PRIVILEGES} statement.)

@item --skip-host-cache
Do not use the internal hostname cache for faster name-to-IP resolution.
Instead, query the DNS server every time a client connects.
@xref{DNS}.

@item --skip-innodb
Disable the @code{InnoDB} storage engine.  This saves memory and disk
space and might speed up some operations.
Do not use this option if you require @code{InnoDB} tables.

@item --skip-isam
Disable the @code{ISAM} storage engine.  As of MySQL 4.1, @code{ISAM} is
disabled by default, so this option applies only if the server was configured
with support for @code{ISAM}.
This option was added in MySQL 4.1.1.

@item --skip-name-resolve
Do not resolve hostnames when checking client connections. Use only IP
numbers. If you use this option, all @code{Host} column values in the
grant tables must be IP numbers or @code{localhost}.  @xref{DNS}.

@item --skip-ndbcluster
Disable the @code{NDB Cluster} storage engine. This is the default for binaries
that were built with @code{NDB Cluster} storage engine support, this means that
the system will only allocate memory and other resources for this storage engine
if it is explicitly enabled.

@item --skip-networking
Don't listen for TCP/IP connections at all.  All interaction with
@command{mysqld} must be made via named pipes or shared memory (on Windows) or Unix socket files
(on Unix).  This option is highly recommended for systems where only local
clients are allowed.  @xref{DNS}.

@item --skip-new
Don't use new, possibly wrong routines.

@item --skip-symlink
This is the old form of @code{--skip-symbolic-links}, for use before MySQL
4.0.13.

@item --symbolic-links, --skip-symbolic-links
Enable or disable symbolic link support. This option has different effects on
Windows and Unix:

@itemize @bullet
@item
On Windows, enabling symbolic links allows you to establish a symbolic
link to a database directory by creating a
@code{directory.sym} file that contains the path to the real directory.
@xref{Windows symbolic links}.

@item
On Unix, enabling symbolic links means that you can link a
@code{MyISAM} index file or data file to another directory with
the @code{INDEX DIRECTORY} or @code{DATA DIRECTORY} options of the
@code{CREATE TABLE} statement.  If you delete or rename the table,
the files that its symbolic links point to also are deleted or
renamed. @xref{CREATE TABLE,  , @code{CREATE TABLE}}.
@end itemize

This option was added in MySQL 4.0.13.

@item --skip-safemalloc
If MySQL is configured with @code{--with-debug=full}, all MySQL programs
check for memory overruns during each memory allocation and memory
freeing operation.  This checking is very slow, so for the server you
can avoid it when you don't need it by using the @code{--skip-safemalloc}
option.

@item --skip-show-database
With this option, the @code{SHOW DATABASES} statement is allowed only to
users who have the @code{SHOW DATABASES} privilege, and the statement
displays all database names.  Without this option, @code{SHOW DATABASES} is
allowed to all users, but displays each database name only if the user has
the @code{SHOW DATABASES} privilege or some privilege for the database.

@item --skip-stack-trace
Don't write stack traces.  This option is useful when you are running
@command{mysqld} under a debugger. On some systems, you also must use
this option to get a core file. @xref{Debugging server}.

@item --skip-thread-priority
Disable using thread priorities for faster response time.

@item --socket=@var{path}
@c Put the Unix description first, because the option name relates directly
@c to the Unix meaning. Putting the Windows meaning first makes this more
@c confusing.
On Unix, this option specifies the Unix socket file to
use for local connections. The default value is @file{/tmp/mysql.sock}.
On Windows, the option specifies the pipe name to use for local connections
that use a named pipe. The default value is @code{MySQL}.

@c TODO: some of these option values currently are unimplemented.
@c Need to say which ones.

@item --sql-mode=@var{value}[,@var{value}[,@var{value}...]]
Set the SQL mode for MySQL. @xref{Server SQL mode}. This option was added in 3.23.41.

@item --temp-pool
This option causes most temporary files created by the
server to use a small set of names, rather than a unique name for
each new file. This works around a problem in the Linux kernel
dealing with creating many
new files with different names. With the old behavior, Linux seems to
``leak'' memory, because it's being allocated to the directory entry cache
rather than to the disk cache.

@item --transaction-isolation=@var{level}
Sets the default transaction isolation level, which can be
@code{READ-UNCOMMITTED},
@code{READ-COMMITTED},
@code{REPEATABLE-READ}, or
@code{SERIALIZABLE}.
@xref{SET TRANSACTION, , @code{SET TRANSACTION}}.

@item --tmpdir=@var{path}, -t @var{path}
The path of the directory to use for creating temporary files. It might be
useful if your default @code{/tmp} directory resides on a partition that
is too small to hold temporary tables.  Starting from MySQL 4.1, this
option accepts several paths that are used in round-robin fashion. Paths
should be separated by colon characters (@samp{:}) on Unix and semicolon
characters (@samp{;}) on Windows, NetWare, and OS/2.
If the MySQL server is acting as a replication slave, you should not set
@code{--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 @code{LOAD DATA INFILE} operations. If
files in the temporary file directory are lost when the server restarts,
replication will fail.

@item --user=@{@var{user_name} | @var{user_id}@}, -u @{@var{user_name} | @var{user_id}@}
Run the @command{mysqld} server as the user having the name @var{user_name} or
the numeric user ID @var{user_id}.
(``User'' in this context refers to a system login account, not a MySQL user
listed in the grant tables.)

This option is @emph{mandatory} when starting @command{mysqld} as @code{root}.
The server will change its user ID during its startup sequence, causing it
to run as that particular user rather than as @code{root}.
@xref{Security guidelines}.

Starting from MySQL 3.23.56 and 4.0.12:
To avoid a possible security hole where a user adds a @code{--user=root}
option to some @file{my.cnf} file (thus causing the server to run as
@code{root}), @command{mysqld} uses only the first
@code{--user} option specified and produces a warning if there are multiple
@code{--user} options. Options in @file{/etc/my.cnf} and
@file{datadir/my.cnf} are processed before
command-line options, so it is recommended that you
put a @code{--user} option in @file{/etc/my.cnf} and specify a value other than
@code{root}. The option in @file{/etc/my.cnf} will be found before any other
@code{--user} options, which ensures that the server runs as a user other
than @code{root}, and that a warning results if any other @code{--user} option
is found.

@item --version, -V
Display version information and exit.

@end table

As of MySQL 4.0,
you can assign a value to a server system variable by using an option of
the form @code{--@var{var_name}=@var{value}}. For example, @code{--key_buffer_size=32M}
sets the @code{key_buffer_size} variable to a value of 32MB.

Note that when setting a variable to a value, MySQL might automatically
correct it to stay within a given range, or adjust the value to the
closest allowable value if only certain values are allowed.

It is also possible to set variables by using
@code{--set-variable=@var{var_name}=@var{value}} or @code{-O @var{var_name}=@var{value}}
syntax. However, this syntax is deprecated as of MySQL 4.0.

You can find a full description for all variables in @ref{Server system
variables}.  The section on tuning server parameters includes information
on how to optimize them.  @xref{Server parameters}.

You can change the values of most system variables for a running server with the
@code{SET} statement. @xref{SET OPTION, , @code{SET OPTION}}.

If you want to restrict the maximum value that a startup option can be set to
with @code{SET}, you can define this by using the
@code{--maximum-@var{var_name}} command-line option.


@node Server SQL mode, Server system variables, Server options, Configuring MySQL
@subsection The Server SQL Mode

The MySQL server can operate in different SQL modes, and (as of MySQL 4.1)
can apply these modes differentially for different clients. This allows
an application to tailor server operation to its own requirements.

Modes define what SQL syntax MySQL should support and what kind of data
validation checks it should perform.  This makes it easier to use MySQL in
different environments and to use MySQL together with other database servers.

You can set the default SQL mode by starting @command{mysqld} with the
@code{--sql-mode="@var{modes}"} option.  The value also can be empty
(@code{--sql-mode=""}) if you want to reset it.

Beginning with MySQL 4.1, you can also change the SQL mode after startup time
by setting the @code{sql_mode} variable with a @code{SET [SESSION|GLOBAL]
sql_mode='@var{modes}'} statement.  Setting the @code{GLOBAL} variable
requires the @code{SUPER} privilege and affects the operation of all clients
that connect from that time on. Setting the @code{SESSION} variable affects
only the current client.  Any client can change its session @code{sql_mode}
value.

@var{modes} is a list of different modes separated
by comma (@samp{,}) characters.  You can retrieve the current mode by
issuing a @code{SELECT @@@@sql_mode} statement. The default value is empty
(no modes set).


The most important @code{sql_mode} values are probably these:

@table @code

@item ANSI
@cindex ANSI SQL mode
Change syntax and behavior to be more conformant to standard SQL.
(New in MySQL 4.1.1)

@item STRICT_TRANS_TABLES
@cindex STRICT_TRANS_TABLES SQL mode
If a value could not be inserted as given into a transactional table, abort
the statement.  For a non-transactional table, abort the statement if the
value occurs in a single-row statement or the first row of a multiple-row
statement. More detail is given later in this section.
(New in MySQL 5.0.2)

@item TRADITIONAL
@cindex TRADITONAL SQL mode
Make MySQL behave like a ``traditional'' SQL database system.  A simple
description of this mode is ``give an error instead of a warning''
when inserting an incorrect value into a column.  @strong{Note}: The
@code{INSERT}/@code{UPDATE} will abort as soon as the error is noticed.
This may not be what you want if you are using a non-transactional storage
engine, because data changes made prior to the error will not be rolled
back, resulting in a ``partially-done'' update.  (New in MySQL 5.0.2)

@end table

@cindex STRICT SQL mode
When this manual refers to ``strict mode,'' it means a mode where at least
one of @code{STRICT_TRANS_TABLES} or @code{STRICT_ALL_TABLES} is enabled.

The following list describes all the supported modes:

@c TODO: add this when it gets pushed:
@c NO_AUTO_CREATE_USER: GRANT statements don't automatically create accounts
@c in the user table. Enabled by MAXDB and TRADITIONAL composite modes.

@table @code

@item ALLOW_INVALID_DATES
@cindex ALLOW_INVALID_DATES SQL mode
Don't do full checking of dates in strict mode. Check only that the month is
in the range from 1 to 12 and the day is in the range from 1 to 31. This
is 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).  This mode applies to @code{DATE}
and @code{DATETIME} columns. It does not apply @code{TIMESTAMP} columns,
which always require a valid date.

This mode is new in MySQL 5.0.2. Before 5.0.2, this was the default MySQL
date-handling mode. As of 5.0.2, enabling strict mode causes the server to
require that month and day values be legal, not just in the range from 1
to 12 and 1 to 31. For example, @code{'2004-04-31'} is legal with strict
mode disabled, but illegal with strict mode enabled. To allow such dates
in strict mode, enable @code{ALLOW_INVALID_DATES} as well.

@item ANSI_QUOTES
@cindex ANSI_QUOTES SQL mode
Treat @samp{"} as an identifier quote character (like the
@samp{`} quote character) and not as a string quote character. You can still
use @samp{`} to quote identifers in ANSI mode. With @code{ANSI_QUOTES}
enabled, you cannot use double quotes to quote a literal string, because it
will be interpreted as an identifier.
(New in MySQL 4.0.0)

@item HIGH_NOT_PRECEDENCE
@cindex HIGH_NOT_PRECEDENCE SQL mode
From MySQL 5.0.2 on, the @code{NOT} operator precedence is handled
so that expressions such as
@code{NOT a BETWEEN b AND c} are parsed as
@code{NOT (a BETWEEN b AND c)}.
Before MySQL 5.0.2, the expression is parsed as
@code{(NOT a) BETWEEN b AND c}.
The old higher-precedence behavior can be obtained by enabling the
@code{HIGH_NOT_PRECEDENCE} SQL mode.
(New in MySQL 5.0.2)

@example
mysql> SET sql_mode = '';
mysql> SELECT NOT 1 BETWEEN -5 AND 5;
        -> 0
mysql> SET sql_mode = 'broken_not';
mysql> SELECT NOT 1 BETWEEN -5 AND 5;
        -> 1
@end example

@item ERROR_FOR_DIVISION_BY_ZERO
@cindex ERROR_FOR_DIVISION_BY_ZERO SQL mode
Produce an error in strict mode (otherwise a warning) when we
encounter a division by zero (or @code{MOD(X,0)}) during an @code{INSERT}/
@code{UPDATE}. If this mode is not given, MySQL instead returns
@code{NULL} for divisions by zero.  If used with @code{IGNORE}, MySQL
generates a warning for divisions by zero, but the result of the operation is
@code{NULL}.
(New in MySQL 5.0.2)

@item IGNORE_SPACE
@cindex IGNORE_SPACE SQL mode
Allow spaces between a function name and the @samp{(} character.  This forces
all function names to be treated as reserved words. As a result, if you want
to access any database, table, or column name that is a reserved word, you
must quote it.  For example, because there is a @code{USER()} function, the
name of the @code{user} table in the @code{mysql} database and the @code{User}
column in that table become reserved, so you must quote them:

@example
SELECT "User" FROM mysql."user";
@end example

(New in MySQL 4.0.0)

@item NO_AUTO_CREATE_USER
@cindex NO_AUTO_CREATE_USER SQL mode
Prevent @code{GRANT} from automatically creating new users if it would
otherwise do so, unless a password also is specified.
(New in MySQL 5.0.2)

@item NO_AUTO_VALUE_ON_ZERO
@cindex NO_AUTO_VALUE_ON_ZERO SQL mode
@code{NO_AUTO_VALUE_ON_ZERO} affects handling of @code{AUTO_INCREMENT}
columns. Normally, you generate the next sequence number for the column by
inserting either @code{NULL} or @code{0} into it.
@code{NO_AUTO_VALUE_ON_ZERO} suppresses this behavior for @code{0} so that
only @code{NULL} generates the next sequence number.
(New in MySQL 4.1.1)

This mode can be useful if @code{0} has been stored in a table's
@code{AUTO_INCREMENT} column. (This is not a recommended practice, by
the way.)  For example, if you dump the table with @command{mysqldump}
and then reload it, MySQL normally generates new sequence numbers when
it encounters the @code{0} values, resulting in a table with different
contents than the one that was dumped. Enabling @code{NO_AUTO_VALUE_ON_ZERO}
before reloading the dump file solves this problem. As of MySQL 4.1.1,
@command{mysqldump} automatically includes a statement in the dump output
to enable @code{NO_AUTO_VALUE_ON_ZERO}.

@item NO_DIR_IN_CREATE
@cindex NO_DIR_IN_CREATE SQL mode
When creating a table, ignore all @code{INDEX DIRECTORY} and @code{DATA
DIRECTORY} directives. This option is useful on slave replication servers.
(New in MySQL 4.0.15)

@item NO_FIELD_OPTIONS
@cindex NO_FIELD_OPTIONS SQL mode
Don't print MySQL-specific column options in the output of @code{SHOW CREATE
TABLE}. This mode is used by @command{mysqldump} in portability mode.
(New in MySQL 4.1.1)

@item NO_KEY_OPTIONS
@cindex NO_KEY_OPTIONS SQL mode
Don't print MySQL-specific index options in the output of @code{SHOW CREATE
TABLE}. This mode is used by @command{mysqldump} in portability mode.
(New in MySQL 4.1.1)

@item NO_TABLE_OPTIONS
@cindex NO_TABLE_OPTIONS SQL mode
Don't print MySQL-specific table options (such as @code{ENGINE}) in the
output of @code{SHOW CREATE TABLE}. This mode is used by @command{mysqldump} in
portability mode.
(New in MySQL 4.1.1)

@item NO_ZERO_DATE
@cindex NO_ZERO_DATE SQL mode
Don't allow @code{'0000-00-00'} as a valid date. You can still insert zero
dates with the @code{IGNORE} option.
(New in MySQL 5.0.2)

@item NO_ZERO_IN_DATE
@cindex NO_ZERO_IN_DATE SQL mode
Don't accept dates where the month or day part is 0. If used with the
@code{IGNORE} option, we insert a @code{'0000-00-00'} date for any such date.
(New in MySQL 5.0.2)

@item NO_UNSIGNED_SUBTRACTION
@cindex NO_UNSIGNED_SUBTRACTION SQL mode
In subtraction operations, don't mark the result as @code{UNSIGNED} if one
of the operands is unsigned. Note that this makes @code{UNSIGNED BIGINT} not
100% usable in all contexts. @xref{Cast Functions}.
(New in MySQL 4.0.2)

@item ONLY_FULL_GROUP_BY
@cindex ONLY_FULL_GROUP_BY SQL mode
Don't allow queries that in the @code{GROUP BY} part refer to a not
selected column.
(New in MySQL 4.0.0)

@item PIPES_AS_CONCAT
@cindex PIPES_AS_CONCAT SQL mode
Treat @code{||} as a string concatenation operator (same as @code{CONCAT()})
rather than as a synonym for @code{OR}.
(New in MySQL 4.0.0)

@item REAL_AS_FLOAT
@cindex REAL_AS_FLOAT SQL mode
Treat @code{REAL} as a synonym for @code{FLOAT} rather than as a synonym for
@code{DOUBLE}.
(New in MySQL 4.0.0)

@item STRICT_ALL_TABLES
@cindex STRICT_ALL_TABLES SQL mode
Enable strict mode for all storage engines.  Invalid data values are rejected.
Additional detail follows.
(New in MySQL 5.0.2)

@item STRICT_TRANS_TABLES
@cindex STRICT_TRANS_TABLES SQL mode
Enable strict mode for transactional storage engines, and when possible for
non-transactional storage engines.  Additional detail follows.
(New in MySQL 5.0.2)

@end table

Strict mode controls how MySQL handles values that are invalid or missing. A
value can be invalid for several reasons.  For example, it might have
the wrong data type for the column, or it might be out of range. A value
is missing when a new row to be inserted does not contain a value for a
column that has no explicit @code{DEFAULT} clause in its definition.

For transactional tables, an error occurs for invalid or missing
values in a statement when either of the @code{STRICT_ALL_TABLES} or
@code{STRICT_TRANS_TABLES} modes are enabled.  The statement is aborted
and rolled back.

For non-transactional tables, the behavior is the same for either mode,
if the bad value occurs in the first row to be inserted or updated.
The statement is aborted and the table remains unchanged.  If the statement
inserts or modifies multiple rows and the bad value occurs in the second or
later row, the result depends on which strict option is enabled:

@itemize @bullet

@item
For @code{STRICT_ALL_TABLES}, MySQL returns an error and ignores the
rest of the rows. However, in this case, the earlier rows will already
have been inserted or updated.  This means that you might get a partial
update, which might not be what you want.  To avoid this, it's best to
use single-row statements because these can be aborted without changing the
table.

@item
For @code{STRICT_TRANS_TABLES}, MySQL converts an invalid value to the
closest valid value for the column and insert the adjusted value. If a
value is missing, MySQL inserts the implicit default value for the column
data type.  In either case, MySQL generates a warning rather than an error
and continues processing the statement. Implicit defaults are described in
@ref{CREATE TABLE,  , @code{CREATE TABLE}}.

@end itemize

Strict mode disallows invalid date values such as @code{'2004-04-31'}.
It does not disallow dates with zero parts such as @code{2004-04-00'} or
``zero'' dates. To disallow these as well, enable the @code{NO_ZERO_IN_DATE}
and @code{NO_ZERO_DATE} SQL modes in addition to strict mode.

If you are not using strict mode (that is, neither @code{STRICT_TRANS_TABLES}
nor @code{STRICT_ALL_TABLES} is enabled), MySQL inserts adjusted values
for invalid or missing values and produces warnings.  In strict mode, you can
produce this behavior by using @code{INSERT IGNORE} or @code{UPDATE IGNORE}.
@xref{SHOW WARNINGS,  , @code{SHOW WARNINGS}}.

The following special modes are provided as shorthand for combinations of
mode values from the preceding list.  All are available as of MySQL 4.1.1,
except @code{TRADITIONAL} (5.0.2).

The descriptions include all mode values that are available in the most
recent version of MySQL.  For older versions, a combination mode does not
include individual mode values that are not available except in newer
versions.

@table @code

@item ANSI
@cindex ANSI SQL mode
Equivalent to
@code{REAL_AS_FLOAT}, @code{PIPES_AS_CONCAT}, @code{ANSI_QUOTES}, @code{IGNORE_SPACE}, @code{ONLY_FULL_GROUP_BY}. @xref{ANSI mode}.

@item DB2
@cindex DB2 SQL mode
Equivalent to
@code{PIPES_AS_CONCAT}, @code{ANSI_QUOTES}, @code{IGNORE_SPACE}, @code{NO_KEY_OPTIONS}, @code{NO_TABLE_OPTIONS}, @code{NO_FIELD_OPTIONS}.

@item MAXDB
@cindex MAXDB SQL mode
Equivalent to
@code{PIPES_AS_CONCAT}, @code{ANSI_QUOTES}, @code{IGNORE_SPACE}, @code{NO_KEY_OPTIONS}, @code{NO_TABLE_OPTIONS}, @code{NO_FIELD_OPTIONS}, @code{NO_AUTO_CREATE_USER}.

@item MSSQL
@cindex MSSQL SQL mode
Equivalent to
@code{PIPES_AS_CONCAT}, @code{ANSI_QUOTES}, @code{IGNORE_SPACE}, @code{NO_KEY_OPTIONS}, @code{NO_TABLE_OPTIONS}, @code{NO_FIELD_OPTIONS}.

@item MYSQL323
@cindex MYSQL323 SQL mode
Equivalent to
@code{NO_FIELD_OPTIONS}, @code{HIGH_NOT_PRECEDENCE}.

@item MYSQL40
@cindex MYSQL40 SQL mode
Equivalent to
@code{NO_FIELD_OPTIONS}, @code{HIGH_NOT_PRECEDENCE}.

@item ORACLE
@cindex ORACLE SQL mode
Equivalent to
@code{PIPES_AS_CONCAT}, @code{ANSI_QUOTES}, @code{IGNORE_SPACE}, @code{NO_KEY_OPTIONS}, @code{NO_TABLE_OPTIONS}, @code{NO_FIELD_OPTIONS}, @code{NO_AUTO_CREATE_USER}.

@item POSTGRESQL
@cindex POSTGRESQL SQL mode
Equivalent to
@code{PIPES_AS_CONCAT}, @code{ANSI_QUOTES}, @code{IGNORE_SPACE}, @code{NO_KEY_OPTIONS}, @code{NO_TABLE_OPTIONS}, @code{NO_FIELD_OPTIONS}.

@item TRADITIONAL
@cindex TRADITIONAL SQL mode
Equivalent to
@code{STRICT_TRANS_TABLES}, @code{STRICT_ALL_TABLES}, @code{NO_ZERO_IN_DATE}, @code{NO_ZERO_DATE}, @code{ERROR_FOR_DIVISION_BY_ZERO}, @code{NO_AUTO_CREATE_USER}.
@end table


@c TODO: not a great node name; there is also a System Variables node.

@node Server system variables, Server status variables, Server SQL mode, Configuring MySQL
@subsection Server System Variables

@cindex system variables
@cindex server variables
@cindex variables, server
@cindex variables, system

@menu
* Dynamic System Variables::    Dynamic System Variables
@end menu


The server maintains many system variables that indicate how it is configured.
All of them have default values. They can be set at server startup
using options on the command line or in option
files. Most of them can be set at runtime using the
@code{SET} statement.

@c NOTE: next few paragraphs also appear in @node System Variables.
@c If you make changes one place, change them both.

Beginning with MySQL 4.0.3,
the @command{mysqld} server maintains two kinds of variables.
Global variables affect the overall operation of the server.
Session variables affect its operation for individual client connections.

When the server starts, it initializes all global variables to their default
values. These defaults can be changed by options specified in option files
or on the command line.  After the server starts, those global variables
that are dynamic can be changed by connecting to the server and issuing
a @code{SET GLOBAL @var{var_name}} statement. To change a global variable,
you must have the @code{SUPER} privilege.

The server also maintains a set of session variables for each client
that connects. The client's session variables are initialized at connect
time using the current values of the corresponding global variables. For
those session variables that are dynamic, the client can change them
by issuing a @code{SET SESSION @var{var_name}} statement. Setting a session
variable requires no special privilege, but a client can change only its
own session variables, not those of any other client.

A change to a global variable is visible to any client that accesses that
global variable. However, it affects the corresponding session variable
that is initialized from the global variable only for clients that connect
after the change.  It does not affect the session variable for any client
that is already connected (not even that of the client that issues the
@code{SET GLOBAL} statement).

When setting a variable using a startup option, variable values can be given
with a suffix of @code{K}, @code{M}, or @code{G} to indicate kilobytes,
megabytes, or gigabytes, respectively. For example, the following command
starts the server with a key buffer size of 16 megabytes:

@example
mysqld --key_buffer_size=16M
@end example

Before MySQL 4.0, use this syntax instead:

@example
mysqld --set-variable=key_buffer_size=16M
@end example

The lettercase of suffix letters does not matter; @code{16M} and @code{16m} are
equivalent.

At runtime, use the @code{SET} statement to set system variables. In this
context, suffix letters cannot be used, but the value can take the form of an
expression:

@example
mysql> SET sort_buffer_size = 10 * 1024 * 1024;
@end example

To specify explicitly whether to set the global or session variable, use the
@code{GLOBAL} or @code{SESSION} options:

@example
mysql> SET GLOBAL sort_buffer_size = 10 * 1024 * 1024;
mysql> SET SESSION sort_buffer_size = 10 * 1024 * 1024;
@end example

Without either option, the statement sets the session variable.

The variables that can be set at runtime are listed in
@ref{Dynamic System Variables}.

If you want to restrict the maximum value to which a system variable can
be set with the @code{SET} statement, you can specify this maximum
by using an option of the form @code{--maximum-@var{var_name}} at server
startup. For example, to prevent the value of @code{query_cache_size}
from being increased to more than 32MB at runtime, use the option
@code{--maximum-query_cache_size=32M}. This feature is available as of MySQL
4.0.2.

You can view system variables and their values by using the
@code{SHOW VARIABLES} statement.
See @ref{System Variables} for more information.

@example
mysql> SHOW VARIABLES;
+---------------------------------+------------------------------+
| Variable_name                   | Value                        |
+---------------------------------+------------------------------|
| back_log                        | 50                           |
| basedir                         | /usr/local/mysql             |
| bdb_cache_size                  | 8388572                      |
| bdb_home                        | /usr/local/mysql             |
| bdb_log_buffer_size             | 32768                        |
| bdb_logdir                      |                              |
| bdb_max_lock                    | 10000                        |
| bdb_shared_data                 | OFF                          |
| bdb_tmpdir                      | /tmp/                        |
| bdb_version                     | Sleepycat Software: ...      |
| binlog_cache_size               | 32768                        |
| bulk_insert_buffer_size         | 8388608                      |
| character_set                   | latin1                       |
| character_sets                  | latin1 big5 czech euc_kr     |
| concurrent_insert               | ON                           |
| connect_timeout                 | 5                            |
| convert_character_set           |                              |
| datadir                         | /usr/local/mysql/data/       |
| default_week_format             | 0                            |
| delay_key_write                 | ON                           |
| delayed_insert_limit            | 100                          |
| delayed_insert_timeout          | 300                          |
| delayed_queue_size              | 1000                         |
| flush                           | OFF                          |
| flush_time                      | 0                            |
| ft_boolean_syntax               | + -><()~*:""&|               |
| ft_max_word_len                 | 84                           |
| ft_min_word_len                 | 4                            |
| ft_query_expansion_limit        | 20                           |
| ft_stopword_file                | (built-in)                   |
| have_bdb                        | YES                          |
| have_innodb                     | YES                          |
| have_isam                       | YES                          |
| have_openssl                    | YES                          |
| have_query_cache                | YES                          |
| have_raid                       | NO                           |
| have_symlink                    | DISABLED                     |
| init_file                       |                              |
| innodb_additional_mem_pool_size | 1048576                      |
| innodb_buffer_pool_size         | 8388608                      |
| innodb_data_file_path           | ibdata1:10M:autoextend       |
| innodb_data_home_dir            |                              |
| innodb_fast_shutdown            | ON                           |
| innodb_file_io_threads          | 4                            |
| innodb_flush_log_at_trx_commit  | 1                            |
| innodb_flush_method             |                              |
| innodb_force_recovery           | 0                            |
| innodb_lock_wait_timeout        | 50                           |
| innodb_log_arch_dir             |                              |
| innodb_log_archive              | OFF                          |
| innodb_log_buffer_size          | 1048576                      |
| innodb_log_file_size            | 5242880                      |
| innodb_log_files_in_group       | 2                            |
| innodb_log_group_home_dir       | ./                           |
| innodb_mirrored_log_groups      | 1                            |
| innodb_thread_concurrency       | 8                            |
| interactive_timeout             | 28800                        |
| join_buffer_size                | 131072                       |
| key_buffer_size                 | 16773120                     |
| key_cache_age_threshold         | 300                          |
| key_cache_block_size            | 1024                         |
| key_cache_division_limit        | 100                          |
| language                        | /usr/local/mysql/share/...   |
| large_files_support             | ON                           |
| local_infile                    | ON                           |
| locked_in_memory                | OFF                          |
| log                             | OFF                          |
| log_bin                         | OFF                          |
| log_slave_updates               | OFF                          |
| log_slow_queries                | OFF                          |
| log_update                      | OFF                          |
| log_warnings                    | 1                            |
| long_query_time                 | 10                           |
| low_priority_updates            | OFF                          |
| lower_case_table_names          | 0                            |
| max_allowed_packet              | 1047552                      |
| max_binlog_cache_size           | 4294967295                   |
| max_binlog_size                 | 1073741824                   |
| max_connect_errors              | 10                           |
| max_connections                 | 100                          |
| max_delayed_threads             | 20                           |
| max_error_count                 | 64                           |
| max_heap_table_size             | 16777216                     |
| max_join_size                   | 4294967295                   |
| max_relay_log_size              | 0                            |
| max_sort_length                 | 1024                         |
| max_tmp_tables                  | 32                           |
| max_user_connections            | 0                            |
| max_write_lock_count            | 4294967295                   |
| myisam_max_extra_sort_file_size | 268435456                    |
| myisam_max_sort_file_size       | 2147483647                   |
| myisam_recover_options          | force                        |
| myisam_repair_threads           | 1                            |
| myisam_sort_buffer_size         | 8388608                      |
| net_buffer_length               | 16384                        |
| net_read_timeout                | 30                           |
| net_retry_count                 | 10                           |
| net_write_timeout               | 60                           |
| open_files_limit                | 1024                         |
| pid_file                        | /usr/local/mysql/name.pid    |
| port                            | 3306                         |
| protocol_version                | 10                           |
| query_cache_limit               | 1048576                      |
| query_cache_size                | 0                            |
| query_cache_type                | ON                           |
| read_buffer_size                | 131072                       |
| read_rnd_buffer_size            | 262144                       |
| rpl_recovery_rank               | 0                            |
| server_id                       | 0                            |
| skip_external_locking           | ON                           |
| skip_networking                 | OFF                          |
| skip_show_database              | OFF                          |
| slave_net_timeout               | 3600                         |
| slow_launch_time                | 2                            |
| socket                          | /tmp/mysql.sock              |
| sort_buffer_size                | 2097116                      |
| sql_mode                        |                              |
| table_cache                     | 64                           |
| table_type                      | MYISAM                       |
| thread_cache_size               | 3                            |
| thread_stack                    | 131072                       |
| timezone                        | EEST                         |
| tmp_table_size                  | 33554432                     |
| tmpdir                          | /tmp/:/mnt/hd2/tmp/          |
| tx_isolation                    | READ-COMMITTED               |
| version                         | 4.0.4-beta                   |
| wait_timeout                    | 28800                        |
+---------------------------------+------------------------------+
@end example

@cindex variables, values

Most system variables are described here.  Variables with no version
indicated have been present since at least MySQL 3.22.  @code{InnoDB} system
variables are listed at
@ref{InnoDB start,  , @code{InnoDB} start}.

Values for buffer sizes, lengths, and stack sizes are given in bytes unless
otherwise specified.

Information on tuning these variables can be found in @ref{Server parameters}.

@table @code

@item ansi_mode
This is @code{ON} if @command{mysqld} was started with @code{--ansi}.
@xref{ANSI mode}.
This variable was added in MySQL 3.23.6 and removed in 3.23.41.
See the description for @code{sql_mode}.

@item back_log
The number of outstanding connection requests MySQL can have. This
comes into play when the main MySQL thread gets very
many connection requests in a very short time. It then takes some time
(although very little) for the main thread to check the connection and start
a new thread. The @code{back_log} value indicates how many requests can be
stacked during this short time before MySQL momentarily stops
answering new requests. You need to increase this only if you expect a large
number of connections in a short period of time.

In other words, this value is the size of the listen queue for incoming
TCP/IP connections.  Your operating system has its own limit on the size
of this queue.  The manual page for the Unix @code{listen()} system
call should have more details.  Check your OS documentation for the
maximum value for this variable.  Attempting to set @code{back_log}
higher than your operating system limit will be ineffective.

@item basedir
The MySQL installation base directory. This variable can be set with the
@code{--basedir} option.

@item bdb_cache_size
The size of the buffer that is allocated for caching indexes and rows for
@code{BDB} tables.  If you don't use @code{BDB} tables, you should start
@command{mysqld} with @code{--skip-bdb} to not waste memory for this cache.
This variable was added in MySQL 3.23.14.

@item bdb_home
The base directory for @code{BDB} tables.  This should be assigned the same
value as the @code{datadir} variable.
This variable was added in MySQL 3.23.14.

@item bdb_log_buffer_size
The size of the buffer that is allocated for caching indexes and rows for
@code{BDB} tables.  If you don't use @code{BDB} tables, you should set this
to 0 or start @command{mysqld} with @code{--skip-bdb} to not waste memory for
this cache.
This variable was added in MySQL 3.23.31.

@item bdb_logdir
The directory where the @code{BDB} storage engine writes its log files.
This variable can be set with the @code{--bdb-logdir} option.
This variable was added in MySQL 3.23.14.

@item bdb_max_lock
The maximum number of locks you can have active on a @code{BDB} table
(10,000 by default). You should increase this if errors such as the
following occur when you perform long transactions or when @command{mysqld} has
to examine many rows to calculate a query:

@example
bdb: Lock table is out of available locks
Got error 12 from ...
@end example

This variable was added in MySQL 3.23.29.

@item bdb_shared_data
This is @code{ON} if you are using @code{--bdb-shared-data}.
This variable was added in MySQL 3.23.29.

@item bdb_tmpdir
The value of the @code{--bdb-tmpdir} option.
This variable was added in MySQL 3.23.14.

@item bdb_version
See the description for @code{version_bdb}.

@item binlog_cache_size
The size of the cache to hold the SQL statements for the binary log during
a transaction.  A binary log cache is allocated for each client if the
server supports any transactional storage engines and, starting from MySQL
4.1.2, if the server has binary log enabled (@code{--log-bin} option). If you
often use big, multiple-statement transactions, you can increase this to get
more performance.
The @code{Binlog_cache_use} and @code{Binlog_cache_disk_use} status variables
can be useful for tuning the size of this variable.
This variable was added in MySQL 3.23.29.
@xref{Binary log}.

@item bulk_insert_buffer_size
@code{MyISAM} uses a special tree-like cache to make bulk inserts faster for
@code{INSERT ... SELECT}, @code{INSERT ... VALUES (...), (...), ...}, and
@code{LOAD DATA INFILE}. This variable limits
the size of the cache tree in bytes per thread. Setting it to 0
disables this optimization.
@strong{Note}: This cache is used only when adding data to a non-empty table.
The default value is 8MB.
This variable was added in MySQL 4.0.3.
This variable previously was named @code{myisam_bulk_insert_tree_size}.

@item character_set
The default character set.
This variable was added in MySQL 3.23.3, then
removed in MySQL 4.1.1 and replaced by the various
@code{character_set_@var{xxx}} variables.

@item character_set_client
The character set for statements that arrive from the client.
This variable was added in MySQL 4.1.1.

@item character_set_connection
The character set used for literals that do not have a character set
introducer and for number-to-string conversion.
This variable was added in MySQL 4.1.1.

@item character_set_database
The character set used by the default database.
The server sets this variable whenever the default database changes.
If there is no default database, the variable has the same value as
@code{character_set_server}.
This variable was added in MySQL 4.1.1.

@item character_set_results
The character set used for returning query results to the client.
This variable was added in MySQL 4.1.1.

@item character_set_server
The server default character set.
This variable was added in MySQL 4.1.1.

@item character_set_system
The character set used by the server for storing identifiers.
The value is always @code{utf8}.
This variable was added in MySQL 4.1.1.

@item character_sets
The supported character sets.
This variable was added in MySQL 3.23.15 and removed in MySQL 4.1.1.
(Use @code{SHOW CHARACTER SET} for a list of character sets.)

@item character_sets_dir
The directory where character sets are installed.
This variable was added in MySQL 4.1.2.

@item collation_connection
The collation of the connection character set.
This variable was added in MySQL 4.1.1.

@item collation_database
The collation used by the default database.
The server sets this variable whenever the default database changes.
If there is no default database, the variable has the same value as
@code{collation_server}.
This variable was added in MySQL 4.1.1.

@item collation_server
The server default collation.
This variable was added in MySQL 4.1.1.

@item concurrent_insert
If @code{ON} (the default), MySQL allows @code{INSERT} and @code{SELECT}
statements to run concurrently for @code{MyISAM} tables that have no free
blocks in the middle.  You can turn this option off by starting
@command{mysqld} with @code{--safe} or @code{--skip-new}.
This variable was added in MySQL 3.23.7.

@item connect_timeout
@cindex timeout
The number of seconds the @command{mysqld} server waits for a connect
packet before responding with @code{Bad handshake}.

@item convert_character_set
The current character set mapping that was set by @code{SET CHARACTER SET}.
This variable was removed in MySQL 4.1.

@item datadir
The MySQL data directory. This variable can be set with the
@code{--datadir} option.

@c TODO: uncomment when implemented
@c @item date_format
@c ADD DESCRIPTION

@c TODO: uncomment when implemented
@c @item datetime_format
@c ADD DESCRIPTION

@item default_week_format
The default mode value to use for the @code{WEEK()} function.
This variable is available as of MySQL 4.0.14.

@item delay_key_write
This option applies only to @code{MyISAM} tables. It can have one of the
following values to affect handling of the @code{DELAY_KEY_WRITE} table
option that can be used in @code{CREATE TABLE} statements.

@multitable @columnfractions .10 .75

@item @strong{Option} @tab @strong{Description}

@item @code{OFF} @tab @code{DELAYED_KEY_WRITE} is ignored.

@item @code{ON}  @tab MySQL honors the @code{DELAY_KEY_WRITE} option
for @code{CREATE TABLE}. This is the default value.

@item @code{ALL} @tab All new opened tables are treated as if they were
created with the @code{DELAY_KEY_WRITE} option enabled.

@end multitable

If @code{DELAY_KEY_WRITE} is enabled, this means that the key buffer for
tables with this option are not flushed on every index update, but
only when a table is closed.  This will speed up writes on keys a lot,
but if you use this feature, you should add automatic checking of all
@code{MyISAM} tables by starting the server with the @code{--myisam-recover}
option (for example, @code{--myisam-recover=BACKUP,FORCE}).
See @ref{Server options} and @ref{MyISAM start}.

Note that @code{--external-locking} doesn't offer any protection against
index corruption for tables that use delayed key writes.

This variable was added in MySQL 3.23.8.

@item delayed_insert_limit
After inserting @code{delayed_insert_limit} delayed rows, the @code{INSERT
DELAYED} handler thread checks whether there are any @code{SELECT}
statements pending. If so, it allows them to execute before continuing to
insert delayed rows.

@item delayed_insert_timeout
How long an @code{INSERT DELAYED} handler thread should wait for
@code{INSERT} statements before terminating.

@item delayed_queue_size
This is a per-table limit on the number of
rows to queue when handling @code{INSERT DELAYED}
statements.  If the queue becomes full, any client that issues an
@code{INSERT DELAYED} statement will wait until there is room in the queue
again.

@item expire_logs_days
The number of days for automatic binary log removal.
The default is 0, which means ``no automatic removal''. Possible removals
happen at startup and at binary log rotation.
This variable was added in MySQL 4.1.0.

@item flush
This is @code{ON} if you have started @command{mysqld} with the @code{--flush}
option.
This variable was added in MySQL 3.22.9.

@item flush_time
If this is set to a non-zero value, all tables will be closed every
@code{flush_time} seconds to free up resources and sync unflushed data to
disk.  We recommend this option only on Windows 9x or Me, or on systems
with minimal resources available.
This variable was added in MySQL 3.22.18.

@item ft_boolean_syntax
The list of operators supported by boolean full-text searches performed using
@code{IN BOOLEAN MODE}.
This variable was added in MySQL 4.0.1.
@xref{Fulltext Boolean}.

The default variable value is @code{'+ -><()~*:""&|'}. The rules for
changing the value are as follows:

@itemize @bullet
@item
Operator function is determined by position within the string.

@item
The replacement value must be 14 characters.

@item
Each character must be an ASCII non-alphanumeric character.

@item
Either the first or second character must be a space.

@item
No duplicates are allowed except the phrase quoting operators in positions
11 and 12. These two characters are not required to be the same, but they
are the only two that may be.

@item
Positions 10, 13, and 14 (which by default are set to @samp{:}, @samp{&}, and
@samp{|}) are reserved for future extensions.

@end itemize

@item ft_max_word_len
The maximum length of the word to be included in a @code{FULLTEXT} index.
This variable was added in MySQL 4.0.0.

@strong{Note}: @code{FULLTEXT} indexes must be rebuilt after changing
this variable.
Use @code{REPAIR TABLE @var{tbl_name} QUICK}.

@item ft_min_word_len
The minimum length of the word to be included in a @code{FULLTEXT} index.
This variable was added in MySQL 4.0.0.

@strong{Note}: @code{FULLTEXT} indexes must be rebuilt after changing
this variable.
Use @code{REPAIR TABLE @var{tbl_name} QUICK}.

@item ft_query_expansion_limit
The number of top matches to use for full-text searches performed using
@code{WITH QUERY EXPANSION}.
This variable was added in MySQL 4.1.1.

@item ft_stopword_file
The file from which to read the list of stopwords for full-text searches.
All the words from the file are used; comments are @emph{not} honored.
By default, a built-in list of stopwords is used (as defined in the
@file{myisam/ft_static.c} file).  Setting this variable to the empty string
(@code{''}) disables stopword filtering.  This variable was added in
MySQL 4.0.10.

@strong{Note}: @code{FULLTEXT} indexes must be rebuilt after changing
this variable.
Use @code{REPAIR TABLE @var{tbl_name} QUICK}.

@item group_concat_max_len
The maximum allowed result length for the @code{GROUP_CONCAT()} function.
This variable was added in MySQL 4.1.0.

@item have_archive
@code{YES} if @command{mysqld} supports @code{ARCHIVE} tables, @code{NO}
if not.  This variable was added in MySQL 4.1.3.

@item have_bdb
@code{YES} if @command{mysqld} supports @code{BDB} tables. @code{DISABLED}
if @code{--skip-bdb} is used.
This variable was added in MySQL 3.23.30.

@item have_compress
Whether the @code{zlib} compression library is available to the server.
If not, the @code{COMPRESS()} and @code{UNCOMPRESS()} functions cannot be
used.
This variable was added in MySQL 4.1.1.

@item have_crypt
Whether the @code{crypt()} system call is available to the server.
If not, the @code{CRYPT()} function cannot be used.
This variable was added in MySQL 4.0.10.

@item have_csv
@code{YES} if @command{mysqld} supports @code{ARCHIVE} tables, @code{NO}
if not.  This variable was added in MySQL 4.1.4.

@item have_example_engine
@code{YES} if @command{mysqld} supports @code{EXAMPLE} tables, @code{NO}
if not.  This variable was added in MySQL 4.1.4.

@item have_geometry
Whether the server supports spatial data types.
This variable was added in MySQL 4.1.3.

@item have_innodb
@code{YES} if @command{mysqld} supports @code{InnoDB} tables. @code{DISABLED}
if @code{--skip-innodb} is used.
This variable was added in MySQL 3.23.37.

@item have_isam
@code{YES} if @command{mysqld} supports @code{ISAM} tables. @code{DISABLED}
if @code{--skip-isam} is used.
This variable was added in MySQL 3.23.30.

@item have_ndbcluster
@code{YES} if @command{mysqld} supports @code{NDB Cluster} tables.
@code{DISABLED} if @code{--skip-ndbcluster} is used.
This variable was added in MySQL 4.1.2.

@item have_openssl
@code{YES} if @command{mysqld} supports SSL (encryption) of the client/server
protocol.
This variable was added in MySQL 3.23.43.

@item have_query_cache
@code{YES} if @command{mysqld} supports the query cache.
This variable was added in MySQL 4.0.2.

@item have_raid
@code{YES} if @command{mysqld} supports the @code{RAID} option.
This variable was added in MySQL 3.23.30.

@item have_rtree_keys
Whether @code{RTREE} indexes are available. (These are used for spatial
indexed in @code{MyISAM} tables.)
This variable was added in MySQL 4.1.3.

@item have_symlink
Whether symbolic link support is enabled. This is required on Unix for
support of the @code{DATA DIRECTORY} and @code{INDEX DIRECTORY} table options.
@c TODO: also used on Windows for dir symlinking?
This variable was added in MySQL 4.0.0.

@c TODO: it may be that init_connect/init_slave should be discussed in
@c a separate section that describes how to control client/slave startup.
@c Move the examples to such a section if it is written.

@item init_connect
A string to be executed by the server for each client that connects.
The string consists of one or more SQL statements. To specify multiple
statements, separate them by semicolon characters.
For example, each client begins by default with autocommit mode enabled.
There is no global server variable to specify that autocommit should be
disabled by default, but @code{init_connect} can be used to achieve the
same effect:

@example
SET GLOBAL init_connect='SET AUTOCOMMIT=0';
@end example

This variable can also be set on the command line or in an option file.
To set the variable as just shown using an option file, include these
lines:

@example
[mysqld]
init_connect='SET AUTOCOMMIT=0'
@end example

Note that the content of @code{init_connect} is not executed for users having
the @code{SUPER} privilege; this is in case that content has been wrongly set
(contains a wrong query, for example with a syntax error),
thus making all connections fail. Not executing it for @code{SUPER} users
enables those to open a connection and fix @code{init_connect}.
This variable was added in MySQL 4.1.2.

@item init_file
The name of the file specified with the @code{--init-file} option when you
start the server.  This is a file containing SQL statements that you want
the server to execute when it starts.
Each statement must be on a single line and should not include comments.
This variable was added in MySQL 3.23.2.

@item init_slave
This variable is similar to @code{init_connect}, but is a string to be
executed by a slave server each time the SQL thread starts.  The format of
the string is the same as for the @code{init_connect} variable.
This variable was added in MySQL 4.1.2.

@item innodb_@var{xxx}
The @code{InnoDB} system variables are listed at
@ref{InnoDB start,  , @code{InnoDB} start}.

@item interactive_timeout
The number of seconds the server waits for activity on an interactive
connection before closing it.  An interactive client is defined as a
client that uses the @code{CLIENT_INTERACTIVE} option to
@code{mysql_real_connect()}.  See also @code{wait_timeout}.

@item join_buffer_size
The size of the buffer that is used for full joins (joins that do not use
indexes).  Normally the best way to get fast joins is to add indexes.
Increase the value of @code{join_buffer_size} to get a faster full join when
adding indexes is not possible.  One join buffer is allocated for each full
join between two tables. For a complex join between several tables for which
indexes are not used, multiple join buffers might be necessary.

@c Make texi2html support index @anchor{Index cache size}. Then change
@c some xrefs to point here

@item key_buffer_size
@cindex indexes, block size
Index blocks for @code{MyISAM} and @code{ISAM} tables are buffered and are
shared by all threads.  @code{key_buffer_size} is the size of the buffer
used for index blocks.  The key buffer is also known as the key cache.

The maximum allowable setting for @code{key_buffer_size} is 4GB. The
effective maximum size might be less, depending on your available
physical RAM and per-process RAM limits imposed by your operating
system or hardware platform.

Increase the value to get better index handling (for all reads and multiple
writes) to as much as you can afford. Using a value that is 25% of total
memory on a machine that mainly runs MySQL is quite common.  However, if you
make the value too large (for example, more than 50% of your total memory)
your system might start to page and become extremely slow.  MySQL relies on
the operating system to perform filesystem caching for data reads, so you
must leave some room for the filesystem cache.

For even more speed when writing many rows at the same time, use
@code{LOCK TABLES}.  @xref{LOCK TABLES, , @code{LOCK TABLES}}.

You can check the performance of the key buffer by issuing a @code{SHOW
STATUS} statement and examining the @code{Key_read_requests},
@code{Key_reads}, @code{Key_write_requests}, and @code{Key_writes} status
variables.
@xref{SHOW, , @code{SHOW}}.

The @code{Key_reads/Key_read_requests} ratio should normally be
less than 0.01.  The @code{Key_writes/Key_write_requests} ratio is usually
near 1 if you are using mostly updates and deletes, but might be much
smaller if you tend to do updates that affect many rows at the same time or
if you are using the @code{DELAY_KEY_WRITE} table option.

The fraction of the key buffer in use can be determined using
@code{key_buffer_size} in conjunction with the @code{Key_blocks_used} status
variable and the buffer block size.  From MySQL 4.1.1 on, the buffer block
size is available from the @code{key_cache_block_size} server variable. The
fraction of the buffer in use is:

@example
(Key_blocks_used * key_cache_block_size) / key_buffer_size
@end example

Before MySQL 4.1.1, key cache blocks are 1024 bytes, so the fraction of the
key buffer in use is:

@example
(Key_blocks_used * 1024) / key_buffer_size
@end example

@xref{MyISAM key cache,  , @code{MyISAM} key cache}.

@item key_cache_age_threshold
This value controls the demotion of buffers from the hot sub-chain of a key
cache to the warm sub-chain.
Lower values cause demotion to happen more quickly.
The minimum value is 100.
The default value is 300.
This variable was added in MySQL 4.1.1.
@xref{MyISAM key cache,  , @code{MyISAM} key cache}.

@item key_cache_block_size
The size in bytes of blocks in the key cache.
The default value is 1024.
This variable was added in MySQL 4.1.1.
@xref{MyISAM key cache,  , @code{MyISAM} key cache}.

@item key_cache_division_limit
The division point between the hot and warm sub-chains of the key cache
buffer chain. The value is the percentage of the buffer chain to use for
the warm sub-chain.  Allowable values range from 1 to 100.
The default value is 100.
This variable was added in MySQL 4.1.1.
@xref{MyISAM key cache,  , @code{MyISAM} key cache}.

@item language
The language used for error messages.

@item large_file_support
Whether @command{mysqld} was compiled with options for large file support.
This variable was added in MySQL 3.23.28.

@item license
The type of license the server has.
This variable was added in MySQL 4.0.19.

@item local_infile
Whether @code{LOCAL} is supported for @code{LOAD DATA INFILE} statements.
This variable was added in MySQL 4.0.3.

@item locked_in_memory
Whether @command{mysqld} was locked in memory with @code{--memlock}.
This variable was added in MySQL 3.23.25.

@item log
Whether logging of all queries to the general query log is enabled.
@xref{Query log}.

@item log_bin
Whether the binary log is enabled.
This variable was added in MySQL 3.23.14.
@xref{Binary log}.

@item log_error
The location of the error log.
This variable was added in MySQL 4.0.10.

@item log_slave_updates
Whether updates received by a slave server from a master server should be
logged to the slave's own binary log. Binary logging must be enabled on the
slave for this to have any effect.
This variable was added in MySQL 3.23.17.
@xref{Replication Options}.

@item log_slow_queries
Whether slow queries should be logged.  ``Slow'' is determined by the value
of the @code{long_query_time} variable.
This variable was added in MySQL 4.0.2.
@xref{Slow query log}.

@item log_update
Whether the update log is enabled.  This variable was added in MySQL 3.22.18.
Note that the binary log is preferable to the update log, which
is unavailable as of MySQL 5.0.
@xref{Update log}.

@item log_warnings
Whether to produce additional warning messages.
This variable was added in MySQL 4.0.3.
It is enabled by default as of MySQL 4.0.19 and 4.1.2.
As of MySQL 4.0.21 and 4.1.3, aborted connections are not logged to the error
log unless the value is greater than 1.

@item long_query_time
If a query takes longer than this many seconds, the @code{Slow_queries}
status variable is incremented. If you are using the
@code{--log-slow-queries} option, the query is logged to the slow query log
file. This value is measured in real time, not CPU time, so a query that is
under the threshold on a lightly loaded system might be above the threshold
on a heavily loaded one.
@xref{Slow query log}.

@item low_priority_updates
If set to @code{1}, all @code{INSERT}, @code{UPDATE}, @code{DELETE}, and
@code{LOCK TABLE WRITE} statements wait until there is no pending
@code{SELECT} or @code{LOCK TABLE READ} on the affected table.
This variable previously was named @code{sql_low_priority_updates}.
It was added in MySQL 3.22.5.

@item lower_case_file_system
This variable indicates whether the filesystem where the data directory is
located has case insensitive filenames.  @code{ON} means filenames are case
insensitive, @code{OFF} means they are case sensitive.  This variable was
added in MySQL 4.0.19.

@item lower_case_table_names
If set to 1, table names are stored in lowercase on disk and table name
comparisons are not case sensitive.  This variable was added in MySQL 3.23.6.
If set to 2 (new in 4.0.18), table names are stored as given but compared
in lowercase.  From MySQL 4.0.2, this option also applies to database names.
From 4.1.1, it also applies to table aliases.
@xref{Name case sensitivity}.

You should @emph{not} set this variable to 0 if you are running
MySQL on a system that does not have case-sensitive filenames (such as
Windows or Mac OS X).  New in 4.0.18:  If this variable is not set at
startup and the
filesystem on which the data directory is located does not have
case-sensitive filenames, MySQL automatically sets
@code{lower_case_table_names} to 2.

@item max_allowed_packet
The maximum size of one packet or any generated/intermediate string.

The packet message buffer is initialized to @code{net_buffer_length}
bytes, but can grow up to @code{max_allowed_packet} bytes when needed.
This value by default is small, to catch big (possibly wrong) packets.

You must increase this value if you are using big @code{BLOB} columns or
long strings. It should be as big as the biggest @code{BLOB} you want to
use.  The protocol limit for @code{max_allowed_packet} is 16MB before
MySQL 4.0 and 1GB thereafter.

@item max_binlog_cache_size
If a multiple-statement transaction requires more than this amount of memory,
you will get the error @code{Multi-statement transaction required more than
'max_binlog_cache_size' bytes of storage}.
This variable was added in MySQL 3.23.29.

@item max_binlog_size
If a write to the binary log exceeds the given value, rotate the binary
logs.  You cannot set this variable to more than 1GB or to less than 4096
bytes.  (The minimum before MYSQL 4.0.14 is 1024 bytes.) The default value
is 1GB.  This variable was added in MySQL 3.23.33.

Note if you are using transactions: A transaction is written in one chunk to
the binary log, hence it is never split between several binary logs.
Therefore, if you have big transactions, you might see binary logs bigger than
@code{max_binlog_size}.

If @code{max_relay_log_size} is 0, the value of @code{max_binlog_size}
applies to relay logs as well. @code{max_relay_log_size} was added in
MySQL 4.0.14.

@item max_connect_errors
If there are more than this number of interrupted connections from a host,
that host is blocked from further connections.  You can unblock blocked hosts
with the @code{FLUSH HOSTS} statement.

@item max_connections
The number of simultaneous client connections allowed. Increasing this value
increases the number of file descriptors that @command{mysqld} requires.  See
@ref{Table cache} for comments on file descriptor limits.
Also see @ref{Too many connections}.

@item max_delayed_threads
Don't start more than this number of threads to handle @code{INSERT DELAYED}
statements.  If you try to insert data into a new table after all @code{INSERT
DELAYED} threads are in use, the row will be inserted as if the
@code{DELAYED} attribute wasn't specified. If you set this to 0, MySQL
never creates a thread to handle @code{DELAYED} rows; in effect, this
disables @code{DELAYED} entirely.
This variable was added in MySQL 3.23.0.

@item max_error_count
The maximum number of error, warning, and note messages to be stored for
display by @code{SHOW ERRORS} or @code{SHOW WARNINGS}.
This variable was added in MySQL 4.1.0.

@item max_heap_table_size
This variable sets the maximum size to which @code{MEMORY} (@code{HEAP})
tables are allowed to grow.  The value of the variable is used to calculate
@code{MEMORY} table @code{MAX_ROWS} values.  Setting this variable has no
effect on any existing @code{MEMORY} table, unless the table is re-created
with a statement such as @code{CREATE TABLE} or @code{TRUNCATE TABLE}, or
altered with @code{ALTER TABLE}.
This variable was added in MySQL 3.23.0.

@item max_insert_delayed_threads
This variable is a synonym for @code{max_delayed_threads}.
It was added in MySQL 4.0.19.

@item max_join_size
Don't allow @code{SELECT} statements that probably will need to examine
more than @code{max_join_size} row combinations or are likely to do more
than @code{max_join_size} disk seeks.  By setting this value, you can catch
@code{SELECT} statements where keys are not used properly and that would
probably take a long time.  Set it if your users tend to perform joins
that lack a @code{WHERE} clause, that take a long time, or that return
millions of rows.

Setting this variable to a value other than @code{DEFAULT} resets
the @code{SQL_BIG_SELECTS} value to @code{0}.  If you set the
@code{SQL_BIG_SELECTS} value again, the @code{max_join_size} variable
is ignored.

If a query result already is in the query cache, no result size
check is performed, because the result has already been computed and it does
not burden the server to send it to the client.

This variable previously was named @code{sql_max_join_size}.

@item max_length_for_sort_data
The cutoff on the size of index values that determines which @code{filesort}
algorithm to use.
@xref{ORDER BY optimization,  , @code{ORDER BY} optimization}.
This variable was added in MySQL 4.1.1

@item max_relay_log_size
If a write by a replication slave to its relay log exceeds the given value,
rotate the relay log.  This variable enables you to put different size
constraints on relay logs and binary logs.  However, setting the variable to
0 makes MySQL use @code{max_binlog_size} for both binary logs and relay
logs.  You must set @code{max_relay_log_size} to between 4096 bytes and 1GB
(inclusive), or to 0. The default value is 0.  This variable was added in
MySQL 4.0.14.
@xref{Replication Implementation Details}.

@item max_seeks_for_key
Limit the assumed maximum number of seeks when looking up rows based on
a key.  The MySQL optimizer will assume that no more than this number of
key seeks will be required when searching for matching rows in a table
by scanning a key, regardless of the actual cardinality of the key
(@pxref{SHOW INDEX}). By setting this to a low value (100?), you can force
MySQL to prefer keys instead of table scans.

This variable was added in MySQL 4.0.14.

@item max_sort_length
The number of bytes to use when sorting @code{BLOB} or @code{TEXT}
values. Only the first @code{max_sort_length} bytes of each value
are used; the rest are ignored.

@item max_tmp_tables
The maximum number of temporary tables a client can keep open at the same time.
(This option doesn't yet do anything.)

@item max_user_connections
The maximum number of simultaneous connections allowed to any given MySQL
account.  A value of 0 means ``no limit.''
This variable was added in MySQL 3.23.34.

@item max_write_lock_count
After this many write locks, allow some read locks to run in between.
This variable was added in MySQL 3.23.7.

@item myisam_data_pointer_size
The default pointer size in bytes, to be used by @code{CREATE TABLE} for
@code{MyISAM} tables when no @code{MAX_ROWS} option is specified.  This
variable cannot be less than 2 or larger than 8.  The default value is 4.
This variable was added in MySQL 4.1.2.
@xref{Full table, @code{myisam_data_pointer_size}}.

@item myisam_max_extra_sort_file_size
If the temporary file used for fast @code{MyISAM} index creation would be
larger than using the key cache by the amount specified here, prefer the key
cache method.  This is mainly used to force long character keys in large
tables to use the slower key cache method to create the index.
This variable was added in MySQL 3.23.37.
@strong{Note}: The value is given in megabytes before 4.0.3 and
in bytes thereafter.

@item myisam_max_sort_file_size
The maximum size of the temporary file MySQL is allowed to use while
re-creating a @code{MyISAM} index (during @code{REPAIR TABLE}, @code{ALTER
TABLE}, or @code{LOAD DATA INFILE}).  If the file size would be bigger than
this value, the index will be created using the key cache instead, which is
slower.
This variable was added in MySQL 3.23.37.
@strong{Note}: The value is given in megabytes before 4.0.3 and
in bytes thereafter.

@item myisam_recover_options
The value of the @code{--myisam-recover} option.
This variable was added in MySQL 3.23.36.

@item myisam_repair_threads
If this value is greater than 1, @code{MyISAM} table indexes are created in
parallel (each index in its own thread) during the @code{Repair by sorting}
process.  The default value is 1.  @strong{Note}: Multi-threaded repair is
still @emph{alpha} quality code.
This variable was added in MySQL 4.0.13.

@item myisam_sort_buffer_size
The buffer that is allocated when sorting @code{MyISAM} indexes during a
@code{REPAIR TABLE} or when creating indexes with @code{CREATE INDEX} or
@code{ALTER TABLE}.
This variable was added in MySQL 3.23.16.

@item named_pipe
On Windows, indicates whether the server supports connections over named
pipes.
This variable was added in MySQL 3.23.50.

@item net_buffer_length
The communication buffer is reset to this size between queries. This should
not normally be changed, but if you have very little memory, you can set it
to the expected length of SQL statements sent by clients.  If statements
exceed this length, the buffer is automatically enlarged, up to
@code{max_allowed_packet} bytes.

@item net_read_timeout
The number of seconds to wait for more data from a connection before
aborting the read.
When the server is reading from the client, @code{net_read_timeout} is the
timeout value controlling when to abort.
When the server is writing to the client, @code{net_write_timeout} is the
timeout value controlling when to abort.
See also @code{slave_net_timeout}.
This variable was added in MySQL 3.23.20.

@item net_retry_count
If a read on a communication port is interrupted, retry this many times
before giving up.  This value should be set quite high on FreeBSD because
internal interrupts are sent to all threads.
This variable was added in MySQL 3.23.7.

@item net_write_timeout
The number of seconds to wait for a block to be written to a connection before
aborting the write.
See also @code{net_read_timeout}.
This variable was added in MySQL 3.23.20.

@item new
This variable is used in MySQL 4.0 to turn on some 4.1 behaviors.
This variable was added in MySQL 4.0.12.

@item old_passwords
Whether the server should use pre-4.1-style passwords for MySQL user
accounts.
This variable was added in MySQL 4.1.1.

@item open_files_limit
The number of files that the operating system allows @command{mysqld} to open.
This is the real value allowed by the system and might be different from the
value you gave @command{mysqld} as a startup option.  The value is 0 on systems
where MySQL can't change the number of open files.  This variable was added
in MySQL 3.23.20.

@item optimizer_prune_level

Controls the heuristics applied during query optimization to prune
less-promising partial plans from the optimizer search space. A value of 0
disables heuristics so that the optimizer performs an exhaustive search. A
value of 1 causes the optimizer to prune plans based on the number of rows
retrieved by intermediate plans.  This variable was added in MySQL 5.0.1.

@item optimizer_search_depth

The maximum depth of search performed by the query optimizer. Values larger
than the number of relations in a query result in better query plans, but
take longer to generate an execution plan for a query. Values smaller than
the number of relations in a query return an execution plan quicker, but
the resulting plan may be far from being optimal. If set to 0, the system
automatically picks a reasonable value. If set to the maximum number of
tables used in a query plus 2, the optimizer switches to the original
algorithm used before MySQL 5.0.1 that performs an exhaustive search.
This variable was added in MySQL 5.0.1.

@item pid_file
The pathname of the process ID (PID) file. This variable can be set
with the @code{--pid-file} option.
This variable was added in MySQL 3.23.23.

@item port
The port on which the server listens for TCP/IP connections.  This variable
can be set with the @code{--port} option.

@item preload_buffer_size
The size of the buffer that is allocated when preloading indexes.
This variable was added in MySQL 4.1.1.

@item protocol_version
The version of the client/server protocol used by the MySQL server.
This variable was added in MySQL 3.23.18.

@item query_alloc_block_size
The allocation size of memory blocks that are allocated for objects created
during query parsing and execution. If you have problems with memory
fragmentation, it might help to increase this a bit.  This variable was added
in MySQL 4.0.16.

@item query_cache_limit
Don't cache results that are bigger than this. The default value is 1MB.
This variable was added in MySQL 4.0.1.

@item query_cache_min_res_unit
The minimum size for blocks allocated by the query cache.
The default value is 4KB. Tuning information for this variable
is given in @ref{Query Cache Configuration}.
This variable is present from MySQL 4.1.

@item query_cache_size
The amount of memory allocated for caching query results.  The default value
is 0, which disables the query cache.  Note that this amount of memory will
be allocated even if @code{query_cache_type} is set to 0.
This variable was added in MySQL 4.0.1.

@item query_cache_type
Set query cache type. Setting the @code{GLOBAL} value sets the type for all
clients that connect thereafter. Individual clients can set the
@code{SESSION} value to affect their own use of the query cache.

@multitable @columnfractions .15 .70

@item @strong{Option} @tab @strong{Description}

@item @code{0} or @code{OFF} @tab Don't cache or retrieve results.
Note that this will not deallocate the query cache buffer. To
do that, you should set @code{query_cache_size} to 0.

@item @code{1} or @code{ON} @tab Cache all query results except for those that
begin with @code{SELECT SQL_NO_CACHE}.

@item @code{2} or @code{DEMAND} @tab Cache results only for queries that
begin with @code{SELECT SQL_CACHE}.

@end multitable

This variable was added in MySQL 4.0.3.

@item query_cache_wlock_invalidate
Normally, when one client acquires a @code{WRITE} lock on a @code{MyISAM}
table, other clients are not blocked from issuing queries for the table if
the query results are present in the query cache. Setting this variable to
1 causes acquisition of a @code{WRITE} lock for a table to invalidate
any queries in the query cache that refer to the table. This forces other
clients that attempt to access the table to wait while the lock is in effect.
This variable was added in MySQL 4.0.19.

@item query_prealloc_size
The size of the persistent buffer used for query parsing and execution.
This buffer is not freed between queries.
If you are running complex queries, a larger @code{query_prealloc_size} value
might be helpful in improving performance, because it can reduce the need for
the server to perform memory allocation during query execution operations.
@c It won't necessarily eliminate allocation completely; server *may* still
@c allocate memory in some situations, e.g., transaction-related or sp-related
@c ops.
This variable was added in MySQL 4.0.16.

@item range_alloc_block_size
The size of blocks that are allocated when doing range optimization.
This variable was added in MySQL 4.0.16.

@item read_buffer_size
Each thread that does a sequential scan allocates a buffer of this
size for each table it scans. If you do many sequential scans, you might
want to increase this value.
This variable was added in MySQL 4.0.3.
Previously, it was named @code{record_buffer}.

@item read_only
When the variable is set to @code{ON} for a replication slave server, it
causes the slave to allow no updates except from slave threads or from users
with the @code{SUPER} privilege.  This can be useful to ensure that a slave
server accepts no updates from clients.
This variable was added in MySQL 4.0.14.

@item relay_log_purge
Disables or enables automatic purging of relay logs as soon as they are not
needed any more.  The default value is 1 (enabled).
This variable was added in MySQL 4.1.1.

@item read_rnd_buffer_size
When reading rows in sorted order after a sort, the rows are read through
this buffer to avoid disk seeks.  Setting the variable to a large value can
improve @code{ORDER BY} performance by a lot.  However, this is a buffer
allocated for each client, so you should not set the global variable to a
large value. Instead, change the session variable only from within those
clients that need to run large queries.
This variable was added in MySQL 4.0.3.
Previously, it was named @code{record_rnd_buffer}.

@item safe_show_database
Don't show databases for which the user has no database or
table privileges. This can improve security if you're concerned about
people being able to see what databases other users have. See also
@code{skip_show_database}.

This variable was removed in MySQL 4.0.5. Instead, use the @code{SHOW
DATABASES} privilege to control access by MySQL accounts to database names.

@item secure_auth
If the MySQL server has been started with the @code{--secure-auth} option,
it blocks connections from all accounts that have passwords stored in the old 
(pre-4.1) format. In that case, the value of this variable is @code{ON}, 
otherwise it is @code{OFF}.

You should enable this option if you want to prevent all usage of passwords
in old format (and hence insecure communication over the network).
This variable was added in MySQL 4.1.1.

Server startup will fail with an error if this option is enabled
and the privilege tables are in pre-4.1 format.

@c TODO: this doesn't really belong here in a discussion of server variables

When used as a client-side option, the client refuses to connect to a server
if the server requires a password in old format for the client account.

@item server_id
The value of the @code{--server-id} option. It is used for master and slave
replication servers.
This variable was added in MySQL 3.23.26.

@item shared_memory
Whether or not the server allows shared-memory connections.
Currently, only Windows servers support this.
This variable was added in MySQL 4.1.1.

@item shared_memory_base_name
Indicates whether or not the server allows shared-memory connections, and sets
the identifier for the shared memory. This is useful when running multiple MYSQL instances
on a single physical machine.
Currently, only Windows servers support this.
This variable was added in MySQL 4.1.0.

@item skip_external_locking
This is @code{OFF} if @command{mysqld} uses external locking.
This variable was added in MySQL 4.0.3.
Previously, it was named @code{skip_locking}.

@item skip_networking
This is @code{ON} if the server allows only local (non-TCP/IP) connections.
On Unix, local connections use a Unix socket file.  On Windows, local
connections use a named pipe or shared memory.  On NetWare, only TCP/IP connections are
supported, so do not set this variable to @code{ON}.
This variable was added in MySQL 3.22.23.

@item skip_show_database
This prevents people from using the @code{SHOW DATABASES} statement if they
don't have the @code{SHOW DATABASES} privilege. This can improve security if
you're concerned about people being able to see what databases other users
have. See also @code{safe_show_database}.
This variable was added in MySQL 3.23.4.  As of MySQL 4.0.2, its effect also
depends on the @code{SHOW DATABASES} privilege: If the variable value is
@code{ON}, the @code{SHOW DATABASES} statement is allowed only to users who
have the @code{SHOW DATABASES} privilege, and the statement displays all
database names.  If the value is @code{OFF}, @code{SHOW DATABASES} is
allowed to all users, but displays each database name only if the user has
the @code{SHOW DATABASES} privilege or some privilege for the database.

@item slave_compressed_protocol
Whether to use compression of the slave/master protocol if both the
slave and the master support it.
This variable was added in MySQL 4.0.3.

@item slave_net_timeout
The number of seconds to wait for more data from a master/slave connection
before aborting the read.
This variable was added in MySQL 3.23.40.

@item slow_launch_time
If creating a thread takes longer than this many seconds, the server
increments the @code{Slow_launch_threads} status variable.
This variable was added in MySQL 3.23.15.

@item socket
On Unix, this is the Unix socket file used for local client connections.  On
Windows, this is the name of the named pipe used for local client
connections.

@item sort_buffer_size
Each thread that needs to do a sort allocates a buffer of this
size. Increase this value for faster @code{ORDER BY} or @code{GROUP BY}
operations.
@xref{Temporary files}.

@item sql_mode
The current server SQL mode.
This variable was added in MySQL 3.23.41.
It can be set dynamically as of MySQL 4.1.1.
@xref{Server SQL mode}.

@item sql_slave_skip_counter
The number of events from the master that a slave server should skip.
It was added in MySQL 3.23.33.

@item storage_engine
This variable is a synonym for @code{table_type}.
It was added in MySQL 4.1.2.

@item sync_binlog
If positive, the MySQL server will synchronize its binary log to disk
(@code{fdatasync()}) after every @code{sync_binlog}'th write to this binary
log. Note that there is one write to the binary log per statement if in
autocommit mode, and otherwise one write per transaction. The default value is
0 which does no sync'ing to disk. A value of 1 is the safest choice, because in
case of crash you will lose at most one statement/transaction from the binary
log; but it is also the slowest choice (unless the disk has a battery-backed
cache, which makes sync'ing very fast). This variable was added in MySQL 4.1.3.

@item sync_frm
This was added as a command-line option in MySQL 4.0.18, and is also a settable
global variable since MySQL 4.1.3. If set to 1, when a non-temporary table is
created it will synchronize its @file{.frm} file to disk (@code{fdatasync()});
this is slower but safer in case of crash. Default is 1.

@item system_time_zone
The server system time zone. When the server begins executing, it inherits
a time zone setting from the machine defaults, possibly modified by the
environment of the account used for running the server or the startup script.
The value is used to set @code{system_time_zone}.  Typically the time zone
is specified by the @code{TZ} environment variable. It also can be specified
using the @code{--timezone} option of the @command{mysqld_safe} script.
This variable was added in MySQL 4.1.3.

@item table_cache
The number of open tables for all threads. Increasing this value
increases the number of file descriptors that @command{mysqld} requires.
You can check whether you need to increase the table cache by checking the
@code{Opened_tables} status variable.
@xref{Server status variables}.
If the value of @code{Opened_tables} is large and you don't do @code{FLUSH
TABLES} a lot (which just forces all tables to be closed and reopened),
then you should increase the value of the @code{table_cache} variable.

For more information about the table cache, see @ref{Table cache}.

@item table_type
The default table type (storage engine).
To set the table type at server startup, use the @code{--default-table-type}
option.
This variable was added in MySQL 3.23.0.
@xref{Server options}.

@item thread_cache_size
How many threads the server should cache for reuse.  When a client
disconnects, the client's threads are put in the cache if there aren't
already @code{thread_cache_size} threads there.  Requests for threads are
satisfied by reusing threads taken from the cache if possible, and only when
the cache is empty is a new thread created.  This variable can be increased
to improve performance if you have a lot of new connections. (Normally this
doesn't give a notable performance improvement if you have a good thread
implementation.)  By examining the difference between the @code{Connections}
and @code{Threads_created} status variables (@pxref{Server status variables}
for details) you can see how efficient the thread cache is.
This variable was added in MySQL 3.23.16.

@item thread_concurrency
On Solaris, @command{mysqld} calls @code{thr_setconcurrency()} with this value.
This function allows applications to give the threads system a hint about
the desired number of threads that should be run at the same time.
This variable was added in MySQL 3.23.7.

@item thread_stack
The stack size for each thread.  Many of the limits detected by the
@code{crash-me} test are dependent on this value. The default is
large enough for normal operation.  @xref{MySQL Benchmarks}.

@c TODO: uncomment when implemented
@c @item time_format
@c ADD DESCRIPTION

@item time_zone
The current time zone. The initial value of this is @code{'SYSTEM'}
(use the value of @code{system_time_zone}), but can be specified
explicitly at server startup time with the @code{--default-time-zone}
option.
This variable was added in MySQL 4.1.3.

@item timezone
The time zone for the server.  This is set from the @code{TZ} environment
variable when @command{mysqld} is started.  The time zone also can be set by
giving a @code{--timezone} argument to @command{mysqld_safe}.
This variable was added in MySQL 3.23.15. As of MySQL 4.1.3, it is obsolete
and has been replaced by the @code{system_time_zone} variable.
@xref{Timezone problems}.

@item tmp_table_size
If an in-memory temporary table exceeds this size, MySQL
automatically converts it to an on-disk @code{MyISAM} table.
Increase the value of @code{tmp_table_size} if you do many advanced
@code{GROUP BY} queries and you have lots of memory.

@item tmpdir
The directory used for temporary files and temporary tables.
Starting from MySQL 4.1, this variable can be set to a list of
several paths that are used in round-robin fashion. Paths
should be separated by colon characters (@samp{:}) on Unix and semicolon
characters (@samp{;}) on Windows, NetWare, and OS/2.

This feature can be used to
spread the load between several physical disks.
If the MySQL server is acting as a replication slave, you should not set
@code{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 @code{LOAD DATA INFILE} operations. If
files in the temporary file directory are lost when the server restarts,
replication will fail.

This variable was added in MySQL 3.22.4.

@item transaction_alloc_block_size
The allocation size of memory blocks that are allocated for storing queries
that are part of a transaction to be stored in the binary log when doing a
commit.  This variable was added in MySQL 4.0.16.

@item transaction_prealloc_size
The size of the persistent buffer for @code{transaction_alloc_blocks} that
is not freed between queries. By making this big enough to fit all queries
in a common transaction, you can avoid a lot of @code{malloc()} calls.  This
variable was added in MySQL 4.0.16.

@item tx_isolation
The default transaction isolation level.
This variable was added in MySQL 4.0.3.

@item updatable_views_with_limit
This variable controls whether updates can be made using a view that
does not contain a primary key in the underlying table, if the update contains
a @code{LIMIT} clause. (Such updates often are generated by GUI tools.)
An update is an @code{UPDATE} or @code{DELETE} statement.  Primary key
here means a @code{PRIMARY KEY}, or a @code{UNIQUE} index in which no column
can contain @code{NULL}.

The variable can have two values:

@itemize @bullet
@item
@code{1} or @code{YES}: Issue a warning only (not an error message).
This is the default value.
@item
@code{0} or @code{NO}: Prohibit the update.
@end itemize

This variable was added in MySQL 5.0.2.

@item version
The version number for the server.

@item version_bdb
The @code{BDB} storage engine version.
This variable was added in MySQL 3.23.31 with the name @code{bdb_version}
and renamed to @code{version_bdb} in MySQL 4.1.1.

@item version_comment
The @command{configure} script has a @code{--with-comment} option that
allows a comment to be specified when building MySQL.
This variable contains the value of that comment.
This variable was added in MySQL 4.0.17.

@item version_compile_machine
The type of machine MySQL was built on.
This variable was added in MySQL 4.1.1.

@item version_compile_os
The type of operating system MySQL was built on.
This variable was added in MySQL 4.0.19.

@item wait_timeout
The number of seconds the server waits for activity on a non-interactive
connection before closing it.

On thread startup, the session @code{wait_timeout} value is initialized from
the global @code{wait_timeout} value or from the global
@code{interactive_timeout} value, depending on the type of client (as
defined by the @code{CLIENT_INTERACTIVE} connect option to
@code{mysql_real_connect()}). See also @code{interactive_timeout}.

@end table


@node Dynamic System Variables,  , Server system variables, Server system variables
@subsubsection Dynamic System Variables

Beginning with MySQL 4.0.3, many server system variables are dynamic and can
be set at runtime using @code{SET GLOBAL} or @code{SET SESSION}. You can also
select their values using @code{SELECT}.
@xref{System Variables}.

The following table shows the full list of all dynamic system variables.
The last column indicates for each variable whether @code{GLOBAL} or
@code{SESSION} (or both) apply.

@c TODO: this list appears to have no InnoDB variables...which of those
@c can be set at runtime?

@multitable @columnfractions .45 .25 .30
@item @strong{Variable Name} @tab @strong{Value Type} @tab @strong{Type}
@item @code{autocommit} @tab boolean @tab @code{SESSION}
@item @code{big_tables} @tab boolean @tab @code{SESSION}
@item @code{binlog_cache_size} @tab numeric @tab @code{GLOBAL}
@item @code{bulk_insert_buffer_size} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{character_set_client} @tab string @tab @code{GLOBAL} | @code{SESSION}
@item @code{character_set_connection} @tab string @tab @code{GLOBAL} | @code{SESSION}
@c Don't advertise this variable as being dynamic...
@c @item @code{character_set_database} @tab string @tab @code{GLOBAL} | @code{SESSION}
@item @code{character_set_results} @tab string @tab @code{GLOBAL} | @code{SESSION}
@item @code{character_set_server} @tab string @tab @code{GLOBAL} | @code{SESSION}
@item @code{collation_connection} @tab string @tab @code{GLOBAL} | @code{SESSION}
@c Don't advertise this variable as being dynamic...
@c @item @code{collation_database} @tab string @tab @code{GLOBAL} | @code{SESSION}
@item @code{collation_server} @tab string @tab @code{GLOBAL} | @code{SESSION}
@item @code{concurrent_insert} @tab boolean @tab @code{GLOBAL}
@item @code{connect_timeout} @tab numeric @tab @code{GLOBAL}
@item @code{convert_character_set} @tab string @tab @code{GLOBAL} | @code{SESSION}
@c next one not listed in system variable section yet
@c @item @code{date_format} @tab string @tab @code{GLOBAL} | @code{SESSION}
@c next one not listed in system variable section yet
@c @item @code{datetime_format} @tab string @tab @code{GLOBAL} | @code{SESSION}
@item @code{default_week_format} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{delay_key_write} @tab @code{OFF} | @code{ON} | @code{ALL} @tab @code{GLOBAL}
@item @code{delayed_insert_limit} @tab numeric @tab @code{GLOBAL}
@item @code{delayed_insert_timeout} @tab numeric @tab @code{GLOBAL}
@item @code{delayed_queue_size} @tab numeric @tab @code{GLOBAL}
@item @code{error_count} @tab numeric @tab @code{SESSION}
@item @code{expire_logs_days} @tab numeric @tab @code{GLOBAL}
@item @code{flush} @tab boolean @tab @code{GLOBAL}
@item @code{flush_time} @tab numeric @tab @code{GLOBAL}
@item @code{foreign_key_checks} @tab boolean @tab @code{SESSION}
@item @code{ft_boolean_syntax} @tab numeric @tab @code{GLOBAL}
@item @code{group_concat_max_len} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{identity} @tab numeric @tab @code{SESSION}
@item @code{insert_id} @tab boolean @tab @code{SESSION}
@item @code{interactive_timeout} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{join_buffer_size} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{key_buffer_size} @tab numeric @tab @code{GLOBAL}
@c TODO: missing key_cache_xxx variables?
@item @code{last_insert_id} @tab numeric @tab @code{SESSION}
@item @code{local_infile} @tab boolean @tab @code{GLOBAL}
@item @code{log_warnings} @tab numeric @tab @code{GLOBAL}
@item @code{long_query_time} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{low_priority_updates} @tab boolean @tab @code{GLOBAL} | @code{SESSION}
@item @code{max_allowed_packet} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{max_binlog_cache_size} @tab numeric @tab @code{GLOBAL}
@item @code{max_binlog_size} @tab numeric @tab @code{GLOBAL}
@item @code{max_connect_errors} @tab numeric @tab @code{GLOBAL}
@item @code{max_connections} @tab numeric @tab @code{GLOBAL}
@item @code{max_delayed_threads} @tab numeric @tab @code{GLOBAL}
@item @code{max_error_count} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{max_heap_table_size} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{max_insert_delayed_threads} @tab numeric @tab @code{GLOBAL}
@item @code{max_join_size} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{max_relay_log_size} @tab numeric @tab @code{GLOBAL}
@item @code{max_seeks_for_key} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{max_sort_length} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{max_tmp_tables} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{max_user_connections} @tab numeric @tab @code{GLOBAL}
@item @code{max_write_lock_count} @tab numeric @tab @code{GLOBAL}
@item @code{myisam_data_pointer_size} @tab numeric @tab @code{GLOBAL}
@item @code{myisam_max_extra_sort_file_size} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{myisam_max_sort_file_size} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{myisam_repair_threads} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{myisam_sort_buffer_size} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{net_buffer_length} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{net_read_timeout} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{net_retry_count} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{net_write_timeout} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{old_passwords} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{optimizer_prune_level} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{optimizer_search_depth} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{preload_buffer_size} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{query_alloc_block_size} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{query_cache_limit} @tab numeric @tab @code{GLOBAL}
@item @code{query_cache_size} @tab numeric @tab @code{GLOBAL}
@item @code{query_cache_type} @tab enumeration @tab @code{GLOBAL} | @code{SESSION}
@item @code{query_cache_wlock_invalidate} @tab boolean @tab @code{GLOBAL} | @code{SESSION}
@item @code{query_prealloc_size} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{range_alloc_block_size} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{read_buffer_size} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{read_only} @tab numeric @tab @code{GLOBAL}
@item @code{read_rnd_buffer_size} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{rpl_recovery_rank} @tab numeric @tab @code{GLOBAL}
@item @code{safe_show_database} @tab boolean @tab @code{GLOBAL}
@item @code{secure_auth} @tab boolean @tab @code{GLOBAL}
@item @code{server_id} @tab numeric @tab @code{GLOBAL}
@item @code{slave_compressed_protocol} @tab boolean @tab @code{GLOBAL}
@item @code{slave_net_timeout} @tab numeric @tab @code{GLOBAL}
@item @code{slow_launch_time} @tab numeric @tab @code{GLOBAL}
@item @code{sort_buffer_size} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{sql_auto_is_null} @tab boolean @tab @code{SESSION}
@item @code{sql_big_selects} @tab boolean @tab @code{SESSION}
@item @code{sql_big_tables} @tab boolean @tab @code{SESSION}
@item @code{sql_buffer_result} @tab boolean @tab @code{SESSION}
@item @code{sql_log_bin} @tab boolean @tab @code{SESSION}
@item @code{sql_log_off} @tab boolean @tab @code{SESSION}
@item @code{sql_log_update} @tab boolean @tab @code{SESSION}
@item @code{sql_low_priority_updates} @tab boolean @tab @code{GLOBAL} | @code{SESSION}
@item @code{sql_max_join_size} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{sql_mode} @tab enumeration @tab @code{GLOBAL} | @code{SESSION}
@item @code{sql_quote_show_create} @tab boolean @tab @code{SESSION}
@item @code{sql_safe_updates} @tab boolean @tab @code{SESSION}
@item @code{sql_select_limit} @tab numeric @tab @code{SESSION}
@item @code{sql_slave_skip_counter} @tab numeric @tab @code{GLOBAL}
@item @code{updatable_views_with_limit} @tab enumeration @tab @code{GLOBAL} | @code{SESSION}
@item @code{sql_warnings} @tab boolean @tab @code{SESSION}
@item @code{sync_binlog} @tab numeric @tab @code{GLOBAL}
@item @code{sync_frm} @tab boolean @tab @code{GLOBAL}
@item @code{storage_engine} @tab enumeration @tab @code{GLOBAL} | @code{SESSION}
@item @code{table_cache} @tab numeric @tab @code{GLOBAL}
@item @code{table_type} @tab enumeration @tab @code{GLOBAL} | @code{SESSION}
@item @code{thread_cache_size} @tab numeric @tab @code{GLOBAL}
@c next one not listed in system variable section yet
@c @item @code{time_format} @tab string @tab @code{GLOBAL} | @code{SESSION}
@item @code{time_zone} @tab string @tab @code{GLOBAL} | @code{SESSION}
@item @code{timestamp} @tab boolean @tab @code{SESSION}
@item @code{tmp_table_size} @tab enumeration @tab @code{GLOBAL} | @code{SESSION}
@item @code{transaction_alloc_block_size} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{transaction_prealloc_size} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{tx_isolation} @tab enumeration @tab @code{GLOBAL} | @code{SESSION}
@item @code{unique_checks} @tab boolean @tab @code{SESSION}
@item @code{wait_timeout} @tab numeric @tab @code{GLOBAL} | @code{SESSION}
@item @code{warning_count} @tab numeric @tab @code{SESSION}
@end multitable

Variables that are marked as ``string'' take a string value.  Variables that
are marked as ``numeric'' take a numeric value. Variables that are
marked as ``boolean'' can be set to 0, 1, @code{ON} or @code{OFF}. Variables
that are marked as ``enumeration'' normally should be set to one of the
available values for the variable, but can also be set to the number that
corresponds to the desired enumeration value.  For enumeration-valued system
variables, the first enumeration value corresponds to 0. This differs
from @code{ENUM} columns, for which the first enumeration value corresponds
to 1.


@node Server status variables,  , Server system variables, Configuring MySQL
@subsection Server Status Variables

@cindex status variables
@cindex variables, status

The server maintains many status variables that provide information about its
operations. You can view these variables and their values by using the
@code{SHOW STATUS} statement:

@c TODO: Add variables new in 4.1.

@example
mysql> SHOW STATUS;
+--------------------------+------------+
| Variable_name            | Value      |
+--------------------------+------------+
| Aborted_clients          | 0          |
| Aborted_connects         | 0          |
| Bytes_received           | 155372598  |
| Bytes_sent               | 1176560426 |
| Connections              | 30023      |
| Created_tmp_disk_tables  | 0          |
| Created_tmp_files        | 60         |
| Created_tmp_tables       | 8340       |
| Delayed_errors           | 0          |
| Delayed_insert_threads   | 0          |
| Delayed_writes           | 0          |
| Flush_commands           | 1          |
| Handler_delete           | 462604     |
| Handler_read_first       | 105881     |
| Handler_read_key         | 27820558   |
| Handler_read_next        | 390681754  |
| Handler_read_prev        | 6022500    |
| Handler_read_rnd         | 30546748   |
| Handler_read_rnd_next    | 246216530  |
| Handler_update           | 16945404   |
| Handler_write            | 60356676   |
| Key_blocks_used          | 14955      |
| Key_read_requests        | 96854827   |
| Key_reads                | 162040     |
| Key_write_requests       | 7589728    |
| Key_writes               | 3813196    |
| Max_used_connections     | 0          |
| Not_flushed_delayed_rows | 0          |
| Not_flushed_key_blocks   | 0          |
| Open_files               | 2          |
| Open_streams             | 0          |
| Open_tables              | 1          |
| Opened_tables            | 44600      |
| Qcache_free_blocks       | 36         |
| Qcache_free_memory       | 138488     |
| Qcache_hits              | 79570      |
| Qcache_inserts           | 27087      |
| Qcache_lowmem_prunes     | 3114       |
| Qcache_not_cached        | 22989      |
| Qcache_queries_in_cache  | 415        |
| Qcache_total_blocks      | 912        |
| Questions                | 2026873    |
| Select_full_join         | 0          |
| Select_full_range_join   | 0          |
| Select_range             | 99646      |
| Select_range_check       | 0          |
| Select_scan              | 30802      |
| Slave_open_temp_tables   | 0          |
| Slave_running            | OFF        |
| Slow_launch_threads      | 0          |
| Slow_queries             | 0          |
| Sort_merge_passes        | 30         |
| Sort_range               | 500        |
| Sort_rows                | 30296250   |
| Sort_scan                | 4650       |
| Table_locks_immediate    | 1920382    |
| Table_locks_waited       | 0          |
| Threads_cached           | 0          |
| Threads_connected        | 1          |
| Threads_created          | 30022      |
| Threads_running          | 1          |
| Uptime                   | 80380      |
+--------------------------+------------+
@end example

Many status variables are reset to 0 by the @code{FLUSH STATUS} statement.

The status variables have the following meanings.  The @code{Com_@var{xxx}}
statement counter variables were added beginning with MySQL 3.23.47. The
@code{Qcache_@var{xxx}} query cache variables were added beginning with MySQL
4.0.1. Otherwise, variables with no version indicated have been present since
at least MySQL 3.22.

@table @code

@item Aborted_clients
The number of connections that were aborted because the client died without
closing the connection properly.
@xref{Communication errors}.

@item Aborted_connects
The number of tries to connect to the MySQL server that failed. @xref{Communication errors}.

@item Binlog_cache_disk_use
The number of transactions that used the temporary binary log cache but that
exceeded the value of @code{binlog_cache_size} and used a temporary file to
store statements from the transaction.
This variable was added in MySQL 4.1.2.

@item Binlog_cache_use
The number of transactions that used the temporary binary log cache.
This variable was added in MySQL 4.1.2.

@item Bytes_received
The number of bytes received from all clients.
This variable was added in MySQL 3.23.7.

@item Bytes_sent
The number of bytes sent to all clients.
This variable was added in MySQL 3.23.7.

@item Com_@var{xxx}
The number of times each @var{xxx} statement has been executed.
There is one status variable for each type of statement. For example,
@code{Com_delete} and @code{Com_insert} count @code{DELETE} and @code{INSERT}
statements.

@item Connections
The number of connection attempts (successful or not) to the MySQL server.

@item Created_tmp_disk_tables
The number of temporary tables on disk created automatically
by the server while executing statements.
This variable was added in MySQL 3.23.24.

@item Created_tmp_files
How many temporary files @command{mysqld} has created.
This variable was added in MySQL 3.23.28.

@item Created_tmp_tables
The number of in-memory temporary tables created automatically by the
server while executing statements.
If @code{Created_tmp_disk_tables} is big, you may want to increase the
@code{tmp_table_size} value to cause temporary tables to be memory-based
instead of disk-based.

@item Delayed_errors
The number of rows written with @code{INSERT DELAYED} for which some error
occurred (probably @code{duplicate key}).

@item Delayed_insert_threads
The number of @code{INSERT DELAYED} handler threads in use.

@item Delayed_writes
The number of @code{INSERT DELAYED} rows written.

@item Flush_commands
The number of executed @code{FLUSH} statements.

@item Handler_commit
The number of internal @code{COMMIT} statements.
This variable was added in MySQL 4.0.2.

@item Handler_discover
The MySQL server can ask the @code{NDB Cluster} storage engine if it knows about
a table with a given name. This is called discovery. @code{Handler_discover}
indicates the number of time tables have been discovered.
This variable was added in MySQL 4.1.2.

@item Handler_delete
The number of times a row was deleted from a table.

@item Handler_read_first
The number of times the first entry was read from an index.  If this is
high, it suggests that the server is doing a lot of full index scans; for
example, @code{SELECT col1 FROM foo}, assuming that @code{col1} is indexed.

@item Handler_read_key
The number of requests to read a row based on a key. If this is high, it is
a good indication that your queries and tables are properly indexed.

@item Handler_read_next
The number of requests to read the next row in key order. This will be
incremented if you are querying an index column with a range constraint or
if you are doing an index scan.

@item Handler_read_prev
The number of requests to read the previous row in key order.  This read
method is mainly used to optimize @code{ORDER BY ... DESC}.
This variable was added in MySQL 3.23.6.

@item Handler_read_rnd
The number of requests to read a row based on a fixed position.  This will
be high if you are doing a lot of queries that require sorting of the
result.
You probably have a lot of queries that require MySQL to scan whole tables
or you have joins that don't use keys properly.

@item Handler_read_rnd_next
The number of requests to read the next row in the data file.
This will be high if you are doing a lot of table scans. Generally this suggests that your tables
are not properly indexed or that your queries are not written to take advantage of the indexes you
have.

@item Handler_rollback
The number of internal @code{ROLLBACK} statements.
This variable was added in MySQL 4.0.2.

@item Handler_update
The number of requests to update a row in a table.

@item Handler_write
The number of requests to insert a row in a table.

@item Innodb_buffer_pool_read_requests

The number of logical read requests @code{InnoDB} has done.
Added in MySQL 5.0.2.

@item Innodb_buffer_pool_reads

The number of logical reads that @code{InnoDB} could not satisfy from
buffer pool and had to do a single-page read.
Added in MySQL 5.0.2.

@item Innodb_buffer_pool_read_ahead_seq

The number of sequential read-aheads @code{InnoDB} initiated. This happens when
@code{InnoDB} does a sequential full table scan.
Added in MySQL 5.0.2.

@item Innodb_buffer_pool_read_ahead_rnd

The number of ``random'' read-aheads @code{InnoDB} initiated. This happens
when a query is to scan a large portion of a table but in random order.
Added in MySQL 5.0.2.

@item Innodb_buffer_pool_write_requests

The number writes done to the e@code{InnoDB} buffer pool.
Added in MySQL 5.0.2.

@item Innodb_buffer_pool_pages_flushed

The number of buffer pool pages that have been requested to be flushed.
Added in MySQL 5.0.2.

@item Innodb_buffer_pool_wait_free

Normally, writes to the @code{InnoDB} buffer pool happen in the background.
However, if it's necessary to read or create a page and no clean pages are
available, it's necessary to wait for pages to be flushed first.
This counter counts instances of these waits.
If the buffer pool size was set properly, this value should be small.
Added in MySQL 5.0.2.

@item Innodb_page_size

The compiled-in @code{InnoDB} page size (default 16KB). Because we count a lot

Added in MySQL 5.0.2.

@item Innodb_buffer_pool_pages_total

Total size of buffer pool, in pages.
Added in MySQL 5.0.2.

@item Innodb_buffer_pool_pages_free

The number of free pages.
Added in MySQL 5.0.2.

@item Innodb_buffer_pool_pages_data

The number of pages containing data (dirty or clean).
Added in MySQL 5.0.2.

@item Innodb_buffer_pool_pages_dirty

The number of pages currently dirty.
Added in MySQL 5.0.2.

@item Innodb_buffer_pool_pages_misc

The number of pages busy because they have been allocated for administrative
overhead such as row locks.
Added in MySQL 5.0.2.

@item Innodb_buffer_pool_pages_latched

The number of latched pages in @code{InnoDB} buffer pool.  These are pages
currently being read or written or that can't be flushed or removed now
for some other reason.
Added in MySQL 5.0.2.

@item Innodb_data_writes

The total number of data writes.
Added in MySQL 5.0.2.

@item Innodb_data_reads

The total number of data reads.
Added in MySQL 5.0.2.

@item Innodb_data_read

The amount of data read so far, in bytes.
Added in MySQL 5.0.2.

@item Innodb_data_written

The amount of data written so far, in bytes.
Added in MySQL 5.0.2.

@item Innodb_data_fsyncs

The number of @code{fsync()} operations so far.
Added in MySQL 5.0.2.

@item Innodb_dblwr_writes
@itemx Innodb_dblwr_pages_written

The number of doublewrite writes that have been performed and the number
of pages that have been written for this purpose.
Added in MySQL 5.0.2.

@item Innodb_data_pending_reads

The current number of pending reads.
Added in MySQL 5.0.2.

@item Innodb_data_pending_writes

The current number of pending writes.
Added in MySQL 5.0.2.

@item Innodb_data_pending_fsyncs

The current number of pending @code{fsync()} operations.
Added in MySQL 5.0.2.

@item Innodb_log_writes

The number of physical writes to the log file.
Added in MySQL 5.0.2.

@item Innodb_log_write_requests

The number of log write requests.
Added in MySQL 5.0.2.

@item Innodb_os_log_written

The number of bytes written to the log file.
Added in MySQL 5.0.2.

@item Innodb_os_log_fsyncs

The number of fsyncs writes done to the log file.

Added in MySQL 5.0.2.

@item Innodb_os_log_pending_writes

Pending log file writes.

Added in MySQL 5.0.2.

@item Innodb_os_log_pending_fsyncs

The number of pending log file fsyncs.

Added in MySQL 5.0.2.

@item Innodb_log_waits

The number of waits we had because log buffer was too small and we had to
wait for it to be flushed before continuing.

Added in MySQL 5.0.2.

@item Innodb_pages_read

The number of pages read.
Added in MySQL 5.0.2.

@item Innodb_pages_written

The number of pages written.
Added in MySQL 5.0.2.

@item Innodb_pages_created

The number of pages created.
Added in MySQL 5.0.2.

@item Innodb_rows_read

The number of rows read from @code{InnoDB} tables.
Added in MySQL 5.0.2.

@item Innodb_rows_inserted

The number of rows inserted in @code{InnoDB} tables.
Added in MySQL 5.0.2.

@item Innodb_rows_updated

The number of rows updated in @code{InnoDB} tables.
Added in MySQL 5.0.2.

@item Innodb_rows_deleted

The number of rows deleted from @code{InnoDB} tables.
Added in MySQL 5.0.2.

@item Key_blocks_not_flushed
The number of key blocks in the key cache that have changed but haven't yet
been flushed to disk.
This variable was added in MySQL 4.1.1.
It used to be known as @code{Not_flushed_key_blocks}.

@item Key_blocks_unused
@c TODO: add description
This variable was added in MySQL 4.1.2.
@ref{Server system variables}.

@item Key_blocks_used
The number of used blocks in the key cache.
You can use this value to determine how much of the key cache is in use;
see the discussion of @code{key_buffer_size} in
@ref{Server system variables}.

@item Key_read_requests
The number of requests to read a key block from the cache.

@item Key_reads
The number of physical reads of a key block from disk.
If @code{Key_reads} is big, then your @code{key_buffer_size} value is
probably too small.  The cache miss rate can be calculated as
@code{Key_reads}/@code{Key_read_requests}.

@item Key_write_requests
The number of requests to write a key block to the cache.

@item Key_writes
The number of physical writes of a key block to disk.

@item Last_query_cost
The total cost of the last compiled query as computed by the query
optimizer. Useful for comparing the cost of different query plans for the
same query. The default value of @minus{}1 means that no query has been
compiled yet. This variable was added in MySQL 5.0.1.

@item Max_used_connections
The maximum number of connections that have been in use simultaneously since
the server started.

@item Not_flushed_delayed_rows
The number of rows waiting to be written in @code{INSERT DELAY} queues.

@item Not_flushed_key_blocks
The old name for @code{Key_blocks_not_flushed} before MySQL 4.1.1.

@item Open_files
The number of files that are open.

@item Open_streams
The number of streams that are open (used mainly for logging).

@item Open_tables
The number of tables that are open.

@item Opened_tables
The number of tables that have been opened.
If @code{Opened_tables} is big, your @code{table_cache}
value is probably too small.

@item Qcache_free_blocks
The number of free memory blocks in query cache.

@item Qcache_free_memory
The amount of free memory for query cache.

@item Qcache_hits
The number of cache hits.

@item Qcache_inserts
The number of queries added to the cache.

@item Qcache_lowmem_prunes
The number of queries that were deleted from the cache because of low memory.

@item Qcache_not_cached
The number of non-cached queries
(not cachable, or due to @code{query_cache_type}).

@item Qcache_queries_in_cache
The number of queries registered in the cache.

@item Qcache_total_blocks
The total number of blocks in the query cache.

@item Questions
The number of queries that have been sent to the server.

@item Rpl_status
The status of failsafe replication (not yet implemented).

@item Select_full_join
The number of joins that do not use indexes.  If this value is not 0, you
should carefully check the indexes of your tables.
This variable was added in MySQL 3.23.25.

@item Select_full_range_join
The number of joins that used a range search on a reference table.
This variable was added in MySQL 3.23.25.

@item Select_range
The number of joins that used ranges on the first table. (It's normally
not critical even if this is big.)
This variable was added in MySQL 3.23.25.

@item Select_range_check
The number of joins without keys that check for key usage after each row.
(If this is not 0, you should carefully check the indexes of your tables.)
This variable was added in MySQL 3.23.25.

@item Select_scan
The number of joins that did a full scan of the first table.
This variable was added in MySQL 3.23.25.

@item Slave_open_temp_tables
The number of temporary tables currently open by the slave SQL thread.
This variable was added in MySQL 3.23.29.

@item Slave_running
This is @code{ON} if this server is a slave that is connected to a master.
This variable was added in MySQL 3.23.16.

@item Slow_launch_threads
The number of threads that have taken more than @code{slow_launch_time}
seconds to create.
This variable was added in MySQL 3.23.15.

@item Slow_queries
The number of queries that have taken more than @code{long_query_time} seconds. @xref{Slow query log}.

@item Sort_merge_passes
The number of merge passes the sort algorithm has had to do. If this value is
large, you should consider increasing the value of the @code{sort_buffer_size}
system variable.
This variable was added in MySQL 3.23.28.

@item Sort_range
The number of sorts that were done with ranges.
This variable was added in MySQL 3.23.25.

@item Sort_rows
The number of sorted rows.
This variable was added in MySQL 3.23.25.

@item Sort_scan
The number of sorts that were done by scanning the table.
This variable was added in MySQL 3.23.25.

@c TODO: add SSL status variables

@item Ssl_@var{xxx}
Variables used for SSL connections.
These variables were added in MySQL 4.0.0.

@item Table_locks_immediate
The number of times that a table lock was acquired immediately. This
variable was added as of MySQL 3.23.33.

@item Table_locks_waited
The number of times that a table lock could not be acquired immediately and a
wait was needed. If this is high, and you have performance problems, you
should first optimize your queries, and then either split your table or
tables or use replication.  This variable was added as of MySQL 3.23.33.

@item Threads_cached
The number of threads in the thread cache.
This variable was added in MySQL 3.23.17.

@item Threads_connected
The number of currently open connections.

@item Threads_created
The number of threads created to handle connections.
If @code{Threads_created} is big, you may want to increase the
@code{thread_cache_size} value.  The cache hit rate can be calculated
as @code{Threads_created}/@code{Connections}.
This variable was added in MySQL 3.23.31.

@item Threads_running
The number of threads that are not sleeping.

@item Uptime
The number of seconds the server has been up.

@end table


@node Server Shutdown, Security, Configuring MySQL, MySQL Database Administration
@section The MySQL Server Shutdown Process

The server shutdown process can be summarized like this:

@enumerate
@item
The shutdown process is initiated
@item
The server creates a shutdown thread if necessary
@item
The server stops accepting new connections
@item
The server terminates current activity
@item
Storage engines are shut down or closed
@item
The server exits
@end enumerate

A more detailed description of the process follows:

@enumerate
@item
The shutdown process is initiated.

Server shutdown can be initiated several ways. For example, a user with
the @code{SHUTDOWN} privilege can execute a @command{mysqladmin shutdown}
command. @command{mysqladmin} can be used on any platform supported by
MySQL. Other operating sytem-specific shutdown initiation methods are possible
as well: The server shuts down on Unix when it receives a @code{SIGTERM}
signal. A server running as a service on Windows shuts down when the services
manager tells it to.

@item
The server creates a shutdown thread if necessary.

Depending on how shutdown was initiated, the server might create a thread to
handle the shutdown process.  If shutdown was requested by a client, a
shutdown thread is created.  If shutdown is the result of receiving a
@code{SIGTERM} signal, the signal thread might handle shutdown itself, or it
might create a separate thread to do so.  If the server tries to create a
shutdown thread and cannot (for example, if memory is exhausted), it issues a
diagnostic message that will appear in the error log:

@example
Error: Can't create thread to kill server
@end example

@item
The server stops accepting new connections.

To prevent new activity from being initiated during shutdown, the server
stops accepting new client connections. It does this by closing the network
connections to which it normally listens for connections: the TCP/IP port,
the Unix socket file, the Windows named pipe, and shared memory on Windows.

@item
The server terminates current activity.

For each thread that is associated with a client connection, the connection
to the client is broken and the thread is marked as killed. Threads die when
they notice that they are so marked. Threads for idle connections die
quickly. Threads that currently are processing queries check their state
periodically and take longer to die.  For additional information about
thread termination, see @ref{KILL,  , @code{KILL}}, in particular for the
instructions about killed @code{REPAIR TABLE} or @code{OPTIMIZE TABLE}
operations on @code{MyISAM} tables.

For threads that have an open transaction, the tranaction is rolled back.
Note that if a thread is updating a non-transactional table, an operation
such as a multiple-row @code{UPDATE} or @code{INSERT} may leave the table
partially updated, because the operation can terminate before completion.

If the server is a master replication server, threads associated with
currently connected slaves are treated like other client threads. That
is, each one is marked as killed and exits when it next checks its state.

If the server is a slave replication server, the I/O and SQL threads, if
active, are stopped before client threads are marked as killed. The SQL
thread is allowed to finish its current statement (to avoid causing
replication problems) then stops. If the SQL thread was in the middle
of a transaction at this point, the transaction is rolled back.

@item
Storage engines are shut down or closed.

At this stage, the table cache is flushed and all open tables are closed.

Each storage engine performs any actions necessary for tables that it manages.
For example, MyISAM flushes any pending index writes for a table.
InnoDB flushes its buffer pool to disk, writes the current LSN to the
tablespace, and terminates its own internal threads.

@item
The server exits.

@end enumerate


@node Security, Privilege system, Server Shutdown, MySQL Database Administration
@section General Security Issues

@cindex system, security

This section describes some general security issues to be aware of and what
you can do to make your MySQL installation more secure against attack or
misuse. For information specifically about the access control system that
MySQL uses for setting up user accounts and checking database access, see
@ref{Privilege system}.

@menu
* Security guidelines::         General Security Guidelines
* Security against attack::     Making MySQL Secure Against Attackers
* Privileges options::          Startup Options for @command{mysqld} Concerning Security
* LOAD DATA LOCAL::             Security Issues with @code{LOAD DATA LOCAL}
@end menu


@node Security guidelines, Security against attack, Security, Security
@subsection General Security Guidelines

Anyone using MySQL on a computer connected to the Internet
should read this section to avoid the most common security mistakes.

In discussing security, we emphasize the necessity of fully protecting the
entire server host (not just the MySQL server) against all types
of applicable attacks: eavesdropping, altering, playback, and denial of
service. We do not cover all aspects of availability and fault tolerance
here.

MySQL uses security based on Access Control Lists (ACLs) for all
connections, queries, and other operations that users can attempt to
perform. There is also some support for SSL-encrypted connections
between MySQL clients and servers. Many of the concepts
discussed here are not specific to MySQL at all; the same
general ideas apply to almost all applications.

When running MySQL, follow these guidelines whenever possible:

@itemize @bullet
@item
@strong{Do not ever give anyone (except MySQL @code{root} accounts) access
to the @code{user} table in the @code{mysql} database!}  This is critical.
@strong{The encrypted password is the real password in MySQL.} Anyone who
knows the password that is listed in the @code{user} table and has access
to the host listed for the account @strong{can easily log in as that user}.

@item
Learn the MySQL access privilege system. The @code{GRANT} and
@code{REVOKE} statements are used for controlling access to MySQL. Do
not grant any more privileges than necessary. Never grant privileges to all
hosts.

Checklist:
@itemize @minus
@item
Try @code{mysql -u root}. If you are able to connect successfully to the
server without being asked for a password, you have problems. Anyone
can connect to your MySQL server as the MySQL
@code{root} user with full privileges!
Review the MySQL installation instructions, paying particular
attention to the information about setting a @code{root} password.
@xref{Default privileges}.
@item
Use the @code{SHOW GRANTS} statement and check to see who has access to
what.  Then use the @code{REVOKE} statement to remove those privileges that
are not necessary.
@end itemize

@item
Do not store any plain-text passwords in your database. If your
computer becomes compromised, the intruder can take the full list of
passwords and use them. Instead, use @code{MD5()}, @code{SHA1()}, or
some other one-way hashing function.
@item
Do not choose passwords from dictionaries. There are special programs to
break them. Even passwords like ``xfish98'' are very bad.  Much better is
``duag98'' which contains the same word ``fish'' but typed one key to the
left on a standard QWERTY keyboard. Another method is to use ``Mhall'' which
is taken from the first characters of each word in the sentence ``Mary had
a little lamb.'' This is easy to remember and type, but difficult to guess
for someone who does not know it.
@item
Invest in a firewall. This protects you from at least 50% of all types of
exploits in any software. Put MySQL behind the firewall or in
a demilitarized zone (DMZ).

Checklist:
@itemize @minus
@item
Try to scan your ports from the Internet using a tool such as
@code{nmap}. MySQL uses port 3306 by default. This port should
not be accessible from untrusted hosts. Another simple way to check whether
or not your MySQL port is open is to try the following command
from some remote machine, where @code{server_host} is the host on which
your MySQL server runs:

@example
shell> telnet server_host 3306
@end example

If you get a connection and some garbage characters, the port is
open, and should be closed on your firewall or router, unless you really
have a good reason to keep it open. If @code{telnet} just hangs or the
connection is refused, everything is OK; the port is blocked.
@end itemize

@item
Do not trust any data entered by users of your applications. They can try to trick your
code by entering special or escaped character sequences in Web forms,
URLs, or whatever application you have built. Be sure that your
application remains secure if a user enters something like ``@code{; DROP
DATABASE mysql;}''. This is an extreme example, but large security leaks
and data loss might occur as a result of hackers using similar techniques,
if you do not prepare for them.

A common mistake is to protect only string data values.  Remember to check
numeric data as well.  If an application generates a query such as
@code{SELECT * FROM table WHERE ID=234} when a user enters the value
@code{234}, the user can enter the value @code{234 OR 1=1} to cause the
application to generate the query @code{SELECT * FROM table WHERE ID=234 OR
1=1}.  As a result, the server retrieves every record in the table.  This
exposes every record and causes excessive server load.  The simplest way to
protect from this type of attack is to use apostrophes around the numeric
constants: @code{SELECT * FROM table WHERE ID='234'}. If the user enters
extra information, it all becomes part of the string. In numeric context,
MySQL automatically converts this string to a number and strips any trailing
non-numeric characters from it.

Sometimes people think that if a database contains only publicly available
data, it need not be protected. This is incorrect.  Even if it is allowable
to display any record in the database, you should still protect against
denial of service attacks (for example, those that are based on the
technique in the preceding paragraph that causes the server to waste
resources). Otherwise, your server becomes unresponsive to legitimate users.

Checklist:
@itemize @minus
@item
Try to enter @samp{'} and @samp{"} in all your Web forms. If you get any kind
of MySQL error, investigate the problem right away.
@item
Try to modify any dynamic URLs by adding @code{%22} (@samp{"}), @code{%23}
(@samp{#}), and @code{%27} (@samp{'}) in the URL.
@item
Try to modify data types in dynamic URLs from numeric ones to character
ones containing characters from previous examples. Your application
should be safe against this and similar attacks.
@item
Try to enter characters, spaces, and special symbols rather than numbers in
numeric fields. Your application should remove them before passing them to
MySQL or else generate an error. Passing
unchecked values to MySQL is very dangerous!
@item
Check data sizes before passing them to MySQL.
@item
Consider having your application connect to the database using a
different username than the one you use for administrative purposes. Do
not give your applications any access privileges they do not need.
@end itemize
@item
Many application programming interfaces provide a means of escaping special
characters in data values. Properly used, this prevents application users from
entering values that cause the application to generate statements that have a
different effect than you intend:
@itemize @minus
@item
MySQL C API:
Use the @code{mysql_real_escape_string()} API call.
@item
MySQL++:
Use the @code{escape} and @code{quote} modifiers for query streams.
@item
PHP:
Use the @code{mysql_escape_string()} function, which
is based on the function of the same name in the MySQL C API.
Prior to PHP 4.0.3, use  @code{addslashes()} instead.
@item
Perl DBI:
Use the @code{quote()} method or use placeholders.
@item
Java JDBC:
Use a @code{PreparedStatement} object and placeholders.
@end itemize

Other programming interfaces might have similar capabilities.

@item
Do not transmit plain (unencrypted) data over the Internet. This information is
accessible to everyone who has the time and ability to intercept it and use
it for their own purposes. Instead, use an encrypted protocol such as SSL or
SSH. MySQL supports internal SSL connections as of Version 4.0.0.
SSH port-forwarding can be used to create an encrypted (and compressed)
tunnel for the communication.
@item
Learn to use the @code{tcpdump} and @code{strings} utilities. For most cases,
you can check whether MySQL data streams are unencrypted
by issuing a command like the following:

@example
shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings
@end example

(This works under Linux and should work with small modifications under other
systems.)  Warning: If you do not see plaintext data, this doesn't always
mean that the information actually is encrypted. If you need high security,
you should consult with a security expert.
@end itemize


@node Security against attack, Privileges options, Security guidelines, Security
@subsection Making MySQL Secure Against Attackers

@cindex attackers, security against
@cindex security, against attackers

When you connect to a MySQL server, you should use a password.  The password
is not transmitted in clear text over the connection. Password handling during
the client connection sequence was upgraded in MySQL 4.1.1 to be very secure.
If you are using an older version of MySQL, or are still using pre-4.1.1-style
passwords, the encryption
algorithm is less strong and with some effort a clever attacker who can
sniff the traffic between the client and the server can crack the password.
(See @ref{Password hashing} for a discussion of the different password handling
methods.)
If the connection between the client and the server goes through an
untrusted network, you should use an SSH tunnel to encrypt the communication.

All other information is transferred as text that can be read by anyone who
is able to watch the connection.  If you are concerned about this, you can
use the compressed protocol (in MySQL 3.22 and above) to make
traffic much more difficult to decipher.  To make the connection even more
secure, you should use SSH to get an encrypted TCP/IP connection between a
MySQL server and a MySQL client.  You can find an Open Source SSH
client at @uref{http://www.openssh.org/}, and a commercial SSH client at
@uref{http://www.ssh.com/}.

If you are using MySQL 4.0 or newer, you can also use internal OpenSSL support.
@xref{Secure connections}.

To make a MySQL system secure, you should strongly consider the
following suggestions:

@itemize @bullet
@item
Use passwords for all MySQL users. A client program does not necessarily
know the identity of the person running it. It is common for client/server
applications that the user can specify any username to the client program.
For example, anyone can use the @command{mysql} program to connect as any other
person simply by invoking it as @code{mysql -u @var{other_user} @var{db_name}} if
@var{other_user} has no password. If all users have a password,
connecting using another user's account becomes much more difficult.

To change the password for a user, use the @code{SET PASSWORD} statement.
It is also possible to update the @code{user} table in the @code{mysql}
database directly.  For example, to change the password of all MySQL accounts
that have a username of @code{root}, do this:

@example
shell> mysql -u root
mysql> UPDATE mysql.user SET Password=PASSWORD('@var{newpwd}')
    -> WHERE User='root';
mysql> FLUSH PRIVILEGES;
@end example

@item
Don't run the MySQL server as the Unix @code{root} user.  This is
very dangerous, because any user with the @code{FILE} privilege will be able
to create files as @code{root} (for example, @code{~root/.bashrc}). To
prevent this, @command{mysqld} refuses to run as @code{root} unless that
is specified explicitly using a @code{--user=root} option.

@command{mysqld} can be run as an ordinary unprivileged user instead.
You can also create a separate Unix account named @code{mysql} to make
everything even more secure. Use the account only for administering MySQL.
To start @command{mysqld} as another Unix user, add a @code{user}
option that specifies the username to the @code{[mysqld]} group of the
@file{/etc/my.cnf} option file or the @file{my.cnf} option file in the
server's data directory. For example:

@example
[mysqld]
user=mysql
@end example

This causes the server to start as the designated user whether you
start it manually or by using @command{mysqld_safe} or @command{mysql.server}.
For more details, see @ref{Changing MySQL user}.

Running @command{mysqld} as a Unix user other than @code{root} does not
mean that you need to change the @code{root} username in the @code{user}
table. Usernames for MySQL accounts have nothing to do with usernames for Unix
accounts.

@item
Don't allow the use of symlinks to tables. (This can be disabled with the
@code{--skip-symbolic-links} option.) This is especially important if you run
@command{mysqld} as @code{root}, because anyone that has write access to the
server's data directory then could delete any file in the system!
@xref{Symbolic links to tables}.

@item
Make sure that the only Unix user with read or write privileges in the
database directories is the user that @command{mysqld} runs as.

@item
Don't grant the @code{PROCESS} or @code{SUPER} privilege to non-administrative users.
The output of @command{mysqladmin processlist} shows the text of the currently
executing queries, so any user who is allowed to execute that command
might be able to see if another user issues an @code{UPDATE user SET
password=PASSWORD('not_secure')} query.

@command{mysqld} reserves an extra connection for users who have the
@code{SUPER} privilege (@code{PROCESS} before MySQL 4.0.2), so that a MySQL
@code{root} user can log in and check server activity even if all normal
connections are in use.

The @code{SUPER} privilege
can be used to terminate client connections, change server operation by
changing the value of system variables, and control replication servers.

@item
Don't grant the @code{FILE} privilege to non-administrative users.
Any user that has this privilege can write a file anywhere in the
filesystem with the privileges of the @command{mysqld} daemon!  To make
this a bit safer, files generated with @code{SELECT ... INTO OUTFILE}
will not overwrite existing files and are writable by everyone.

@tindex @file{/etc/passwd}

The @code{FILE} privilege may also be used to read any file that is
world-readable or accessible to the Unix user that the server runs as.
With this privilege, you can read any file into a database table.
This could be abused, for example, by using @code{LOAD DATA} to load
@file{/etc/passwd} into a table, which then can be displayed with
@code{SELECT}.

@item
If you don't trust your DNS, you should use IP numbers rather than
hostnames in the grant tables. In any case, you should be very careful
about creating grant table entries using hostname values that contain
wildcards!

@item
If you want to restrict the number of connections allowed to a single account,
you can do so by setting the @code{max_user_connections} variable in
@command{mysqld}.
The @code{GRANT} statement also supports resource control options for limiting
the extent of server use allowed to an account.
@end itemize


@node Privileges options, LOAD DATA LOCAL, Security against attack, Security
@subsection Startup Options for @command{mysqld} Concerning Security

@c TODO: There may be overlap between this and the section that has
@c the general server option list...

The following @command{mysqld} options affect security:

@table @code
@item --local-infile[=@{0|1@}]
If you start the server with @code{--local-infile=0}, clients cannot use
@code{LOCAL} in @code{LOAD DATA} statements.
@xref{LOAD DATA LOCAL,  , @code{LOAD DATA LOCAL}}.

@item --safe-show-database
With this option, the @code{SHOW DATABASES} statement displays the names
of only those databases for which the user has some kind of privilege.
As of MySQL 4.0.2, this option is deprecated and doesn't do anything
(it is enabled by default), because there is now a @code{SHOW DATABASES}
privilege that can be used to control access to database
names on a per-account basis. @xref{GRANT,  , @code{GRANT}}.

@item --safe-user-create
If this is enabled, a user cannot create new users with the @code{GRANT}
statement unless the user has the @code{INSERT} privilege for the
@code{mysql.user} table.  If you want a user to have the ability to create
new users with those privileges that the user has right to grant, you should
grant the user the following privilege:

@example
mysql> GRANT INSERT(user) ON mysql.user TO '@var{user_name}'@@'@var{host_name}';
@end example

This will ensure that the user can't change any privilege columns directly,
but has to use the @code{GRANT} statement to give privileges to other users.

@item --secure-auth
Disallow authentication for accounts that have old (pre-4.1) passwords.
This option is available as of MySQL 4.1.1.

@item --skip-grant-tables
This option causes the server not to use the privilege system at all. This
gives everyone @emph{full access} to all databases!  (You can tell a running
server to start using the grant tables again by executing a @command{mysqladmin
flush-privileges} or @command{mysqladmin reload} command, or by issuing a
@code{FLUSH PRIVILEGES} statement.)

@item --skip-name-resolve
Hostnames are not resolved.  All @code{Host} column values in the grant
tables must be IP numbers or @code{localhost}.

@item --skip-networking
Don't allow TCP/IP connections over the network.  All connections to
@command{mysqld} must be made via Unix socket files.
This option is unsuitable when using a MySQL version prior to 3.23.27 with
the MIT-pthreads package, because Unix socket files were not supported by
MIT-pthreads at that time.

@item --skip-show-database
With this option, the @code{SHOW DATABASES} statement is allowed only to
users who have the @code{SHOW DATABASES} privilege, and the statement
displays all database names.  Without this option, @code{SHOW DATABASES} is
allowed to all users, but displays each database name only if the user has
the @code{SHOW DATABASES} privilege or some privilege for the database.

@end table

@node LOAD DATA LOCAL,  , Privileges options, Security
@subsection Security Issues with @code{LOAD DATA LOCAL}

The @code{LOAD DATA} statement can load a file that is located on the
server host, or it can load a file that is located on the client host when
the @code{LOCAL} keyword is specified.

There are two potential security issues with supporting the @code{LOCAL}
version of @code{LOAD DATA} statements:

@itemize @bullet
@item
The transfer of the file from the client host to the server host is initiated
by the MySQL server. In theory, a patched server could be built that would
tell the client program to transfer a file of the server's choosing rather
than the file named by the client in the @code{LOAD DATA} statement. Such a
server could access any file on the client host to which the client user has
read access.

@item
In a Web environment where the clients are connecting from a Web
server, a user could use @code{LOAD DATA LOCAL} to read any files
that the Web server process has read access to (assuming that a user could
run any command against the SQL server). In this environment, the client with
respect to the MySQL server actually is the Web server, not the program being
run by the user connecting to the Web server.

@end itemize

To deal with these problems, we changed how @code{LOAD DATA
LOCAL} is handled as of MySQL 3.23.49 and MySQL 4.0.2 (4.0.13 on Windows):

@itemize @bullet

@item
By default, all MySQL clients and libraries in binary distributions are
compiled with the @code{--enable-local-infile} option, to be compatible
with MySQL 3.23.48 and before.

@item
If you build MySQL from source but don't use the @code{--enable-local-infile}
option to @command{configure}, @code{LOAD DATA LOCAL} cannot be used
by any client unless it is written explicitly to invoke
@code{mysql_options(... MYSQL_OPT_LOCAL_INFILE, 0)}.
@xref{mysql_options, , @code{mysql_options()}}.

@item
You can disable all @code{LOAD DATA LOCAL} commands from the server side
by starting @command{mysqld} with the @code{--local-infile=0} option.

@item
For the @command{mysql} command-line client, @code{LOAD DATA LOCAL} can be
enabled by specifying the @code{--local-infile[=1]} option, or disabled with
the @code{--local-infile=0} option.  Similarly, for @command{mysqlimport},
the @code{--local} or @code{-L} option enables local data file loading. In
any case, successful use of a local loading operation requires that the
server is enabled to allow it.

@item
If you use @code{LOAD DATA LOCAL} in Perl scripts or other programs that
read the @code{[client]} group from option files, you can add the
@code{local-infile=1} option to that group. However, to keep this from
causing problems for programs that do not understand @code{local-infile},
specify it using the @code{loose-} prefix:

@example
[client]
loose-local-infile=1
@end example

The @code{loose-} prefix can be used as of MySQL 4.0.2.

@item
If @code{LOAD DATA LOCAL INFILE} is disabled, either in the server or
the client, a client that attempts to issue such a statement receives the
following error message:

@example
ERROR 1148: The used command is not allowed with this MySQL version
@end example

@end itemize


@node Privilege system, User Account Management, Security, MySQL Database Administration
@section The MySQL Access Privilege System

@cindex access privileges
@cindex privileges, access
@cindex security system
@cindex ACLs

MySQL has an advanced but non-standard security/privilege
system.  This section describes how it works.

@menu
* What Privileges::             What the Privilege System Does
* Privileges::                  How the Privilege System Works
* Privileges provided::         Privileges Provided by MySQL
* Connecting::                  Connecting to the MySQL Server
* Connection access::           Access Control, Stage 1: Connection Verification
* Request access::              Access Control, Stage 2: Request Verification
* Privilege changes::           When Privilege Changes Take Effect
* Access denied::               Causes of @code{Access denied} Errors
* Password hashing::            Password Hashing in MySQL 4.1
@end menu

@node What Privileges, Privileges, Privilege system, Privilege system
@subsection What the Privilege System Does

@cindex system, privilege
@cindex privilege system
@cindex passwords, security

The primary function of the MySQL privilege system is to
authenticate a user connecting from a given host, and to associate that user
with privileges on a database such as
@code{SELECT}, @code{INSERT}, @code{UPDATE}, and @code{DELETE}.

Additional functionality includes the ability to have an anonymous user and
to grant privileges for MySQL-specific functions such as @code{LOAD
DATA INFILE} and administrative operations.


@node Privileges, Privileges provided, What Privileges, Privilege system
@subsection How the Privilege System Works

@cindex privilege system, described

The MySQL privilege system ensures that all users may perform only the
operations allowed to them.  As a user, when you connect to a
MySQL server, your identity is determined by @emph{the host from
which you connect} and @emph{the username you specify}.  The system grants
privileges according to your identity and @emph{what you want to do}.

MySQL considers both your hostname and username in identifying you
because there is little reason to assume that a given username belongs to
the same person everywhere on the Internet.  For example, the user
@code{joe} who connects from @code{office.com} need not be the same
person as the user @code{joe} who connects from @code{elsewhere.com}.
MySQL handles this by allowing you to distinguish users on different
hosts that happen to have the same name:  You can grant @code{joe} one set
of privileges for connections from @code{office.com}, and a different set
of privileges for connections from @code{elsewhere.com}.

MySQL access control involves two stages:

@itemize @bullet
@item
Stage 1: The server checks whether you are even allowed to connect.

@item
Stage 2: Assuming that you can connect, the server checks each statement you issue
to see whether you have sufficient privileges to perform it.  For
example, if you try to select rows from a table in a database or drop a table
from the database, the server verifies that you have the @code{SELECT}
privilege for the table or the @code{DROP} privilege for the database.
@end itemize

If your privileges are changed (either by yourself or someone
else) while you are connected, those changes will not necessarily take
effect immediately for the next statement you issue.  See @ref{Privilege
changes} for details.

The server stores privilege information in the grant tables of the
@code{mysql} database (that is, in the database named @code{mysql}).
The MySQL server reads the contents of these tables into memory when it
starts and re-reads them under the circumstances indicated in @ref{Privilege
changes}. Access-control decisions are based on the in-memory copies of the
grant tables.

Normally, you manipulate the contents of the grant tables indirectly by using
the @code{GRANT} and @code{REVOKE} statements to set up accounts and control
the privileges available to each one.
@xref{GRANT,  , @code{GRANT}}.
The discussion here describes the underlying structure of the grant tables and
how the server uses their contents when interacting with clients.

The server uses the @code{user}, @code{db}, and @code{host} tables in the
@code{mysql} database at both stages of access control.  The columns in these
grant tables are shown here:

@c arjen 2003-03-28 These column fractions probably need updating (with the new privs since 4.0.2)
@multitable @columnfractions .20 .20 .20 .20
@item @strong{Table Name}
       @tab @strong{user}                @tab @strong{db}                   @tab @strong{host}

@item @strong{Scope columns}
       @tab @code{Host}                  @tab @code{Host}                  @tab @code{Host}
@item  @tab @code{User}                  @tab @code{Db}                    @tab @code{Db}
@item  @tab @code{Password}              @tab @code{User}                  @tab

@item @strong{Privilege columns}
       @tab @code{Select_priv}           @tab @code{Select_priv}           @tab @code{Select_priv}
@item  @tab @code{Insert_priv}           @tab @code{Insert_priv}           @tab @code{Insert_priv}
@item  @tab @code{Update_priv}           @tab @code{Update_priv}           @tab @code{Update_priv}
@item  @tab @code{Delete_priv}           @tab @code{Delete_priv}           @tab @code{Delete_priv}
@item  @tab @code{Index_priv}            @tab @code{Index_priv}            @tab @code{Index_priv}
@item  @tab @code{Alter_priv}            @tab @code{Alter_priv}            @tab @code{Alter_priv}
@item  @tab @code{Create_priv}           @tab @code{Create_priv}           @tab @code{Create_priv}
@item  @tab @code{Drop_priv}             @tab @code{Drop_priv}             @tab @code{Drop_priv}
@item  @tab @code{Grant_priv}            @tab @code{Grant_priv}            @tab @code{Grant_priv}
@item  @tab @code{Create_view_priv}      @tab @code{Create_view_priv}      @tab @code{Create_view_priv}
@item  @tab @code{Show_view_priv}        @tab @code{Show_view_priv}        @tab @code{Show_view_priv}

@item  @tab @code{References_priv}       @tab @code{References_priv}       @tab @code{References_priv}
@item  @tab @code{Reload_priv}           @tab                              @tab
@item  @tab @code{Shutdown_priv}         @tab                              @tab
@item  @tab @code{Process_priv}          @tab                              @tab
@item  @tab @code{File_priv}             @tab                              @tab

@item  @tab @code{Show_db_priv}          @tab                              @tab
@item  @tab @code{Super_priv}            @tab                              @tab
@item  @tab @code{Create_tmp_table_priv} @tab @code{Create_tmp_table_priv} @tab @code{Create_tmp_table_priv}
@item  @tab @code{Lock_tables_priv}      @tab @code{Lock_tables_priv}      @tab @code{Lock_tables_priv}
@item  @tab @code{Execute_priv}          @tab                              @tab
@item  @tab @code{Repl_slave_priv}       @tab                              @tab
@item  @tab @code{Repl_client_priv}      @tab                              @tab

@item  @tab @code{ssl_type}              @tab                              @tab
@item  @tab @code{ssl_cipher}            @tab                              @tab
@item  @tab @code{x509_issuer}           @tab                              @tab
@item  @tab @code{x509_subject}          @tab                              @tab

@item  @tab @code{max_questions}         @tab                              @tab
@item  @tab @code{max_updates}           @tab                              @tab
@item  @tab @code{max_connections}       @tab                              @tab
@end multitable

The
@code{ssl_type},
@code{ssl_cipher},
@code{x509_issuer}, and
@code{x509_subject}
columns were added in MySQL 4.0.0.

The
@code{Create_tmp_table_priv},
@code{Execute_priv},
@code{Lock_tables_priv},
@code{Repl_client_priv},
@code{Repl_slave_priv},
@code{Show_db_priv},
@code{Super_priv},
@code{max_questions},
@code{max_updates}, and
@code{max_connections}
columns were added in MySQL 4.0.2.

The @code{Create_view_priv} and @code{Show_view_priv} columns were added in
MySQL 5.0.1.

During the second stage of access control (request verification), the server
may, if the request involves tables, additionally consult the
@code{tables_priv} and @code{columns_priv} tables that provide finer control
at the table and column levels.  The columns in these
tables are shown here:

@multitable @columnfractions .20 .20 .20
@item @strong{Table Name}       @tab @strong{tables_priv} @tab @strong{columns_priv}

@item @strong{Scope columns}    @tab @code{Host}          @tab @code{Host}
@item                           @tab @code{Db}            @tab @code{Db}
@item                           @tab @code{User}          @tab @code{User}
@item                           @tab @code{Table_name}    @tab @code{Table_name}
@item                           @tab                      @tab @code{Column_name}

@item @strong{Privilege columns} @tab @code{Table_priv}    @tab @code{Column_priv}
@item                           @tab @code{Column_priv}   @tab

@item @strong{Other columns}    @tab @code{Timestamp}     @tab @code{Timestamp}
@item                           @tab @code{Grantor}       @tab
@end multitable

The @code{Timestamp} and @code{Grantor} columns currently are unused and are
discussed no further here.

Each grant table contains scope columns and privilege columns:

@itemize @bullet
@item
Scope columns determine the scope of each entry (row) in the tables; that is, the
context in which the entry applies.  For example, a @code{user} table entry
with @code{Host} and @code{User} values of @code{'thomas.loc.gov'} and
@code{'bob'} would be used for authenticating connections made to the server
from the host @code{thomas.loc.gov} by a client that specifies a username of
@code{bob}.  Similarly, a @code{db}
table entry with @code{Host}, @code{User}, and @code{Db} column values of
@code{'thomas.loc.gov'}, @code{'bob'} and @code{'reports'} would be used when
@code{bob} connects from the host @code{thomas.loc.gov} to access the
@code{reports} database.  The @code{tables_priv} and @code{columns_priv}
tables contain scope columns indicating tables or table/column combinations
to which each entry applies.

@item
Privilege columns indicate the privileges granted by a table entry; that is,
what operations can be performed.  The server combines the information in the
various grant tables to form a complete description of a user's privileges.
The rules used to do this are described in @ref{Request access}.

@end itemize

Scope columns contain strings. They are declared as shown here;
the default value for each is the empty string:

@multitable @columnfractions .20 .15
@item @strong{Column Name} @tab @strong{Type}
@item @code{Host}         @tab @code{CHAR(60)}
@item @code{User}         @tab @code{CHAR(16)}
@item @code{Password}     @tab @code{CHAR(16)}
@item @code{Db}           @tab @code{CHAR(64)}
@item @code{Table_name}   @tab @code{CHAR(60)}
@item @code{Column_name}  @tab @code{CHAR(60)}
@end multitable

Before MySQL 3.23, the @code{Db} column is @code{CHAR(32)} in some tables
and @code{CHAR(60)} in others.

@cindex case-sensitivity, in access checking
For access-checking purposes, comparisons of @code{Host} values are
case-insensitive.  @code{User}, @code{Password}, @code{Db}, and
@code{Table_name} values are case sensitive.
@code{Column_name} values are case insensitive in MySQL
3.22.12 or later.

In the @code{user}, @code{db}, and @code{host} tables, each privilege
is listed in a separate column that is declared as
@code{ENUM('N','Y') DEFAULT 'N'}. In other words, each privilege can be disabled
or enabled, with the default being disabled.

In the @code{tables_priv} and @code{columns_priv} tables, the privilege
columns are declared as @code{SET} columns. Values in these columns can
contain any combination of the privileges controlled by the table:

@multitable @columnfractions .15 .15 .55
@item @strong{Table Name}
 @tab @strong{Column Name}
 @tab @strong{Possible Set Elements}
@item @code{tables_priv}
 @tab @code{Table_priv}
 @tab @code{'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter'}
@item @code{tables_priv}
 @tab @code{Column_priv}
 @tab @code{'Select', 'Insert', 'Update', 'References'}
@item @code{columns_priv}
 @tab @code{Column_priv}
 @tab @code{'Select', 'Insert', 'Update', 'References'}
@end multitable

Briefly, the server uses the grant tables as follows:

@itemize @bullet
@item
The @code{user} table scope columns determine whether to reject or allow
incoming connections.  For allowed connections, any privileges granted in
the @code{user} table indicate the user's global (superuser) privileges.
These privileges apply to @emph{all} databases on the server.

@item
The @code{db} table scope columns determine which users can access which
databases from which hosts.  The privilege columns determine which operations
are allowed. A privilege granted at the database level applies to the database
and to all its tables.

@item
The @code{host} table is used in conjunction with the @code{db} table when you
want a given @code{db} table entry to apply to several hosts.  For example,
if you want a user to be able to use a database from several hosts in
your network, leave the @code{Host} value empty in the user's @code{db} table
entry, then populate the @code{host} table with an entry for each of those
hosts.  This mechanism is described more detail in @ref{Request access}.

@strong{Note}: The @code{host} table is not affected by the @code{GRANT} and
@code{REVOKE} statements. Most MySQL installations need not use this table at
all.

@item
The @code{tables_priv} and @code{columns_priv} tables are similar to
the @code{db} table, but are more fine-grained: They apply at the
table and column levels rather than at the database level.
A privilege granted at the table level applies to the table and to all its
columns.
A privilege granted at the column level applies only to a specific column.
@end itemize

Administrative privileges (such as @code{RELOAD} or @code{SHUTDOWN})
are specified only in the @code{user} table.  This is because
administrative operations are operations on the server itself and are not
database-specific, so there is no reason to list these privileges in the
other grant tables.  In fact, to determine whether you can perform an
administrative operation, the server need consult only the @code{user} table.

The @code{FILE} privilege also is specified only in the @code{user} table.
It is not an administrative privilege as such, but your ability to read or
write files on the server host is independent of the database you are
accessing.

The @command{mysqld} server reads the contents of the grant tables into memory
when it starts. You can tell it to re-read the tables by issuing a @code{FLUSH
PRIVILEGES} statement or executing a @command{mysqladmin flush-privileges} or
@command{mysqladmin reload} command.
Changes to the grant tables take effect as indicated in
@ref{Privilege changes}.

When you modify the contents of the grant tables, it is a good idea to make
sure that your changes set up privileges the way you want. One way to check
the privileges for a given account is to use the @code{SHOW GRANTS} statement.
For example, to determine the privileges that are granted to an account with
@code{Host} and @code{User} values of @code{pc84.example.com} and @code{bob},
issue this statement:

@example
mysql> SHOW GRANTS FOR 'bob'@@'pc84.example.com';
@end example

A useful
diagnostic tool is the @command{mysqlaccess} script, which Yves Carlier has
provided for the MySQL distribution.  Invoke @command{mysqlaccess} with
the @code{--help} option to find out how it works.
Note that @command{mysqlaccess} checks access using only the @code{user},
@code{db}, and @code{host} tables.  It does not check table or column
privileges specified in the @code{tables_priv} or @code{columns_priv} tables.

For additional help in diagnosing privilege-related problems, see
@ref{Access denied}.  For general advice on security issues, see
@ref{Security}.


@node Privileges provided, Connecting, Privileges, Privilege system
@subsection Privileges Provided by MySQL

@cindex privilege information, location

Information about account privileges is stored in the @code{user}, @code{db},
@code{host}, @code{tables_priv}, and @code{columns_priv} tables in the
@code{mysql} database.  The MySQL server reads the contents of these
tables into memory when it starts and re-reads them under the circumstances
indicated in @ref{Privilege changes}.  Access-control decisions are based
on the in-memory copies of the grant tables.

The names used in this manual to refer to the privileges provided by
MySQL are shown in the following table, along with the table column name
associated with each privilege in the grant tables and the context in
which the privilege applies. Further information about the meaning of
each privilege may be found at @ref{GRANT, , @code{GRANT}}.

@c TODO: probably should have that information here as well.

@c FIX agl 2002-06-13 Long items added, will need to re-measure colwidths!
@multitable @columnfractions .15 .20 .35
@item @strong{Privilege}             @tab @strong{Column}              @tab @strong{Context}
@item @code{ALTER}                   @tab @code{Alter_priv}            @tab tables
@item @code{DELETE}                  @tab @code{Delete_priv}           @tab tables
@item @code{INDEX}                   @tab @code{Index_priv}            @tab tables
@item @code{INSERT}                  @tab @code{Insert_priv}           @tab tables
@item @code{SELECT}                  @tab @code{Select_priv}           @tab tables
@item @code{UPDATE}                  @tab @code{Update_priv}           @tab tables
@item @code{CREATE}                  @tab @code{Create_priv}           @tab databases, tables, or indexes
@item @code{DROP}                    @tab @code{Drop_priv}             @tab databases or tables
@item @code{GRANT}                   @tab @code{Grant_priv}            @tab databases or tables
@item @code{REFERENCES}              @tab @code{References_priv}       @tab databases or tables
@item @code{CREATE TEMPORARY TABLES} @tab @code{Create_tmp_table_priv} @tab server administration
@item @code{EXECUTE}                 @tab @code{Execute_priv}          @tab server administration
@item @code{FILE}                    @tab @code{File_priv}             @tab file access on server host
@item @code{LOCK TABLES}             @tab @code{Lock_tables_priv}      @tab server administration
@item @code{PROCESS}                 @tab @code{Process_priv}          @tab server administration
@item @code{RELOAD}                  @tab @code{Reload_priv}           @tab server administration
@item @code{REPLICATION CLIENT}      @tab @code{Repl_client_priv}      @tab server administration
@item @code{REPLICATION SLAVE}       @tab @code{Repl_slave_priv}       @tab server administration
@item @code{SHOW DATABASES}          @tab @code{Show_db_priv}          @tab server administration
@item @code{SHUTDOWN}                @tab @code{Shutdown_priv}         @tab server administration
@item @code{SUPER}                   @tab @code{Super_priv}            @tab server administration
@end multitable

The @code{CREATE TEMPORARY TABLES}, @code{EXECUTE}, @code{LOCK TABLES},
@code{REPLICATION CLIENT}, @code{REPLICATION SLAVE}, @code{SHOW DATABASES},
and @code{SUPER} privileges were added in MySQL 4.0.2.

The @code{EXECUTE} and @code{REFERENCES} privileges currently are unused.

The @code{SELECT}, @code{INSERT}, @code{UPDATE}, and @code{DELETE}
privileges allow you to perform operations on rows in existing tables in
a database.

@code{SELECT} statements require the @code{SELECT} privilege only if they
actually retrieve rows from a table.  Some @code{SELECT} statements do not
access tables and can be executed without permission for any database.
For example, you can use the @command{mysql} client as a simple calculator
to evaluate expressions that make no reference to tables:

@example
mysql> SELECT 1+1;
mysql> SELECT PI()*2;
@end example

The @code{CREATE} and @code{DROP} privileges allow you to create new
databases and tables, or to drop (remove) existing databases and tables.
If you grant the @code{DROP} privilege for the @code{mysql}
database to a user, that user can drop the database in which the
MySQL access privileges are stored!

The @code{INDEX} privilege allows you to create or drop (remove) indexes.
@code{INDEX} applies to existing tables.
If you have the @code{CREATE} privilege for a table, you can include index
definitions in the @code{CREATE TABLE} statement.

The @code{ALTER} privilege allows you to use @code{ALTER TABLE} to change the
structure of or rename tables.

The @code{GRANT} privilege allows you to give to other users those
privileges that you yourself possess.

The @code{FILE} privilege gives you permission to read and write files on
the server host using the @code{LOAD DATA INFILE} and @code{SELECT ... INTO
OUTFILE} statements. A user who has the @code{FILE} privilege can read any
file on the server host that is either world-readable or readable by the MySQL
server. (This implies the user can read any file in any database
directory, because the server can access any of those files.)
The @code{FILE} privilege also allows the user to create new files in any
directory where the MySQL server has write access. Existing files cannot be
overwritten.

The remaining privileges are used for administrative operations. Many of
them can be performed by using the @command{mysqladmin} program or by
issuing SQL statements.  The following table shows which @command{mysqladmin}
commands each administrative privilege allows you to execute:

@multitable @columnfractions .15 .75
@item @strong{Privilege}  @tab @strong{Commands Permitted to Privilege Holders}
@item @code{RELOAD}       @tab @code{flush-hosts}, @code{flush-logs}, @code{flush-privileges}, @code{flush-status}, @code{flush-tables}, @code{flush-threads}, @code{refresh}, @code{reload}
@item @code{SHUTDOWN}     @tab @code{shutdown}
@item @code{PROCESS}      @tab @code{processlist}
@item @code{SUPER}        @tab @code{kill}
@end multitable

The @code{reload} command tells the server to re-read the grant tables
into memory.  @code{flush-privileges} is a synonym for @code{reload}.
The @code{refresh} command closes and reopens the log files and flushes
all tables.  The other @code{flush-@var{xxx}} commands perform functions similar to
@code{refresh}, but are more specific and may be preferable in some instances.
For example, if you want to flush just the log files, @code{flush-logs}
is a better choice than @code{refresh}.

The @code{shutdown} command shuts down the server. This command can be issued
only from @command{mysqladmin}. There is no corresponding SQL statement.

The @code{processlist} command displays information about the threads
executing within the server (that is, about the statements being executed by
clients associated with other accounts).
The @code{kill} command terminates server threads.
You can always display or kill your own threads, but you need the
@code{PROCESS} privilege to display threads initiated by other users and
the @code{SUPER} privilege to kill them.
@xref{KILL,  , @code{KILL}}. Prior to MySQL 4.0.2 when @code{SUPER} was
introduced, the @code{PROCESS} privilege controls the ability to both see and
terminate threads for other clients.

The @code{CREATE TEMPORARY TABLES} privilege allows the use of the keyword
@code{TEMPORARY} in @code{CREATE TABLE} statements.

The @code{LOCK TABLES} privilege allows the use of explicit @code{LOCK TABLES}
statements to lock tables for which you have the @code{SELECT} privilege.
This includes the use of write locks, which prevents anyone else from reading
the locked table.

The @code{REPLICATION CLIENT} privilege allows the use of @code{SHOW MASTER
STATUS} and @code{SHOW SLAVE STATUS}.

The @code{REPLICATION SLAVE} privilege should be granted to accounts that are
used by slave servers when they connect to the current server as their master.
Without this privilege, the slave cannot request updates that have been made
to databases on the master server.

The @code{SHOW DATABASES} privilege allows the account to see database names
by issuing the @code{SHOW DATABASE} statement. Accounts that do not have this
privilege see only databases for which they have some privileges, and cannot
use the statement at all if the server was started with the
@code{--skip-show-database} option.

It is a good idea in general to grant privileges to only those accounts
that need them, but you should exercise particular caution in granting
administrative privileges:

@itemize @bullet
@item
The @code{GRANT} privilege allows users to give their privileges to
other users.  Two users with different privileges and with the @code{GRANT}
privilege are able to combine privileges.

@item
The @code{ALTER} privilege may be used to subvert the privilege system
by renaming tables.

@item
The @code{FILE} privilege can be abused to read into a database table any
files that the MySQL server can read on the server host. This includes all
world-readable files and files in the server's data directory. The table
can then be accessed using @code{SELECT} to transfer its contents to the
client host.

@item
The @code{SHUTDOWN} privilege can be abused to deny service to other
users entirely by terminating the server.

@item
The @code{PROCESS} privilege can be used to view the plain text of
currently executing queries, including queries that set or change passwords.

@item
The @code{SUPER} privilege can be used to terminate other clients or change
how the server operates.

@item
Privileges granted for the @code{mysql} database itself can be used to
change passwords and other access privilege information.  Passwords are
stored encrypted, so a malicious user cannot simply read them to know the
plain text password.  However, a user with write access to the @code{user}
table @code{Password} column can change an account's password, and then
connect to the MySQL server using that account.

@end itemize

There are some things that you cannot do with the MySQL
privilege system:

@itemize @bullet
@item
You cannot explicitly specify that a given user should be denied access.
That is, you cannot explicitly match a user and then refuse the connection.

@item
You cannot specify that a user has privileges to create or drop tables
in a database but not to create or drop the database itself.
@end itemize


@node Connecting, Connection access, Privileges provided, Privilege system
@subsection Connecting to the MySQL Server

@cindex connecting, to the server
@cindex default hostname
@cindex hostname, default
@cindex server, connecting

MySQL client programs generally expect you to specify connection
parameters when you want to access a MySQL server:

@itemize @bullet
@item
The name of the host where the MySQL server is running
@item
Your username
@item
Your password
@end itemize

For example, the
@command{mysql} client can be started as follows from a command-line prompt
(indicated here by @code{shell>}):

@example
shell> mysql -h @var{host_name} -u @var{user_name} -p@var{your_pass}
@end example

Alternate forms of the @code{-h}, @code{-u}, and @code{-p} options are
@code{--host=@var{host_name}}, @code{--user=@var{user_name}}, and
@code{--password=@var{your_pass}}.  Note that there is @emph{no space} between
@code{-p} or @code{--password=} and the password following it.

If you use a @code{-p} or @code{--password} option but do not specify the
password value, the client program will prompt you to enter the password.
The password is not displayed as you enter it.
This is more secure than giving the password on the command line.
Any user on your system may be able to see a password specified on the command
line by executing a command such as @command{ps auxww}.
@xref{Password security}.

MySQL client programs use default values for any connection parameter option
that you do not specify:

@itemize @bullet
@item
The default hostname is @code{localhost}.

@item
The default username is @code{ODBC} on Windows and your Unix login name
on Unix.

@item
No password is supplied if @code{-p} is missing.
@end itemize

Thus, for a Unix user with a login name of @code{joe}, all of the following
commands are equivalent:

@example
shell> mysql -h localhost -u joe
shell> mysql -h localhost
shell> mysql -u joe
shell> mysql
@end example

Other MySQL clients behave similarly.

You can specify different default values to be used when you
make a connection so that you need not enter them on the command line each
time you invoke a client program.  This can be done in a couple of ways:

@itemize @bullet
@item
@tindex .my.cnf file
You can specify connection parameters in the @code{[client]} section of an
option file.  The relevant section of the file might look like this:

@example
[client]
host=@var{host_name}
user=@var{user_name}
password=@var{your_pass}
@end example

Option files are discussed further in @ref{Option files}.

@item
@tindex @code{MYSQL_HOST} environment variable
@tindex environment variable, @code{MYSQL_HOST}
@tindex @code{MYSQL_PWD} environment variable
@tindex environment variable, @code{MYSQL_PWD}
@tindex @code{USER} environment variable
@tindex environment variable, @code{USER}
You can specify some connection parameters using environment variables.  The
host can be specified for @command{mysql} using @code{MYSQL_HOST}.  The
MySQL username can be specified using @code{USER} (this is for
Windows and NetWare only).  The password can be specified using
@code{MYSQL_PWD},
although this is insecure; see @ref{Password security}.
For a list of variables, see @ref{Environment variables}.
@end itemize


@node Connection access, Request access, Connecting, Privilege system
@subsection Access Control, Stage 1: Connection Verification

@cindex access control
@cindex control access
@cindex connecting, verification
@cindex testing, connection to the server

When you attempt to connect to a MySQL server, the server accepts or
rejects the connection based on your identity and whether you can
verify your identity by supplying the correct password.  If not, the server
denies access to you completely.  Otherwise, the server accepts the
connection, then enters Stage 2 and waits for requests.

Your identity is based on two pieces of information:

@itemize @bullet
@item
The client host from which you connect

@item
Your MySQL username
@end itemize

Identity checking is performed using the three @code{user} table scope columns
(@code{Host}, @code{User}, and @code{Password}).  The server accepts the
connection only if the @code{Host} and @code{User} columns in some
@code{user} table record match the client hostname and username,
and the client supplies the password specified in that record.

@code{Host} values in the @code{user} table may be specified as follows:

@itemize @bullet
@item
A @code{Host} value may be a hostname or an IP number, or @code{'localhost'}
to indicate the local host.

@item
@cindex wildcards, in @code{mysql.user} table
You can use the wildcard characters @samp{%} and @samp{_} in @code{Host}
column values.
These have the same meaning as for pattern-matching operations
performed with the @code{LIKE} operator.
For example, a @code{Host} value of @code{'%'} matches any hostname, whereas a
value of @code{'%.mysql.com'} matches any host in the @code{mysql.com} domain.

@item
@cindex netmask notation, in @code{mysql.user} table
As of MySQL 3.23, for @code{Host} values specified as
IP numbers, you can specify a netmask indicating how many address bits to
use for the network number. For example:

@example
mysql> GRANT ALL PRIVILEGES ON db.*
    -> TO david@@'192.58.197.0/255.255.255.0';
@end example

This allows @code{david} to connect from any client host having an IP number
@code{client_ip} for which the following condition is true:

@example
client_ip & netmask = host_ip
@end example

That is, for the @code{GRANT} statement just shown:

@example
client_ip & 255.255.255.0 = 192.58.197.0
@end example

IP numbers that satisfy this condition and can connect to the
MySQL server are those that lie in the range from @code{192.58.197.0} to
@code{192.58.197.255}.

@item
A blank @code{Host} value in a @code{db} table record means that its
privileges should be combined with those in the entry in the @code{host}
table that matches the client hostname.  The privileges are combined
using an AND (intersection) operation, not OR (union).  You can find more
information about the @code{host} table in @ref{Request access}.

A blank @code{Host} value in the other grant tables is the same as @code{'%'}.

@end itemize

Because you can use IP wildcard values in the @code{Host} column
(for example, @code{'144.155.166.%'} to match every host on a
subnet), someone could try to exploit this capability by naming a host
@code{144.155.166.somewhere.com}.  To foil such attempts, MySQL disallows
matching on hostnames that start with digits and a dot. Thus, if you have
a host named something like @code{1.2.foo.com}, its name will never match
the @code{Host} column of the grant tables.  An IP wildcard value can
match only IP numbers, not hostnames.

@cindex anonymous user
In the @code{User} column, wildcard characters are not allowed, but you can
specify a blank value, which matches any name.  If the @code{user} table
entry that matches an incoming connection has a blank username, the user is
considered to be an anonymous user with no name, not a user with the
name that the client actually specified.  This means that a blank username
is used for all further access checking for the duration of the connection
(that is, during Stage 2).

The @code{Password} column can be blank.  This is not a wildcard and does
not mean that any password matches. It means that the user must connect
without specifying a password.

@findex PASSWORD()
Non-blank @code{Password} values in the @code{user} table represent
encrypted passwords.  MySQL does not store passwords in plaintext form for
anyone to see.  Rather, the password supplied by a user who is attempting to
connect is encrypted (using the @code{PASSWORD()} function). The encrypted
password then is used during the connection process when checking whether
the password is correct. (This is done without the encrypted password ever
traveling over the connection.)  From MySQL's point of view, the
encrypted password is the REAL password, so you should not give anyone
access to it!  In particular, don't give non-administrative users read
access to the tables in the @code{mysql} database!

From version 4.1 on, MySQL employs a stronger authentication method that has
better password protection during the connection process than in earlier
versions. It is secure even if TCP/IP packets are sniffed or the
@code{mysql} database is captured.  Password encryption is discussed further
in @ref{Password hashing}.

The following examples show how various combinations of @code{Host} and
@code{User} values in the @code{user} table apply to incoming
connections:

@multitable @columnfractions .35 .15 .50
@item @code{Host} @strong{Value} @tab @code{User} @strong{Value} @tab @strong{Connections Matched by Entry}
@item @code{'thomas.loc.gov'} @tab @code{'fred'} @tab @code{fred}, connecting from @code{thomas.loc.gov}
@item @code{'thomas.loc.gov'} @tab @code{''} @tab Any user, connecting from @code{thomas.loc.gov}
@item  @code{'%'} @tab @code{'fred'} @tab @code{fred}, connecting from any host
@item @code{'%'} @tab  @code{''} @tab Any user, connecting from any host
@item @code{'%.loc.gov'} @tab @code{'fred'} @tab @code{fred}, connecting from any host in the @code{loc.gov} domain
@item @code{'x.y.%'} @tab @code{'fred'} @tab @code{fred}, connecting from @code{x.y.net}, @code{x.y.com}, @code{x.y.edu}, and so on. (this is probably not useful)
@item @code{'144.155.166.177'} @tab @code{'fred'} @tab @code{fred}, connecting from the host with IP address @code{144.155.166.177}
@item @code{'144.155.166.%'} @tab @code{'fred'} @tab @code{fred}, connecting from any host in the @code{144.155.166} class C subnet
@item @code{'144.155.166.0/255.255.255.0'} @tab @code{'fred'} @tab Same as previous example
@end multitable

It is possible for the client hostname and username of
an incoming connection to match more than one entry in the
@code{user} table.  The preceding set of examples demonstrates this:
Several of the entries shown match a connection from @code{thomas.loc.gov} by
@code{fred}.

When multiple matches are possible, the server must determine which of them to
use.  It resolves this issue as follows:

@itemize @bullet
@item
Whenever the server reads the @code{user} table into memory, it sorts the
entries.
@item
When a client attempts to connect, the server looks through the entries in
sorted order.
@item
The server uses the first entry that matches the client hostname and username.
@end itemize

To see how this works, suppose that the @code{user} table looks like this:

@example
+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| %         | root     | ...
| %         | jeffrey  | ...
| localhost | root     | ...
| localhost |          | ...
+-----------+----------+-
@end example

When the server reads in the table, it orders the entries with the
most-specific @code{Host} values first.  Literal hostnames and IP numbers
are the most specific. The pattern @code{'%'} means ``any host'' and is
least specific.  Entries with the same @code{Host} value are ordered with
the most-specific @code{User} values first (a blank @code{User} value means
``any user'' and is least specific). For the @code{user} table just shown,
the result after sorting looks like this:

@example
+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| localhost | root     | ...
| localhost |          | ...
| %         | jeffrey  | ...
| %         | root     | ...
+-----------+----------+-
@end example

@cindex grant tables, sorting
@cindex sorting, grant tables
@cindex @code{user} table, sorting
When a client attempts to connect, the server looks through the sorted entries
and uses the first match found.  For a connection from @code{localhost} by
@code{jeffrey}, two of the entries in the table match:
the one with @code{Host} and @code{User} values of @code{'localhost'} and
@code{''}, and the one with values of @code{'%'} and @code{'jeffrey'}.
The @code{'localhost'} entry appears first in sorted order, so that is the one
the server uses.

Here is another example.  Suppose that the @code{user} table looks like this:

@example
+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| %              | jeffrey  | ...
| thomas.loc.gov |          | ...
+----------------+----------+-
@end example

The sorted table looks like this:

@example
+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| thomas.loc.gov |          | ...
| %              | jeffrey  | ...
+----------------+----------+-
@end example

A connection by @code{jeffrey} from @code{thomas.loc.gov} is matched by the
first entry, whereas a connection by @code{jeffrey} from @code{whitehouse.gov}
is matched by the second.

It is a common misconception to think that, for a given username, all entries
that explicitly name that user will be used first when the server attempts to
find a match for the connection.  This is simply not true.  The previous
example illustrates this, where a connection from @code{thomas.loc.gov} by
@code{jeffrey} is first matched not by the entry containing @code{'jeffrey'}
as the @code{User} column value, but by the entry with no username!
As a result, @code{jeffrey} will be authenticated as an anonymous user, even
though he specified a username when connecting.

If you are able to connect to the server, but your privileges are not
what you expect, you probably are being authenticated as some other
account.  To find out what account the server used to authenticate
you, use the @code{CURRENT_USER()} function. It returns a value in
@code{@var{user_name}@@@var{host_name}} format that indicates the @code{User}
and @code{Host} values from the matching @code{user} table record.
Suppose that @code{jeffrey} connects and issues the following query:

@example
mysql> SELECT CURRENT_USER();
+----------------+
| CURRENT_USER() |
+----------------+
| @@localhost     |
+----------------+
@end example

The result shown here indicates that the matching @code{user} table entry
had a blank @code{User} column value.  In other words, the server is
treating @code{jeffrey} as an anonymous user.

The @code{CURRENT_USER()} function is available as of MySQL 4.0.6.
@xref{Information functions}.
Another thing you can do to diagnose authentication problems is to print
out the @code{user} table and sort it by hand to see where the first
match is being made.


@node Request access, Privilege changes, Connection access, Privilege system
@subsection Access Control, Stage 2: Request Verification

Once you establish a connection, the server enters Stage 2 of access
control.  For each request that comes in on the connection, the server
determines what operation you want to perform, then checks whether you have
sufficient privileges to do so.  This is where the privilege columns in the
grant tables come into play.  These privileges can come from any of the
@code{user}, @code{db}, @code{host}, @code{tables_priv}, or
@code{columns_priv} tables.  (You may find it helpful to refer to
@ref{Privileges}, which lists the columns present in each of the grant
tables.)

The @code{user} table grants privileges that are assigned to you on a global
basis and that apply no matter what the current database is.  For example, if
the @code{user} table grants you the @code{DELETE} privilege, you can
delete rows from any table in any database on the server host!  In other words,
@code{user} table privileges are superuser privileges.  It is wise to grant
privileges in the @code{user} table only to superusers such as
database administrators.  For other users, you should leave the privileges
in the @code{user} table set to @code{'N'} and grant privileges at more
specific levels only. You can grant privileges for particular databases,
tables, or columns.

@cindex anonymous user
@cindex wildcards, in @code{mysql.db} table
@cindex wildcards, in @code{mysql.host} table
The @code{db} and @code{host} tables grant database-specific privileges.
Values in the scope columns of these tables can take the following forms:

@itemize @bullet
@item
The wildcard characters @samp{%} and @samp{_} can be used in the @code{Host}
and @code{Db} columns of either table.  These have the same meaning as for
pattern-matching operations performed with the @code{LIKE} operator.  If you
want to use either character literally when granting privileges, you must
escape it with a backslash.  For example, to include @samp{_} character
as part of a database name, specify it as @samp{\_} in the @code{GRANT}
statement.

@item
A @code{'%'} @code{Host} value in the @code{db} table means ``any host.'' A
blank @code{Host} value in the @code{db} table means ``consult the
@code{host} table for further information'' (a process that is described later
in this section).

@item
A @code{'%'} or blank @code{Host} value in the @code{host} table means ``any
host.''

@item
A @code{'%'} or blank @code{Db} value in either table means ``any database.''

@item
A blank @code{User} value in either table matches the anonymous user.
@end itemize

@cindex grant tables, sorting
@cindex sorting, grant tables
@cindex @code{db} table, sorting
@cindex @code{host} table, sorting

The server reads in and sorts the @code{db} and @code{host} tables at the
same time that it reads the @code{user} table.  The server sorts the @code{db}
table based on the @code{Host}, @code{Db}, and @code{User} scope columns,
and sorts the @code{host} table based on the @code{Host} and @code{Db}
scope columns.  As with the @code{user} table, sorting puts the
most-specific values first and least-specific values last, and when the
server looks for matching entries, it uses the first match that it finds.

@cindex wildcards, in @code{mysql.tables_priv} table
@cindex wildcards, in @code{mysql.columns_priv} table

The @code{tables_priv} and @code{columns_priv} tables grant table-specific and
column-specific privileges.  Values in the scope columns of these tables can
take the following form:

@itemize @bullet
@item
The wildcard characters @samp{%} and @samp{_} can be used in the @code{Host}
column of either table.  These have the same meaning as for pattern-matching
operations performed with the @code{LIKE} operator.

@item
A @code{'%'} or blank @code{Host} value in either table means ``any host.''

@item
The @code{Db}, @code{Table_name}, and @code{Column_name} columns cannot contain
wildcards or be blank in either table.
@end itemize

The server sorts the @code{tables_priv} and @code{columns_priv} tables based
on the @code{Host}, @code{Db}, and @code{User} columns.  This is similar to
@code{db} table sorting, but simpler because only the @code{Host} column can
contain wildcards.

The request verification process is described here.  (If you are familiar
with the access-checking source code, you will notice that the description
here differs slightly from the algorithm used in the code.  The description
is equivalent to what the code actually does; it differs only to make the
explanation simpler.)

For requests that require administrative privileges such as @code{SHUTDOWN} or
@code{RELOAD}, the
server checks only the @code{user} table entry because that is the only table
that specifies administrative privileges.  Access is granted if the entry
allows the requested operation and denied otherwise.  For example, if you
want to execute @command{mysqladmin shutdown} but your @code{user} table entry
doesn't grant the @code{SHUTDOWN} privilege to you, the server denies access
without even checking the @code{db} or @code{host} tables.  (They
contain no @code{Shutdown_priv} column, so there is no need to do so.)

For database-related requests (@code{INSERT}, @code{UPDATE}, and so on), the
server first checks the user's global (superuser) privileges by looking in
the @code{user} table entry.  If the entry allows the requested operation,
access is granted.  If the global privileges in the @code{user} table are
insufficient, the server determines the user's database-specific privileges
by checking the @code{db} and @code{host} tables:

@enumerate
@item
The server looks in the @code{db} table for a match on the @code{Host},
@code{Db}, and @code{User} columns.  The @code{Host} and @code{User} columns are
matched to the connecting user's hostname and MySQL username.  The
@code{Db} column is matched to the database that the user wants to access.  If
there is no entry for the @code{Host} and @code{User}, access is denied.

@item
If there is a matching @code{db} table entry and its @code{Host} column is
not blank, that entry defines the user's database-specific privileges.

@item
If the matching @code{db} table entry's @code{Host} column is blank, it
signifies that the @code{host} table enumerates which hosts should be allowed
access to the database.  In this case, a further lookup is done in the
@code{host} table to find a match on the @code{Host} and @code{Db} columns.
If no @code{host} table entry matches, access is denied.  If there is a
match, the user's database-specific privileges are computed as the
intersection (@emph{not} the union!) of the privileges in the @code{db} and
@code{host} table entries; that is, the privileges that are @code{'Y'} in both
entries.  (This way you can grant general privileges in the @code{db} table
entry and then selectively restrict them on a host-by-host basis using the
@code{host} table entries.)
@end enumerate

After determining the database-specific privileges granted by the @code{db}
and @code{host} table entries, the server adds them to the global privileges
granted by the @code{user} table.  If the result allows the requested
operation, access is granted.  Otherwise, the server successively
checks the user's table and column privileges in the @code{tables_priv}
and @code{columns_priv} tables, adds those to the user's privileges,
and allows or denies access based on the result.

Expressed in boolean terms, the preceding description of how a user's
privileges are calculated may be summarized like this:

@example
global privileges
OR (database privileges AND host privileges)
OR table privileges
OR column privileges
@end example

It may not be apparent why, if the global @code{user} entry privileges are
initially found to be insufficient for the requested operation, the server
adds those privileges to the database, table, and column privileges
later. The reason is that a request might require more than one type of
privilege.  For example, if you execute an @code{INSERT INTO ...  SELECT}
statement, you need both the @code{INSERT} and the @code{SELECT} privileges.
Your privileges might be such that the @code{user} table entry grants one
privilege and the @code{db} table entry grants the other.  In this case, you
have the necessary privileges to perform the request, but the server cannot
tell that from either table by itself; the privileges granted by the entries
in both tables must be combined.

@cindex @code{host} table
@cindex tables, @code{host}

The @code{host} table is not affected by the @code{GRANT} or @code{REVOKE}
statements, so it is unused in most MySQL installations. If you modify
it directly, you can use it for some specialized purposes, such as to to
maintain a list of secure servers.  For example, at TcX, the @code{host}
table contains a list of all machines on the local network. These are
granted all privileges.

You can also use the @code{host} table to indicate hosts that are @emph{not}
secure.  Suppose that you have a machine @code{public.your.domain} that is located
in a public area that you do not consider secure.  You can allow access to
all hosts on your network except that machine by using @code{host} table
entries
like this:

@example
+--------------------+----+-
| Host               | Db | ...
+--------------------+----+-
| public.your.domain | %  | ... (all privileges set to 'N')
| %.your.domain      | %  | ... (all privileges set to 'Y')
+--------------------+----+-
@end example

@cindex privilege, changes
@cindex changes to privileges
@cindex tables, grant
@cindex grant tables

Naturally, you should always test your entries in the grant tables (for
example, by using @code{SHOW GRANTS} or
@command{mysqlaccess}) to make sure that your access privileges are
actually set up the way you think they are.


@node Privilege changes, Access denied, Request access, Privilege system
@subsection When Privilege Changes Take Effect

When @command{mysqld} starts, all grant table contents are read into memory and
become effective for access control at that point.

When the server reloads the grant tables, privileges for
existing client connections are affected as follows:

@itemize @bullet
@item
Table and column privilege changes take effect with the client's next
request.

@item
Database privilege changes take effect at the next @code{USE @var{db_name}}
statement.

@item
Changes to global privileges and passwords take effect the next time
the client connects.
@end itemize

If you modify the grant tables using @code{GRANT}, @code{REVOKE}, or
@code{SET PASSWORD}, the server notices these changes and reloads the
grant tables into memory again immediately.

If you modify the grant tables directly using statements such as
@code{INSERT}, @code{UPDATE}, or @code{DELETE}, your changes have
no effect on privilege checking until you either restart the server
or tell it to reload the tables.  To reload the grant tables manually,
issue a @code{FLUSH PRIVILEGES} statement or execute a @command{mysqladmin
flush-privileges} or @command{mysqladmin reload} command.

If you change the grant tables directly but forget to reload them, your
changes will have @emph{no effect} until you restart the server.  This may
leave you wondering why your changes don't seem to make any difference!


@node Access denied, Password hashing, Privilege changes, Privilege system
@subsection Causes of @code{Access denied} Errors

@c TODO: some of these items apply only to old systems and are now more
@c of archaeological than practical value. Probably should move them to
@c the end of the list.

If you encounter problems when you try to connect to the
MySQL server, the following items describe some courses of
action you can take to correct the problem.

@itemize @bullet
@item
Make sure that the server is running. If it is not running, you cannot connect to it.
For example, if you attempt to connect to the server and see a message such
as one of those following, one cause might be that the server is not running:

@example
shell> mysql
ERROR 2003: Can't connect to MySQL server on '@var{host_name}' (111)
shell> mysql
ERROR 2002: Can't connect to local MySQL server through socket
'/tmp/mysql.sock' (111)
@end example

It might also be that the server is running, but you are trying to connect
using a TCP/IP port, named pipe, or Unix socket file different from those
on which the server is listening. To correct this when you invoke a client
program, specify a @code{--port} option to indicate the proper port, or a
@code{--socket} option to indicate the proper named pipe or Unix socket
file.
To find out what port is used, and where the socket is, you can do:

@example
shell> netstat -l | grep mysql
@end example

@item
The grant tables must be properly set up so that the server can use them for
access control.  For some distribution types (such as binary distributions
on Windows on RPM distributions on Linux), the installation process
initializes the @code{mysql} database containing the grant tables.  For
distributions that do not do this, you should initialize the grant tables
manually by running the @command{mysql_install_db} script.  For details, see
@ref{Unix post-installation}.

One way to determine whether you need to initialize the grant tables is to
look for a @file{mysql} directory under the data directory. (The data
directory normally is named @file{data} or @file{var} and is located under
your MySQL installation directory.)  Make sure that you have a file named
@file{user.MYD} in the @file{mysql} database directory.  If you do not,
execute the @command{mysql_install_db} script.  After running this script and
starting the server, test the initial privileges by executing this command:

@example
shell> mysql -u root test
@end example

The server should let you connect without error.

@item
After a fresh installation, you should connect to the server and set up
your users and their access permissions:

@example
shell> mysql -u root mysql
@end example

The server should let you connect because the MySQL @code{root} user
has no password initially.  That is also a security risk, so setting the
password for the
@code{root} accounts is something you should do while you're setting up
your other MySQL users.
For instructions on setting the initial passwords, see @ref{Default
privileges}.

@item
@cindex @command{mysql_fix_privilege_tables}
If you have updated an existing MySQL installation to a newer version, did
you run the @command{mysql_fix_privilege_tables} script?  If not, do so. The
structure of the grant tables changes occasionally when new capabilities are
added, so after an upgrade you should always make sure that your tables have
the current structure. For instructions, see @ref{Upgrading-grant-tables}.

@item
If a client program receives the following error message when it tries
to connect, it means that the server expects passwords in a newer format
than the client is capable of generating:

@example
shell> mysql
Client does not support authentication protocol requested
by server; consider upgrading MySQL client
@end example

For information on how to deal with this, see @ref{Password hashing} and
@ref{Old client}.

@item
If you try to connect as @code{root} and get the following error,
it means that you don't have an entry in the @code{user} table with a
@code{User} column value of @code{'root'} and that @command{mysqld} cannot
resolve the hostname for your client:

@example
Access denied for user ''@@'unknown' to database mysql
@end example

In this case, you must restart the server with the @code{--skip-grant-tables}
option and edit your @file{/etc/hosts} or @file{\windows\hosts} file to
add an entry for your host.

@item
@cindex option files
@cindex configuration files
@cindex environment variables
@tindex .my.cnf file
Remember that client programs will use connection parameters specified
in option files or environment variables.  If a client program seems to
be sending incorrect default connection parameters when you don't specify
them on the command line, check your environment and any applicable option
files. For example, if you get @code{Access denied} when you run a client
without any options, make sure that you haven't specified an old password in
any of your option files!

You can suppress the use of option files by a client program by invoking it
with the @code{--no-defaults} option. For example:

@example
shell> mysqladmin --no-defaults -u root version
@end example

The option files that clients use are listed in @ref{Option files}.
Environment variables are listed in @ref{Environment variables}.

@item
If you get the following error, it means that you are using an incorrect
@code{root} password:

@example
shell> mysqladmin -u root -p@var{xxxx} ver
Access denied for user 'root'@@'localhost' (using password: YES)
@end example

If the preceding error occurs even when you haven't specified a password,
it means that you have an incorrect password listed in some option
file. Try the @code{--no-defaults} option as described in the previous item.

For information on changing passwords, see @ref{Passwords}.

If you have lost or forgotten the @code{root} password, you can restart
@command{mysqld} with @code{--skip-grant-tables} to change the password.
@xref{Resetting permissions}.

@item
If you change a password by using @code{SET PASSWORD}, @code{INSERT}, or
@code{UPDATE}, you must encrypt the password using the @code{PASSWORD()}
function.  If you do not use @code{PASSWORD()} for these statements,
the password will not work. For example, the following statement sets a
password, but fails to encrypt it, so the user will not be able to connect
afterward:

@example
mysql> SET PASSWORD FOR 'abe'@@'@var{host_name}' = 'eagle';
@end example

Instead, set the password like this:

@example
mysql> SET PASSWORD FOR 'abe'@@'@var{host_name}' = PASSWORD('eagle');
@end example

The @code{PASSWORD()} function is unnecessary when you specify a password
using the @code{GRANT} statement or the @command{mysqladmin password} command,
both of which automatically use @code{PASSWORD()} to encrypt the password.
@xref{Passwords}.

@item
@code{localhost} is a synonym for your local hostname, and is also the
default host to which clients try to connect if you specify no host
explicitly.  However, connections to @code{localhost} on Unix systems
do not work if you are using a MySQL version older than 3.23.27 that uses
MIT-pthreads: @code{localhost} connections are made using Unix socket files,
which were not supported by MIT-pthreads at that time.

To avoid this problem on such systems, you can use a @code{--host=127.0.0.1}
option to name the server host explicitly.  This will make a TCP/IP
connection to the local @command{mysqld} server. You can also use TCP/IP by
specifying a @code{--host} option that uses the actual hostname of the
local host.  In this case, the hostname must be specified in a @code{user}
table entry on the server host, even though you are running the client
program on the same host as the server.

@item
If you get an @code{Access denied} error when trying to connect to the
database with @code{mysql -u user_name}, you may have a problem
with the @code{user} table. Check this by executing @code{mysql -u root
mysql} and issuing this SQL statement:

@example
mysql> SELECT * FROM user;
@end example

The result should include an entry with the @code{Host} and @code{User}
columns matching your computer's hostname and your MySQL username.

@item
The @code{Access denied} error message will tell you who you are trying
to log in as, the client host from which you are trying to connect, and whether
or not you were using a password. Normally, you should have one entry in
the @code{user} table that exactly matches the hostname and username
that were given in the error message. For example, if you get an error
message that contains @code{using password: NO}, it means that you
tried to log in without an password.

@item
If the following error occurs when you try to connect from a host other than
the one on which the MySQL server is running, it means that there is no row
in the @code{user} table with a @code{Host} value that matches the client
host:

@example
Host ... is not allowed to connect to this MySQL server
@end example

You can fix this by setting up an account for the combination of client
hostname and username that you are using when trying to connect.

If you don't know the IP number
or hostname of the machine from which you are connecting, you should put
an entry with @code{'%'} as the @code{Host} column value in the @code{user}
table and restart @command{mysqld} with the @code{--log} option on the server
machine.  After trying to connect from the client machine, the information
in the MySQL log will indicate how you really did connect.  (Then change
the @code{'%'} in the @code{user} table entry to the actual hostname
that shows up in the log.  Otherwise, you'll have a system that is insecure
because it allows connections from any host for the given username.)

On Linux, another reason that this error might occur is that you are using
a binary MySQL version that is compiled with a different version of the
@code{glibc} library than the one you are using.  In this case, you should
either upgrade your operating system or @code{glibc}, or download a source
distribution of MySQL version and compile it yourself.  A source RPM is
normally trivial to compile and install, so this isn't a big problem.

@item
If you specify a hostname when trying to connect, but get an error message
where the hostname is not shown or is an IP number,
it means that the MySQL server got an error when trying to resolve the
IP number of the client host to a name:

@example
shell> mysqladmin -u root -p@var{xxxx} -h @var{some-hostname} ver
Access denied for user 'root'@@'' (using password: YES)
@end example

This indicates a DNS problem.  To fix it, execute @command{mysqladmin
flush-hosts} to reset the internal DNS hostname cache. @xref{DNS}.

Some permanent solutions are:

@itemize @minus
@item
Try to find out what is wrong with your DNS server and fix it.

@item
Specify IP numbers rather than hostnames in the MySQL grant tables.

@item
Put an entry for the client machine name in @code{/etc/hosts}.

@item
Start @command{mysqld} with the @code{--skip-name-resolve} option.

@item
Start @command{mysqld} with the @code{--skip-host-cache} option.

@item
On Unix, if you are running the server and the client on the same machine,
connect to @code{localhost}. Unix connections to @code{localhost} use a Unix
socket file rather than TCP/IP.

@item
On Windows, if you are running the server and the client on the same machine
and the server supports named pipe connections, connect to the hostname
@code{.} (period). Connections to @code{.} use a named pipe rather than
TCP/IP.
@end itemize

@item
If @code{mysql -u root test} works but @code{mysql -h @var{your_hostname} -u root
test} results in @code{Access denied} (where @var{your_hostname} is the
actual hostname of the local host), you may not have the correct name
for your host in the @code{user} table.  A common problem here is that the
@code{Host} value in the user table entry specifies an unqualified hostname,
but your system's name resolution routines return a fully qualified domain
name (or vice versa).  For example, if you have an entry with host
@code{'tcx'} in the @code{user} table, but your DNS tells MySQL that
your hostname is @code{'tcx.subnet.se'}, the entry will not work. Try adding
an entry to the @code{user} table that contains the IP number of your host as
the @code{Host} column value.  (Alternatively, you could add an entry to the
@code{user} table with a @code{Host} value that contains a wildcard; for
example, @code{'tcx.%'}.  However, use of hostnames ending with @samp{%} is
@emph{insecure} and is @emph{not} recommended!)

@item
If @code{mysql -u @var{user_name} test} works but @code{mysql -u @var{user_name}
@var{other_db_name}} does not, you have not granted database access for
@var{other_db_name} to the given user.

@item
If @code{mysql -u @var{user_name}} works when executed on the server host, but
@code{mysql -h @var{host_name} -u @var{user_name}} doesn't work when executed on a
remote client host, you have not enabled access to the server for the given
username from the remote host.

@item
If you can't figure out why you get @code{Access denied}, remove from the
@code{user} table all entries that have @code{Host} values containing
wildcards (entries that contain @samp{%} or @samp{_}).  A very common error
is to insert a new entry with @code{Host}=@code{'%'} and
@code{User}=@code{'@var{some_user}'}, thinking that this will allow you to specify
@code{localhost} to connect from the same machine.  The reason that this
doesn't work is that the default privileges include an entry with
@code{Host}=@code{'localhost'} and @code{User}=@code{''}.  Because that entry
has a @code{Host} value @code{'localhost'} that is more specific than
@code{'%'}, it is used in preference to the new entry when connecting from
@code{localhost}!  The correct procedure is to insert a second entry with
@code{Host}=@code{'localhost'} and @code{User}=@code{'@var{some_user}'}, or to
delete the entry with @code{Host}=@code{'localhost'} and
@code{User}=@code{''}.
After deleting the entry, remember to issue a @code{FLUSH PRIVILEGES}
statement to reload the grant tables.

@item
If you get the following error, you may have a problem with the @code{db} or
@code{host} table:

@example
Access to database denied
@end example

If the entry selected from the @code{db} table has an empty value in the
@code{Host} column, make sure that there are one or more corresponding entries in
the @code{host} table specifying which hosts the @code{db} table entry
applies to.

@item
If you are able to connect to the MySQL server, but get an @code{Access
denied} message whenever you issue a @code{SELECT ...  INTO OUTFILE} or
@code{LOAD DATA INFILE} statement, your entry in the @code{user} table
doesn't have the @code{FILE} privilege enabled.

@item
If you change the grant tables directly (for example, by using @code{INSERT},
@code{UPDATE}, or @code{DELETE} statements) and your changes seem to be
ignored, remember that you must execute a @code{FLUSH PRIVILEGES} statement
or a @command{mysqladmin flush-privileges} command to cause the server
to re-read the privilege tables. Otherwise, your changes have no effect
until the next time the server is restarted.  Remember that after you change
the @code{root} password with an @code{UPDATE} command, you won't need
to specify the new password until after you flush the privileges, because
the server won't know you've changed the password yet!

@item
If your privileges seem to have changed in the middle of a session, it may
be that a MySQL administrator has changed them.  Reloading the grant tables
affects new client connections, but it also affects existing connections
as indicated in @ref{Privilege changes}.

@item
If you have access problems with a Perl, PHP, Python, or ODBC program, try to
connect to the server with @code{mysql -u @var{user_name} @var{db_name}} or @code{mysql
-u @var{user_name} -p@var{your_pass} @var{db_name}}.  If you are able to connect using the
@command{mysql} client, the problem lies with your program, not with the
access privileges.  (There is no space between @code{-p} and the
password; you can also use the @code{--password=@var{your_pass}} syntax to specify
the password. If you use the @code{-p} option alone, MySQL will
prompt you for the password.)

@item
For testing, start the @command{mysqld} server with the
@code{--skip-grant-tables} option.  Then you can change the MySQL
grant tables and use the @command{mysqlaccess} script to check whether
your modifications have the desired effect.  When you are satisfied with your
changes, execute @command{mysqladmin flush-privileges} to tell the @command{mysqld}
server to start using the new grant tables.  (Reloading the
grant tables overrides the @code{--skip-grant-tables} option.  This allows
you to tell the server to begin using the grant tables again without stopping
and restarting it.)

@item
If everything else fails, start the @command{mysqld} server with a debugging
option (for example, @code{--debug=d,general,query}). This will print host and
user information about attempted connections, as well as information about
each command issued. @xref{Making trace files}.

@item
If you have any other problems with the MySQL grant tables and
feel you must post the problem to the mailing list, always provide a
dump of the MySQL grant tables. You can dump the tables with
the @command{mysqldump mysql} command. As always, post your problem using
the @command{mysqlbug} script.  @xref{Bug reports}.  In some cases, you may need
to restart @command{mysqld} with @code{--skip-grant-tables} to run
@command{mysqldump}.

@end itemize


@node Password hashing,  , Access denied, Privilege system
@subsection Password Hashing in MySQL 4.1

@c TODO: discuss --secure-auth option

@menu
* Application password use::    Implications of Password Hashing Changes for Application Programs
* Password hashing 4.1.0::      Password Hashing in MySQL 4.1.0
@end menu

MySQL user accounts are listed in the @code{user} table of the @code{mysql}
database. Each MySQL account is assigned a password, although
what is stored in the @code{Password} column of the @code{user} table is not the
plaintext version of the password, but a hash value computed from
it.  Password hash values are computed by the @code{PASSWORD()} function.

MySQL uses passwords in two phases of client/server communication:

@itemize @bullet

@item
When a client attempts to connect to the server, there is an initial
authentication step in which the client must present a password that has
a hash value matching the hash value stored in the @code{user} table for
the account that the client wants to use.

@item
After the client connects, it can (if it has sufficient privileges) set or
change the password hashes for accounts listed in the @code{user} table.
The client can do this by using the @code{PASSWORD()} function to generate a
password hash, or by using the @code{GRANT} or @code{SET PASSWORD}
statements.

@end itemize

In other words, the server @emph{uses} hash values during authentication when
a client first attempts to connect. The server @emph{generates} hash values
if a connected client invokes the @code{PASSWORD()} function or uses a
@code{GRANT}
or @code{SET PASSWORD} statement to set or change a password.

The password hashing mechanism was updated in MySQL 4.1 to provide
better security and to reduce the risk of passwords being intercepted.
However, this new mechanism is understood only by the 4.1 server and
4.1 clients, which can result in some compatibility problems.
A 4.1 client can connect to a pre-4.1 server, because the client
understands both the old and new password hashing mechanisms. However,
a pre-4.1 client that attempts to connect to a 4.1 server may run into
difficulties.  For example, a 4.0 @command{mysql} client that attempts to connect
to a 4.1 server may fail with the following error message:

@example
shell> mysql -h localhost -u root
Client does not support authentication protocol requested
by server; consider upgrading MySQL client
@end example

The following discussion describes the differences between the old and
new password mechanisms, and what you should do if you upgrade your
server to 4.1 but need to maintain backward compatibility with pre-4.1
clients. Additional information can be found in @ref{Old client}.

@strong{Note}: This discussion contrasts 4.1 behavior with pre-4.1 behavior,
but the 4.1 behavior described here actually begins with 4.1.1. MySQL
4.1.0 is an ``odd'' release because it has a slightly different mechanism
than that implemented in 4.1.1 and up.  Differences between 4.1.0 and
more recent versions are described further in @ref{Password hashing 4.1.0}.

Prior to MySQL 4.1, password hashes computed by the @code{PASSWORD()} function
are 16 bytes long.  Such hashes look like this:

@example
mysql> SELECT PASSWORD('mypass');
+--------------------+
| PASSWORD('mypass') |
+--------------------+
| 6f8c114b58f2ce9e   |
+--------------------+
@end example

The @code{Password} column of the @code{user} table (in which these hashes are stored)
also is 16 bytes long before MySQL 4.1.

As of MySQL 4.1, the @code{PASSWORD()} function has been modified to produce
a longer 41-byte hash value:

@example
mysql> SELECT PASSWORD('mypass');
+-----------------------------------------------+
| PASSWORD('mypass')                            |
+-----------------------------------------------+
| *43c8aa34cdc98eddd3de1fe9a9c2c2a9f92bb2098d75 |
+-----------------------------------------------+
@end example

Accordingly, the @code{Password} column in the @code{user} table also must be 41
bytes long to store these values:

@itemize @bullet
@item
If you perform a new installation of MySQL 4.1, the @code{Password} column
will be made 41 bytes long automatically.

@item
If you upgrade an older installation to 4.1, you should run the
@command{mysql_fix_privilege_tables} script to increase the length of the
@code{Password}
column from 16 to 41 bytes. (The script does not change existing
password values, which remain 16 bytes long.)

@end itemize

A widened @code{Password} column can store password hashes in both the old and
new formats. The format of any given password hash value can be
determined two ways:

@itemize @bullet
@item
The obvious difference is the length (16 bytes versus 41 bytes).

@item
A second difference is that password hashes in the new format always
begin with a @samp{*} character, whereas passwords in the old format never do.

@end itemize

The longer password hash format has better cryptographic properties, and
client authentication based on long hashes is more secure than that
based on the older short hashes.

The differences between short and long password hashes are relevant
both for how the server uses passwords during authentication and for
how it generates password hashes for connected clients that perform
password-changing operations.

The way in which the server uses password hashes during authentication
is affected by the width of the @code{Password} column:

@itemize @bullet

@item
If the column is short, only short-hash authentication is used.

@item
If the column is long, it can hold either short or long hashes, and
the server can use either format:

@itemize @minus

@item
Pre-4.1 clients can connect, although because they know only about
the old hashing mechanism, they can authenticate only for accounts that
have short hashes.

@item
4.1 clients can authenticate for accounts that have short or long hashes.

@end itemize

@end itemize

For short-hash accounts, the authentication process is actually a bit
more secure for 4.1 clients than for older clients.  In terms of security,
the gradient from least to most secure is:

@itemize @bullet

@item
Pre-4.1 client authenticating for account with short password hash

@item
4.1 client authenticating for account with short password hash

@item
4.1 client authenticating for account with long password hash

@end itemize

The way in which the server generates password hashes for connected
clients is affected by the width of the @code{Password} column and by the
@code{--old-passwords} option.  A 4.1 server generates long hashes only if certain
conditions are met:
The @code{Password} column must be wide enough to hold long
values and the @code{--old-passwords} option must not be given.
These conditions apply as follows:

@itemize @bullet

@item
The @code{Password} column must be wide enough to hold long hashes (41 bytes).
If the column has not been updated and still has the pre-4.1 width of
16 bytes, the server notices that long hashes cannot fit into it and
generates only short hashes when a client performs password-changing
operations using @code{PASSWORD()}, @code{GRANT}, or @code{SET PASSWORD}.
This is the behavior that
occurs if you have upgraded to 4.1 but have not yet run the
@command{mysql_fix_privilege_tables} script to widen the @code{Password} column.

@item
If the @code{Password} column is wide, it can store either short or long
password hashes. In this case, @code{PASSWORD()}, @code{GRANT}, and @code{SET PASSWORD}
generate long hashes unless the server was started with the
@code{--old-passwords} option. That option forces the server to generate
short password hashes instead.

@end itemize

The purpose of the @code{--old-passwords} option is to allow you to maintain
backward compatibility with pre-4.1 clients under circumstances where
the server would otherwise generate long password hashes. The option doesn't
affect authentication (4.1 clients can still use accounts that have
long password hashes), but it does prevent creation of a long
password hash in the @code{user} table as the result of a password-changing
operation. Were that to occur, the account no longer could be used
by pre-4.1 clients. Without the @code{--old-passwords} option, the following
undesirable scenario is possible:

@itemize @bullet

@item
An old client connects to an account that has a short password hash.

@item
The client changes its own password. Without @code{--old-passwords},
this results in the account having a long password hash.

@item
The next time the old client attempts to connect to the account, it cannot,
because the account now has a long password hash that requires the new
hashing mechanism during authentication. (Once an account has a long
password hash in the user table, only 4.1 clients can authenticate for it,
because pre-4.1 clients do not understand long hashes.)

@end itemize

This scenario illustrates that, if you must support older pre-4.1 clients,
it is dangerous to run a 4.1 server without using the @code{--old-passwords}
option.  By running the server with @code{--old-passwords}, password-changing
operations will not generate long password hashes and thus do not cause
accounts to become inaccessible to older clients. (Those clients cannot
inadvertently lock themselves out by changing their password and ending
up with a long password hash.)

The downside of the @code{--old-passwords} option is that any passwords you
create or change will use short hashes, even for 4.1 clients. Thus, you
lose the additional security provided by long password hashes. If you want
to create an account that has a long hash (for example, for use by 4.1
clients), you must do so while running the server without
@code{--old-passwords}.

The following scenarios are possible for running a 4.1 server:

@strong{Scenario 1:} Short @code{Password} column in user table:

@itemize @bullet

@item
Only short hashes can be stored in the @code{Password} column.

@item
The server uses only short hashes during client authentication.

@item
For connected clients, password hash-generating operations
involving @code{PASSWORD()}, @code{GRANT}, or @code{SET PASSWORD} use short hashes
exclusively.  Any change to an account's password results in
that account having a short password hash.

@item
The @code{--old-passwords} option can be used but is superfluous because
with a short @code{Password} column, the server will generate only short
password hashes anyway.

@end itemize

@strong{Scenario 2:} Long @code{Password} column; server not started with
@code{--old-passwords} option:

@itemize @bullet

@item
Short or long hashes can be stored in the @code{Password} column.

@item
4.1 clients can authenticate for accounts that have short or long
hashes.

@item
Pre-4.1 clients can authenticate only for accounts that have short
hashes.

@item
For connected clients, password hash-generating operations involving
@code{PASSWORD()}, @code{GRANT}, or @code{SET PASSWORD} use long hashes
exclusively.  A change to an account's password results in that account
having a long password hash.

@end itemize

As indicated earlier, a danger in this scenario is that it is possible for
accounts that have a short password hash to become inaccessible to pre-4.1
clients. A change to such an account's password made via @code{GRANT},
@code{PASSWORD()}, or @code{SET PASSWORD} results in the account being
given a long password hash. From that point on, no pre-4.1 client can
authenticate to that account until the client upgrades to 4.1.

To deal with this problem, you can change a password in a special way.
For example, normally you use @code{SET PASSWORD} as follows to change
an account password:

@example
mysql> SET PASSWORD FOR '@var{some_user}'@@'@var{some_host}' = PASSWORD('mypass');
@end example

To change the password but create a short hash, use the
@code{OLD_PASSWORD()} function instead:

@example
mysql> SET PASSWORD FOR '@var{some_user}'@@'@var{some_host}' = OLD_PASSWORD('mypass');
@end example

@code{OLD_PASSWORD()} is useful for situations in which you explicitly want
to generate a short hash.

@strong{Scenario 3:} Long @code{Password} column; server started with
@code{--old-passwords} option:

@itemize @bullet

@item
Short or long hashes can be stored in the @code{Password} column.

@item
4.1 clients can authenticate for accounts that have short or long
hashes (but note that it is possible to create long hashes only when
the server is started without @code{--old-passwords}).

@item
Pre-4.1 clients can authenticate only for accounts that have short
hashes.

@item
For connected clients, password hash-generating operations
involving @code{PASSWORD()}, @code{GRANT}, or @code{SET PASSWORD} use short hashes
exclusively.  Any change to an account's password results in that
account having a short password hash.

@end itemize

In this scenario, you cannot create accounts that have long password
hashes, because the @code{--old-passwords} option prevents generation of long hashes.  Also,
if you create an account with a long hash before using the
@code{--old-passwords}
option, changing the account's password while @code{--old-passwords} is in
effect results in the account being given a short password, causing it
to lose the security benefits of a longer hash.

The disadvantages for these scenarios may be summarized as follows:

In scenario 1, you cannot take advantage of longer hashes that provide more
secure authentication.

In scenario 2, accounts with short hashes become inaccessible to pre-4.1
clients if you change their passwords without explicitly using
@code{OLD_PASSWORD()}.

In scenario 3, @code{--old-passwords} prevents accounts with short hashes from
becoming inaccessible, but password-changing operations cause accounts
with long hashes to revert to short hashes, and you cannot change them
back to long hashes while @code{--old-passwords} is in effect.


@node Application password use, Password hashing 4.1.0, Password hashing, Password hashing
@subsubsection Implications of Password Hashing Changes for Application Programs

An upgrade to MySQL 4.1 can cause a compatibility issue for
applications that use @code{PASSWORD()} to generate passwords for their own
purposes. Applications really should not do this, because @code{PASSWORD()}
should be used only to manage passwords for MySQL accounts. But some
applications use @code{PASSWORD()} for their own purposes anyway.

If you upgrade to 4.1 and run the server under conditions where it
generates long password hashes, an application that uses @code{PASSWORD()}
for its own passwords will break.  The recommended course of action is
to modify the application to use another function, such as @code{SHA1()}
or @code{MD5()}, to produce hashed values.  If that is not possible, you
can use the @code{OLD_PASSWORD()} function, which is provided to generate
short hashes in the old format. But note that @code{OLD_PASSWORD()} may
one day no longer be supported.

If the server is running under circumstances where it generates short hashes,
@code{OLD_PASSWORD()} is available but is equivalent to @code{PASSWORD()}.

@node Password hashing 4.1.0,  , Application password use, Password hashing
@subsubsection Password Hashing in MySQL 4.1.0

Password hashing in MySQL 4.1.0 differs from hashing in 4.1.1 and up.
The 4.1.0 differences are:

@itemize @bullet

@item
Password hashes are 45 bytes long rather than 41 bytes.

@item
The @code{PASSWORD()} function is non-repeatable.  That is, with a given
argument @var{X}, successive calls to @code{PASSWORD(@var{X})} generate different
results.

@end itemize

These differences make authentication in 4.1.0 incompatible with that of
releases that follow it.  If you have upgraded to MySQL 4.1.0, it is
recommended that you upgrade to a newer version as soon as possible. After
you do, reassign any long passwords in the @code{user} table so that they are
compatible with the 41-byte format.


@node User Account Management, Disaster Prevention, Privilege system, MySQL Database Administration
@section MySQL User Account Management

This section describes how to set up accounts for clients of your MySQL
server. It discusses the following topics:

@itemize @bullet
@item
The meaning of account names and passwords as used in MySQL and how that
compares to names and passwords used by your operating system

@item
How to set up new accounts and remove existing accounts

@item
How to change passwords

@item
Guidelines for using passwords securely

@item
How to use secure connections with SSL

@end itemize

@menu
* User names::                  MySQL Usernames and Passwords
* Adding users::                Adding New User Accounts to MySQL
* Removing users::              Removing User Accounts from MySQL
* User resources::              Limiting Account Resources
* Passwords::                   Assigning Account Passwords
* Password security::           Keeping Your Password Secure
* Secure connections::          Using Secure Connections
@end menu

@node User names, Adding users, User Account Management, User Account Management
@subsection MySQL Usernames and Passwords

@cindex usernames, and passwords
@cindex passwords, for users

A MySQL account is defined in terms of a username and the client host or hosts
from which the user can connect to the server. The account also has a
password.
There are several distinctions between the way usernames and passwords are
used by MySQL and the way they are used by your operating system:

@itemize @bullet
@item
Usernames, as used by MySQL for authentication purposes, have nothing to do
with usernames (login names) as used by Windows or Unix.  On Unix, most
MySQL clients by default try to log in using the current Unix username as
the MySQL username, but that is for convenience only. The default can be
overridden easily, because client programs allow any username to be
specified with a @code{-u} or @code{--user} option. Because this means
that anyone can attempt to connect to the server using any username, you
can't make a database secure in any way unless all MySQL accounts have
passwords.  Anyone who specifies a username for an account that
has no password will be able to connect successfully to the server.

@item
MySQL usernames can be up to 16 characters long. Operating system usernames
might have a different maximum length. For example, Unix usernames typically
are limited to eight characters.

@item
MySQL passwords have nothing to do with passwords for logging in to your
operating system.  There is no necessary connection between the password
you use to log in to a Windows or Unix machine and the password you use
to access the MySQL server on that machine.

@item
MySQL encrypts passwords using its own algorithm. This encryption is
different from that used during the Unix login process.  MySQL password
encryption is the same as that implemented by the @code{PASSWORD()} SQL
function.  Unix password encryption is the same as that implemented by the
@code{ENCRYPT()} SQL function.  See the descriptions of the
@code{PASSWORD()} and @code{ENCRYPT()} functions in @ref{Encryption
functions}.  From version 4.1 on, MySQL employs a stronger authentication
method that has better password protection during the connection process
than in earlier versions. It is secure even if TCP/IP packets are sniffed or
the @code{mysql} database is captured.  (In earlier versions, even though
passwords are stored in encrypted form in the @code{user} table, knowledge
of the encrypted password value could be used to connect to the MySQL
server.)

@end itemize

When you install MySQL, the grant tables are populated with an initial set of
accounts. These accounts have names and access privileges that are described
in @ref{Default privileges}, which also discusses how to assign passwords
to them.  Thereafter, you normally set up, modify, and remove MySQL accounts
using the @code{GRANT} and @code{REVOKE} statements.
@xref{GRANT,  , @code{GRANT}}.

When you connect to a MySQL server with a command-line client, you
should specify the username and password for the account that you want to use:

@example
shell> mysql --user=monty --password=@var{guess} @var{db_name}
@end example

If you prefer short options, the command looks like this:

@example
shell> mysql -u monty -p@var{guess} @var{db_name}
@end example

There must be @emph{no space} between the @code{-p} option and the
following password value.
@xref{Connecting}.

The preceding commands include the password value on the command line, which
can be a security risk.
@xref{Password security}.
To avoid this, specify the @code{--password} or @code{-p} option without any
following password value:

@example
shell> mysql --user=monty --password @var{db_name}
shell> mysql -u monty -p @var{db_name}
@end example

Then the client program will print a prompt and wait for you to enter
the password.
(In these examples, @var{db_name} is @emph{not} interpreted as a
password, because it is separated from the preceding password option by a
space.)

On some systems, the library call that MySQL uses to prompt for a password
automatically limits the password to eight characters.  That is a problem
with the system library, not with MySQL.  Internally, MySQL doesn't have
any limit for the length of the password.  To work around the problem,
change your MySQL password to a value that is eight or fewer characters
long, or put your password in an option file.


@node Adding users, Removing users, User names, User Account Management
@subsection Adding New User Accounts to MySQL

@findex GRANT statement
@findex statements, GRANT

@cindex privileges, adding
@cindex adding, new user privileges
@cindex user privileges, adding
@cindex adding, new account privileges
@cindex account privileges, adding

You can create MySQL accounts in two ways:

@itemize @bullet
@item
By using @code{GRANT} statements
@item
By manipulating the MySQL grant tables directly
@end itemize

The preferred method is to use @code{GRANT} statements, because they are
more concise and less error-prone. @code{GRANT} is available as of MySQL
3.22.11; its syntax is described in
@ref{GRANT,  , @code{GRANT}}.

Another option for creating accounts is to use one of several available
third-party programs that offer capabilities for MySQL account
administration.  @code{phpMyAdmin} is one such program.

The following examples show how to use the @command{mysql} client program to
set up new users.  These examples assume that privileges are set up
according to the defaults described in @ref{Default privileges}.  This means
that to make changes, you must connect to the MySQL server as the MySQL
@code{root} user, and the @code{root} account must have the @code{INSERT}
privilege for the @code{mysql} database and the @code{RELOAD} administrative
privilege.

First, use the @command{mysql} program to connect to the server as the
MySQL @code{root} user:

@example
shell> mysql --user=root mysql
@end example

If you have assigned a password to the @code{root} account, you'll also
need to supply a @code{--password} or @code{-p} option for this @command{mysql}
command and also for those later in this section.

After connecting to the server as @code{root}, you can add new accounts.  The following
statements use @code{GRANT} to set up four new accounts:

@example
mysql> GRANT ALL PRIVILEGES ON *.* TO 'monty'@@'localhost'
    ->     IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
mysql> GRANT ALL PRIVILEGES ON *.* TO 'monty'@@'%'
    ->     IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
mysql> GRANT RELOAD,PROCESS ON *.* TO 'admin'@@'localhost';
mysql> GRANT USAGE ON *.* TO 'dummy'@@'localhost';
@end example

The accounts created by these @code{GRANT} statements have the
following properties:

@itemize @bullet
@item
Two of the accounts have a username of @code{monty} and a password of
@code{some_pass}. Both accounts are superuser accounts with full privileges
to do anything. One account (@code{'monty'@@'localhost'}) can be used only
when connecting from the local host. The other (@code{'monty'@@'%'}) can be
used to connect from any other host.  Note that it is necessary to have both
accounts for @code{monty} to be able to connect from anywhere as
@code{monty}.  Without the @code{localhost} account, the anonymous-user
account for @code{localhost} that is created by @command{mysql_install_db}
would take precedence when @code{monty} connects from the local host. As a
result, @code{monty} would be treated as an anonymous user.  The reason for
this is that the anonymous-user account has a more specific @code{Host}
column value than the @code{'monty'@@'%'} account and thus comes earlier in
the @code{user} table sort order.  (@code{user} table sorting is discussed
in @ref{Connection access}.)

@item
One account has a username of @code{admin} and no password.  This account
can be used only by connecting from the local host.  It is granted the
@code{RELOAD} and @code{PROCESS} administrative privileges.  These
privileges allow the @code{admin} user to execute the @command{mysqladmin
reload}, @command{mysqladmin refresh}, and @command{mysqladmin flush-@var{xxx}} commands,
as well as @command{mysqladmin processlist} .  No privileges are granted for
accessing any databases. You could add such privileges later by issuing
additional @code{GRANT} statements.

@item
One account has a username of @code{dummy} and no password.  This account
can be used only by connecting from the local host.  No privileges are
granted. The @code{USAGE} privilege in the @code{GRANT} statement allows you
to create an account without giving it any privileges. It has the effect of
setting all the global privileges to @code{'N'}.  It is assumed that you
will grant specific privileges to the account later.

@end itemize

@findex INSERT statement, grant privileges
@findex statements, INSERT

As an alternative to @code{GRANT}, you can create the same accounts
directly by issuing @code{INSERT} statements and then telling
the server to reload the grant tables:

@example
shell> mysql --user=root mysql
mysql> INSERT INTO user
    ->     VALUES('localhost','monty',PASSWORD('some_pass'),
    ->     'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO user
    ->     VALUES('%','monty',PASSWORD('some_pass'),
    ->     'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO user SET Host='localhost',User='admin',
    ->     Reload_priv='Y', Process_priv='Y';
mysql> INSERT INTO user (Host,User,Password)
    ->     VALUES('localhost','dummy','');
mysql> FLUSH PRIVILEGES;
@end example

The reason for using @code{FLUSH PRIVILEGES} when you create accounts with
@code{INSERT} is to tell the server to re-read the grant tables.
Otherwise, the changes will go unnoticed until you restart the server. With
@code{GRANT}, @code{FLUSH PRIVILEGES} is unnecessary.

The reason for using the @code{PASSWORD()} function with @code{INSERT} is to
encrypt the password. The @code{GRANT} statement encrypts the password for
you, so @code{PASSWORD()} is unnecessary.

The @code{'Y'} values enable privileges for the accounts.  Depending on your
MySQL version, you may have to use a different number of @code{'Y'} values
in the first two @code{INSERT} statements. (Versions prior to 3.22.11 have
fewer privilege columns, and versions from 4.0.2 on have more.)  For the
@code{admin} account, the more readable extended @code{INSERT} syntax using
@code{SET} that is available starting with MySQL 3.22.11 is used.

In the @code{INSERT} statement for the @code{dummy} account, only the
@code{Host}, @code{User}, and @code{Password} columns in the @code{user}
table record are assigned values. None of the privilege columns are set
explicitly, so MySQL assigns them all the default value of @code{'N'}.
This is equivalent to what @code{GRANT USAGE} does.

Note that to set up a superuser account, it is necessary only to create a
@code{user} table entry with the privilege columns set to @code{'Y'}.
@code{user} table privileges are global, so no entries in any of the other
grant tables are needed.

The next examples create three accounts and give them access to specific
databases. Each of them has a username of @code{custom} and password of
@code{obscure}.

To create the accounts with @code{GRANT}, use the following statements:

@example
shell> mysql --user=root mysql
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    ->     ON bankaccount.*
    ->     TO 'custom'@@'localhost'
    ->     IDENTIFIED BY 'obscure';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    ->     ON expenses.*
    ->     TO 'custom'@@'whitehouse.gov'
    ->     IDENTIFIED BY 'obscure';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    ->     ON customer.*
    ->     TO 'custom'@@'server.domain'
    ->     IDENTIFIED BY 'obscure';
@end example

The three accounts can be used as follows:

@itemize @bullet
@item
The first account can
access the @code{bankaccount} database, but only from the local host.
@item
The second account can access
the @code{expenses} database, but only from the host @code{whitehouse.gov}.
@item
The third account can access
the @code{customer} database, but only from the host @code{server.domain}.
@end itemize

To set up the @code{custom} accounts without @code{GRANT}, use @code{INSERT}
statements as follows to modify the grant tables directly:

@example
shell> mysql --user=root mysql
mysql> INSERT INTO user (Host,User,Password)
    ->     VALUES('localhost','custom',PASSWORD('obscure'));
mysql> INSERT INTO user (Host,User,Password)
    ->     VALUES('whitehouse.gov','custom',PASSWORD('obscure'));
mysql> INSERT INTO user (Host,User,Password)
    ->     VALUES('server.domain','custom',PASSWORD('obscure'));
mysql> INSERT INTO db
    ->     (Host,Db,User,Select_priv,Insert_priv,
    ->     Update_priv,Delete_priv,Create_priv,Drop_priv)
    ->     VALUES('localhost','bankaccount','custom',
    ->     'Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO db
    ->     (Host,Db,User,Select_priv,Insert_priv,
    ->     Update_priv,Delete_priv,Create_priv,Drop_priv)
    ->     VALUES('whitehouse.gov','expenses','custom',
    ->     'Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO db
    ->     (Host,Db,User,Select_priv,Insert_priv,
    ->     Update_priv,Delete_priv,Create_priv,Drop_priv)
    ->     VALUES('server.domain','customer','custom',
    ->     'Y','Y','Y','Y','Y','Y');
mysql> FLUSH PRIVILEGES;
@end example

The first three @code{INSERT} statements add @code{user} table entries that
allow the user @code{custom} to connect from the various hosts with the given
password, but grant no global privileges (all privileges are set to the
default value of @code{'N'}).  The next three @code{INSERT} statements add
@code{db} table entries that grant privileges to @code{custom} for the
@code{bankaccount}, @code{expenses}, and @code{customer} databases, but only
when accessed from the proper hosts.  As usual when you modify the grant
tables directly, you tell the server to reload them with
@code{FLUSH PRIVILEGES} so that the privilege changes take effect.

If you want to give a specific user access from all machines in a given
domain (for example, @code{mydomain.com}), you can issue a @code{GRANT}
statement that uses the @samp{%} wildcard character in the host part of the
account name:

@example
mysql> GRANT ...
    ->     ON *.*
    ->     TO 'myname'@@'%.mydomain.com'
    ->     IDENTIFIED BY 'mypass';
@end example

To do the same thing by modifying the grant tables directly, do this:

@example
mysql> INSERT INTO user (Host,User,Password,...)
    ->     VALUES('%.mydomain.com','myname',PASSWORD('mypass'),...);
mysql> FLUSH PRIVILEGES;
@end example


@node Removing users, User resources, Adding users, User Account Management
@subsection Removing User Accounts from MySQL

@cindex privileges, deleting
@cindex privileges, dropping
@cindex dropping, user
@cindex user privileges, dropping
@cindex deleting, user
@cindex user privileges, deleting
@cindex deleting, users
@cindex users, deleting

To remove an account, use the @code{DROP USER} statement, which was added in
MySQL 4.1.1.  For older versions of MySQL, use @code{DELETE} instead.
The account removal procedure is described in @ref{DROP USER}.


@node User resources, Passwords, Removing users, User Account Management
@subsection Limiting Account Resources

Before MySQL 4.0.2, the only available method for limiting use of MySQL
server resources is to set the @code{max_user_connections} system
variable to a non-zero value. But that method is strictly global.  It does
not allow for management of individual accounts. Also, it limits only the
number of simultaneous connections made using a single account, not
what a client can do once connected. Both types of control are
interest to many MySQL administrators, particularly those for Internet
Service Providers.

Starting from MySQL 4.0.2, you can limit the following server resources for
individual accounts:

@itemize @bullet
@item
The number of queries that an account can issue per hour
@item
The number of updates that an account can issue per hour
@item
The number of times an account can connect to the server per hour
@end itemize

Any statement that a client can issue counts against the query limit.
Only statements that modify databases or tables count against the update
limit.

An account in this context is a single record in the @code{user} table. Each
account is uniquely identified by its @code{User} and @code{Host} column
values.

As a prerequisite for using this feature, the @code{user} table in the
@code{mysql} database must contain the resource-related columns.  Resource
limits are stored in the @code{max_questions}, @code{max_updates}, and
@code{max_connections} columns.  If your @code{user} table doesn't have
these columns, it must be upgraded; see @ref{Upgrading-grant-tables}.

To set resource limits with a @code{GRANT} statement, use a @code{WITH}
clause that names each resource to be limited and a per-hour count
indicating the limit value.  For example, to create a new account that can
access the @code{customer} database, but only in a limited fashion, issue
this statement:

@example
mysql> GRANT ALL ON customer.* TO 'francis'@@'localhost'
    ->     IDENTIFIED BY 'frank'
    ->     WITH MAX_QUERIES_PER_HOUR 20
    ->          MAX_UPDATES_PER_HOUR 10
    ->          MAX_CONNECTIONS_PER_HOUR 5;
@end example

The limit types need not all be named in the @code{WITH} clause, but those
named can be present in any order. The value for each limit should be an
integer representing a count per hour. If the @code{GRANT} statement has no
@code{WITH} clause, the limits are each set to the default value of zero
(that is, no limit).

To set or change limits for an existing account, use a @code{GRANT USAGE}
statement at the global level (@code{ON *.*}). The following statement
changes the query limit for @code{francis} to 100:

@example
mysql> GRANT USAGE ON *.* TO 'francis'@@'localhost'
    ->     WITH MAX_QUERIES_PER_HOUR 100;
@end example

This statement leaves the account's existing privileges unchanged and
modifies only the limit values specified.

To remove an existing limit, set its value to zero. For example, to remove the
limit on how many times per hour @code{francis} can connect, use this
statement:

@example
mysql> GRANT USAGE ON *.* TO 'francis'@@'localhost'
    ->     WITH MAX_CONNECTIONS_PER_HOUR 0;
@end example

Resource-use counting takes place when any account has a non-zero limit
placed on its use of any of the resources.

As the server runs, it counts the number of times each account uses
resources.  If an account reaches its limit on number of connections within
the last hour, further connections for the account are rejected until that
hour is up. Similarly, if the account reaches its limit on the number of
queries or updates, further queries or updates are rejected until the hour
is up. In all such cases, an appropriate error message is issued.

Resource counting is done per account, not per client. For example, if your
account has a query limit of 50, you cannot increase your limit to 100 by
making two simultaneous client connections to the server.  Queries issued on
both connections are counted together.

The current resource-use counts can be reset globally for all accounts, or
individually for a given count:

@itemize @bullet
@item
To reset the current counts to zero for all accounts, issue a @code{FLUSH
USER_RESOURCES} statement. The counts also can be reset by reloading the
grant tables (for example, with a @code{FLUSH PRIVILEGES} statement or a
@command{mysqladmin reload} command).
@item
The counts for an individual account can be set to zero by re-granting
it any of its limits. To do this, use @code{GRANT USAGE} as described earlier
and specify a limit value equal to the value that the account
already has.

@end itemize

@node Passwords, Password security, User resources, User Account Management
@subsection Assigning Account Passwords

@findex PASSWORD()
@findex SET PASSWORD statement

@cindex passwords, setting
@cindex setting, passwords

Passwords may be assigned from the command line by using the @command{mysqladmin}
command:

@example
shell> mysqladmin -u @var{user_name} -h @var{host_name} password "@var{newpwd}"
@end example

The account for which this command resets the password is the one with a
@code{user} table record that matches @var{user_name} in the @code{User}
column and the client host @emph{from which you connect} in the
@code{Host} column.

Another way to assign a password to an account is to issue a @code{SET
PASSWORD} statement:

@example
mysql> SET PASSWORD FOR 'jeffrey'@@'%' = PASSWORD('biscuit');
@end example

Only users such as @code{root} with update access to the @code{mysql}
database can change the password for other users.  If you are not connected
as an anonymous user, you can change your own password by omitting the
@code{FOR} clause:

@example
mysql> SET PASSWORD = PASSWORD('biscuit');
@end example

You can also use a @code{GRANT USAGE} statement at the global level
(@code{ON *.*}) to assign a password to an account without affecting the
account's current privileges:

@example
mysql> GRANT USAGE ON *.* TO 'jeffrey'@@'%' IDENTIFIED BY 'biscuit';
@end example

Although it is generally preferable to assign passwords using one of the
preceding methods, you can also do so by modifying the @code{user} table
directly:

@itemize @bullet
@item
To establish a password when creating a new account, provide a
value for the @code{Password} column:

@example
shell> mysql -u root mysql
mysql> INSERT INTO user (Host,User,Password)
    -> VALUES('%','jeffrey',PASSWORD('biscuit'));
mysql> FLUSH PRIVILEGES;
@end example

@item
To change the password for an existing account, use @code{UPDATE} to set the
@code{Password} column value:

@example
shell> mysql -u root mysql
mysql> UPDATE user SET Password = PASSWORD('bagel')
    -> WHERE Host = '%' AND User = 'francis';
mysql> FLUSH PRIVILEGES;
@end example

@end itemize

When you assign an account a password using @code{SET PASSWORD},
@code{INSERT}, or @code{UPDATE}, you must use the @code{PASSWORD()} function
to encrypt it.  (The only exception is that you need not use
@code{PASSWORD()} if the password is empty.) @code{PASSWORD()} is
necessary because the @code{user} table stores passwords in encrypted form,
not as plaintext.  If you forget that fact, you are likely to set passwords
like this:

@example
shell> mysql -u root mysql
mysql> INSERT INTO user (Host,User,Password)
    -> VALUES('%','jeffrey','biscuit');
mysql> FLUSH PRIVILEGES;
@end example

@c Unnecessarily complex for the explanation below, but it may be useful
@c at some point to include this elsewhere:

@c When the user @code{jeffrey} attempts to connect to the server using this
@c password, the @command{mysql} client encrypts it with @code{PASSWORD()},
@c generates an authentication vector based on @strong{encrypted} password
@c and a random number, obtained from server, and sends the result to
@c the server.

The result is that the literal value @code{'biscuit'} is stored as the
password in the @code{user} table, not the encrypted value.  When
@code{jeffrey} attempts to connect to the server using this password, the
value is encrypted and compared to the value stored in the @code{user}
table.  However, the stored value is the literal string @code{'biscuit'}, so
the comparison fails and the server rejects the connection:

@example
shell> mysql -u jeffrey -pbiscuit test
Access denied
@end example

If you set passwords using the @code{GRANT ... IDENTIFIED BY} statement or
the @command{mysqladmin password} command, they both take care of encrypting
the password for you.  The @code{PASSWORD()} function is unnecessary.

@strong{Note}: @code{PASSWORD()} encryption is different from Unix password
encryption.
@xref{User names}.


@node Password security, Secure connections, Passwords, User Account Management
@subsection Keeping Your Password Secure

@c TODO: Perhaps most of this should be in Using MySQL Programs? Other than
@c the first item, it seems primarily applicable to running clients, not
@c to administering the server.  If it gets moved, be sure to retarget xrefs
@c that now point here.

On an administrative level, you should never grant access to the
@code{mysql.user} table to any non-administrative accounts. Passwords in the
@code{user} table are stored in encrypted form, but in versions of MySQL
earlier than 4.1, knowing the encrypted password for an account makes it
possible to connect to the server using that account.

When you run a client program to connect to the MySQL server, it is
inadvisable to specify your password in a way that exposes it to discovery
by other users.  The methods you can use to specify your password when you
run client programs are listed here, along with an assessment of the risks
of each method:

@itemize @bullet
@item
@findex -p option
@findex --password option
Use a @code{-p@var{your_pass}} or @code{--password=@var{your_pass}} option on the command
line.  For example:

@example
shell> mysql -u francis -pfrank @var{db_name}
@end example

This is convenient but insecure, because your password becomes visible to
system status programs such as @command{ps} that may be invoked by other users
to display command lines.  MySQL clients typically overwrite the
command-line password argument with zeros during their initialization
sequence, but there is still a brief interval during which the value is
visible.

@item
Use a @code{-p} or @code{--password} option with no password value
specified.  In this case, the client program solicits the password from
the terminal:

@example
shell> mysql -u francis -p @var{db_name}
Enter password: ********
@end example

The @samp{*} characters indicate where you enter your password. The password
is not displayed as you enter it.

It is more secure to enter your password this way than to specify it on the
command line because it is not visible to other users.  However, this method
of entering a password is suitable only for programs that you run
interactively.  If you want to invoke a client from a script that runs
non-interactively, there is no opportunity to enter the password from the
terminal. On some systems, you may even find that the first line of your
script is read and interpreted (incorrectly) as your password!

@item
@tindex .my.cnf file
Store your password in an option file.  For example, on Unix you can list your
password in the @code{[client]} section of the @file{.my.cnf} file in your
home directory:

@example
[client]
password=your_pass
@end example

If you store your password in @file{.my.cnf}, the file should not be
accessible to anyone but yourself. To ensure this, set the file access mode to
@code{400} or @code{600}. For example:

@example
shell> chmod 600 .my.cnf
@end example

@ref{Option files} discusses option files in more detail.

@item
Store your password in the @code{MYSQL_PWD} environment variable.
This method of specifying your MySQL password must be considered
extremely insecure and should not be used.  Some versions of @command{ps}
include an option to display the environment of running processes. If you
set @code{MYSQL_PWD}, your password will be exposed to any other user who
runs @command{ps}.  Even on systems without such a version of @command{ps}, it is
unwise to assume that there are no other methods by which users can examine
process environments.
@xref{Environment variables}.

@end itemize

All in all, the safest methods are to have the client program prompt for the
password or to specify the password in a properly protected option file.

@node Secure connections,  , Password security, User Account Management
@subsection Using Secure Connections

@cindex OpenSSL
@cindex SSL and X509 Basics

Beginning with version 4.0.0, MySQL has support for secure (encrypted)
connections between MySQL clients and the server using the Secure Sockets
Layer (SSL) protocol.  This section discusses how to use SSL connections.
It also describes a way to set up SSH on Windows.

The standard configuration of MySQL is intended to be as fast as possible,
so encrypted connections are not used by default.  Doing so would make the
client/server protocol much slower.  Encrypting data is a CPU-intensive
operation that requires the computer to do additional work and can delay
other MySQL tasks.  For applications that require the security provided by
encrypted connections, the extra computation is warranted.

MySQL allows encryption to be enabled on a per-connection basis. You can
choose a normal unencrypted connection or a secure encrypted SSL connection
according the requirements of individual applications.

@menu
* Secure basics::               Basic SSL Concepts
* Secure requirements::         Requirements
* Secure create certs::         Setting Up SSL Certificates for MySQL
* Secure GRANT::                SSL @code{GRANT} Options
* SSL options::                 SSL Command-Line Options
* Windows and SSH::             Connecting to MySQL Remotely from Windows with SSH
@end menu

@node Secure basics, Secure requirements, Secure connections, Secure connections
@subsubsection Basic SSL Concepts

To understand how MySQL
uses SSL, it's necessary to explain some basic SSL and X509 concepts. People
who are already familiar with them can skip this part.

By default, MySQL uses unencrypted connections between the client and the
server. This means that someone with access to the network could watch all
your traffic and look at the data being sent or received.  They could even
change the data while it is in transit between client and server. To improve
security a little, you can compress client/server traffic by using the
@code{--compress} option when invoking client programs.  However, this will
not foil a determined attacker.

@cindex What is encryption
When you need to move information over a network in a secure fashion,
an unencrypted connection is unacceptable.  Encryption is the way to make
any kind of data unreadable. In fact, today's practice requires many
additional security elements from encryption algorithms.  They should resist
many kind of known attacks such as changing the order of encrypted messages
or replaying data twice.

SSL is a protocol that uses different encryption algorithms to ensure that
data received over a public network can be trusted. It has mechanisms to
detect any data change, loss, or replay. SSL also incorporates algorithms
that provide identity verification using the X509 standard.

@cindex What is an X509/Certificate?
X509 makes it possible to identify someone on the Internet.  It is most
commonly used in e-commerce applications. In basic terms, there should be
some company called a ``Certificate Authority'' (or CA) that assigns electronic
certificates to anyone who needs them. Certificates rely on asymmetric
encryption algorithms that have two encryption keys (a public key and a
secret key). A certificate owner can show the certificate to another party
as proof of identity. A certificate consists of its owner's public key. Any
data encrypted with this public key can be decrypted only using the
corresponding secret key, which is held by the owner of the certificate.

If you need more information about SSL, X509, or encryption, use your
favorite Internet search engine to search for keywords in which you are
interested.

@node Secure requirements, Secure create certs, Secure basics, Secure connections
@subsubsection Requirements

To use SSL connections between the MySQL server and client programs, your
system must be able to support OpenSSL and your version of MySQL must be
4.0.0 or newer.

To get secure connections to work with MySQL, you must do the following:

@enumerate
@item
Install the OpenSSL library. We have tested MySQL with OpenSSL 0.9.6.
If you need OpenSSL, visit @uref{http://www.openssl.org}.
@item
When you configure MySQL, run the @command{configure} script with the
@code{--with-vio} and @code{--with-openssl} options.
@item
Make sure that you have upgraded your grant tables to include the SSL-related
columns in the @code{mysql.user} table.
This is necessary if your grant tables date from a version prior to MySQL
4.0.0.  The upgrade procedure is described in @ref{Upgrading-grant-tables}.
@item
To check whether a running @command{mysqld} server supports OpenSSL,
examine the value of the @code{have_openssl} system variable:

@example
mysql> SHOW VARIABLES LIKE 'have_openssl';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_openssl  | YES   |
+---------------+-------+
@end example

If the value is @code{YES}, the server supports OpenSSL connections.
@end enumerate


@node Secure create certs, Secure GRANT, Secure requirements, Secure connections
@subsubsection Setting Up SSL Certificates for MySQL

Here is an example for setting up SSL certificates for MySQL:

@example
DIR=`pwd`/openssl
PRIV=$DIR/private

mkdir $DIR $PRIV $DIR/newcerts
cp /usr/share/ssl/openssl.cnf $DIR
replace ./demoCA $DIR -- $DIR/openssl.cnf

# Create necessary files: $database, $serial and $new_certs_dir 
# directory (optional)

touch $DIR/index.txt
echo "01" > $DIR/serial

#
# Generation of Certificate Authority(CA)
#

openssl req -new -x509 -keyout $PRIV/cakey.pem -out $DIR/cacert.pem \
    -config $DIR/openssl.cnf

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# ................++++++
# .........++++++
# writing new private key to '/home/monty/openssl/private/cakey.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be
# incorporated into your certificate request.
# What you are about to enter is what is called a Distinguished Name
# or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL admin
# Email Address []:

#
# Create server request and key
#
openssl req -new -keyout $DIR/server-key.pem -out \
    $DIR/server-req.pem -days 3600 -config $DIR/openssl.cnf

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# ..++++++
# ..........++++++
# writing new private key to '/home/monty/openssl/server-key.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be
# incorporated into your certificate request.
# What you are about to enter is what is called a Distinguished Name
# or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL server
# Email Address []:
# 
# Please enter the following 'extra' attributes
# to be sent with your certificate request
# A challenge password []:
# An optional company name []:

#
# Remove the passphrase from the key (optional)
#

openssl rsa -in $DIR/server-key.pem -out $DIR/server-key.pem

#
# Sign server cert
#
openssl ca  -policy policy_anything -out $DIR/server-cert.pem \
    -config $DIR/openssl.cnf -infiles $DIR/server-req.pem

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Enter PEM pass phrase:
# Check that the request matches the signature
# Signature ok
# The Subjects Distinguished Name is as follows
# countryName           :PRINTABLE:'FI'
# organizationName      :PRINTABLE:'MySQL AB'
# commonName            :PRINTABLE:'MySQL admin'
# Certificate is to be certified until Sep 13 14:22:46 2003 GMT
# (365 days)
# Sign the certificate? [y/n]:y
# 
# 
# 1 out of 1 certificate requests certified, commit? [y/n]y
# Write out database with 1 new entries
# Data Base Updated

#
# Create client request and key
#
openssl req -new -keyout $DIR/client-key.pem -out \
    $DIR/client-req.pem -days 3600 -config $DIR/openssl.cnf

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# .....................................++++++
# .............................................++++++
# writing new private key to '/home/monty/openssl/client-key.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be
# incorporated into your certificate request.
# What you are about to enter is what is called a Distinguished Name
# or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL user
# Email Address []:
# 
# Please enter the following 'extra' attributes
# to be sent with your certificate request
# A challenge password []:
# An optional company name []:

#
# Remove a passphrase from the key (optional)
#
openssl rsa -in $DIR/client-key.pem -out $DIR/client-key.pem

#
# Sign client cert
#

openssl ca  -policy policy_anything -out $DIR/client-cert.pem \
    -config $DIR/openssl.cnf -infiles $DIR/client-req.pem

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Enter PEM pass phrase:
# Check that the request matches the signature
# Signature ok
# The Subjects Distinguished Name is as follows
# countryName           :PRINTABLE:'FI'
# organizationName      :PRINTABLE:'MySQL AB'
# commonName            :PRINTABLE:'MySQL user'
# Certificate is to be certified until Sep 13 16:45:17 2003 GMT
# (365 days)
# Sign the certificate? [y/n]:y
# 
# 
# 1 out of 1 certificate requests certified, commit? [y/n]y
# Write out database with 1 new entries
# Data Base Updated

#
# Create a my.cnf file that you can use to test the certificates
#

cnf=""
cnf="$cnf [client]"
cnf="$cnf ssl-ca=$DIR/cacert.pem"
cnf="$cnf ssl-cert=$DIR/client-cert.pem"
cnf="$cnf ssl-key=$DIR/client-key.pem"
cnf="$cnf [mysqld]"
cnf="$cnf ssl-ca=$DIR/cacert.pem"
cnf="$cnf ssl-cert=$DIR/server-cert.pem"
cnf="$cnf ssl-key=$DIR/server-key.pem"
echo $cnf | replace " " '
' > $DIR/my.cnf
@end example

To test SSL connections, start the server as follows, where @code{$DIR} is the
pathname to the directory where the sample @file{my.cnf} option file is
located:

@example
shell> mysqld --defaults-file=$DIR/my.cnf &
@end example

Then invoke a client program using the same option file:

@example
shell> mysql --defaults-file=$DIR/my.cnf
@end example

If you have a MySQL source distribution, you can also test your setup by
modifying the preceding @file{my.cnf} file to refer to the demonstration
certificate and key files in the @file{SSL} directory of the distribution.


@node Secure GRANT, SSL options, Secure create certs, Secure connections
@subsubsection SSL @code{GRANT} Options

@cindex SSL related options
@findex REQUIRE GRANT option
@findex GRANT statement

MySQL can check X509 certificate attributes in addition to the usual
authentication that is based on the username and password.  To specify
SSL-related options for a MySQL account, use the @code{REQUIRE} clause of
the @code{GRANT} statement.
@xref{GRANT,  , @code{GRANT}}.

There are different possibilities for limiting connection types for an account:

@itemize @bullet
@item
If an account has no SSL or X509 requirements, unencrypted connections are
allowed if the username and password are valid. However, encrypted
connections also can be used at the client's option, if the client has the
proper certificate and key files.

@item
@code{REQUIRE SSL} option limits the server to allow only SSL
encrypted connections for the account. Note that this option can be omitted
if there are any ACL records that allow non-SSL connections.

@example
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@@'localhost'
    -> IDENTIFIED BY 'goodsecret' REQUIRE SSL;
@end example

@item
@code{REQUIRE X509} means that the client must have a valid certificate
but that the exact certificate, issuer, and subject do not matter.
The only requirement is that it should be possible to verify its
signature with one of the CA certificates.

@example
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@@'localhost'
    -> IDENTIFIED BY 'goodsecret' REQUIRE X509;
@end example

@item
@code{REQUIRE ISSUER 'issuer'} places the restriction on connection attempts
that the client must present a valid X509 certificate issued by CA
@code{'issuer'}.  If the client presents a certificate that is valid but has
a different issuer, the server rejects the connection.  Use of X509
certificates always implies encryption, so the @code{SSL} option is
unneccessary.

@c TODO: isn't preceding sentence also true for X509, SUBJECT, and CIPHER?

@example
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@@'localhost'
    -> IDENTIFIED BY 'goodsecret'
    -> REQUIRE ISSUER '/C=FI/ST=Some-State/L=Helsinki/
       O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@@example.com';
@end example

Note that the @code{ISSUER} value should be entered as a single string.

@item
@code{REQUIRE SUBJECT 'subject'} places the restriction on connection
attempts that the client must present a valid X509 certificate with subject
@code{'subject'} on it.  If the client presents a certificate that is valid
but has a different subject, the server rejects the connection.

@example
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@@'localhost'
    -> IDENTIFIED BY 'goodsecret'
    -> REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/
       O=MySQL demo client certificate/
       CN=Tonu Samuel/Email=tonu@@example.com';
@end example

Note that the @code{SUBJECT} value should be entered as a single string.

@item
@code{REQUIRE CIPHER 'cipher'} is needed to ensure that strong enough ciphers
and key lengths will be used. SSL itself can be weak if old algorithms
with short encryption keys are used. Using this option, we can ask for
some exact cipher method to allow a connection.

@example
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@@'localhost'
    -> IDENTIFIED BY 'goodsecret'
    -> REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA';
@end example

@end itemize

The @code{SUBJECT}, @code{ISSUER}, and @code{CIPHER} options can be
combined in the @code{REQUIRE} clause like this:

@example
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@@'localhost'
    -> IDENTIFIED BY 'goodsecret'
    -> REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/
       O=MySQL demo client certificate/
       CN=Tonu Samuel/Email=tonu@@example.com'
    -> AND ISSUER '/C=FI/ST=Some-State/L=Helsinki/
       O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@@example.com'
    -> AND CIPHER 'EDH-RSA-DES-CBC3-SHA';
@end example

Note that the @code{SUBJECT} and @code{ISSUER} values each should be entered
as a single string.

Starting from MySQL 4.0.4, the @code{AND} keyword is optional between
@code{REQUIRE} options.

The order of the options does not matter, but no option can be specified
twice.


@node SSL options, Windows and SSH, Secure GRANT, Secure connections
@subsubsection SSL Command-Line Options

@cindex SSL command-line options

The following list describes options that are used for specifying the
use of SSL, certificate files, and key files.
These options are available beginning with MySQL 4.0. They may
be given on the command line or in an option file.

@table @code

@item --ssl
For the server, this option specifies that the server allows SSL connections.
For a client program, it allows the client to connect to the server using SSL.
This option is not sufficient in itself to cause an SSL connection to be used.
You must also specify the
@code{--ssl-ca}, @code{--ssl-cert}, and @code{--ssl-key} options.

This option is more often used in its opposite form to indicate that SSL
should @emph{not} be used. To do this, specify the option as
@code{--skip-ssl} or @code{--ssl=0}.

Note that use of @code{--ssl} doesn't @emph{require} an SSL connection.
For example, if the server or client is compiled without SSL support,
a normal unencrypted connection will be used.

The secure way to ensure that an SSL connection will be used is
to create an account on the server that includes a
@code{REQUIRE SSL} clause in the @code{GRANT} statement.
Then use this account to connect to the server, with both a server and client
that have SSL support enabled.

@item --ssl-ca=@var{file_name}
The path to a file with a list of trusted SSL CAs.

@item --ssl-capath=@var{directory_name}
The path to a directory that contains trusted 
SSL CA certificates in pem format.

@item --ssl-cert=@var{file_name}
The name of the SSL certificate file to use
for establishing a secure connection.

@item --ssl-cipher=@var{cipher_list}
A list of allowable ciphers to use for SSL encryption.
@var{cipher_list} has the same format as the @code{openssl ciphers}
command.

Example: @code{--ssl-cipher=ALL:-AES:-EXP}

@item --ssl-key=@var{file_name}
The name of the SSL key file to use
for establishing a secure connection.

@end table


@node Windows and SSH,  , SSL options, Secure connections
@subsubsection Connecting to MySQL Remotely from Windows with SSH

@c WHEN THE WEB TEAM MOVES MY (MIKE HILLYER) MYSQL AND SSH ARTICLE
@c TO DEV.MYSQL.COM WE COULD POINT TO IT INSTEAD
@c http://www.vbmysql.com/articles/security/sshtunnel.html
@c
@cindex SSH
@cindex connecting, remotely with SSH

Here is a note about how to connect to get a secure connection to remote
MySQL server with SSH (by David Carlson @email{dcarlson@@mplcomm.com}):

@enumerate
@item
@c URLs last verified: 2003-11-15
Install an SSH client on your Windows machine.  As a user, the best non-free
one I've found is from @code{SecureCRT} from @uref{http://www.vandyke.com/}.
Another option is @code{f-secure} from @uref{http://www.f-secure.com/}. You
can also find some free ones on @code{Google} at
@uref{http://directory.google.com/Top/Computers/Security/Products_and_Tools/Cryptography/SSH/Clients/Windows/}.

@item
Start your Windows SSH client.
Set @code{Host_Name = yourmysqlserver_URL_or_IP}.
Set @code{userid=your_userid} to log in to your server. This @code{userid}
value may not be the same as the username of your MySQL account.

@item
Set up port forwarding. Either do a remote forward (Set @code{local_port: 3306}, @code{remote_host: yourmysqlservername_or_ip}, @code{remote_port: 3306} )
or a local forward (Set @code{port: 3306},  @code{host: localhost}, @code{remote port: 3306}).

@item
Save everything, otherwise you'll have to redo it the next time.

@item
Log in to your server with the SSH session you just created.

@item
On your Windows machine, start some ODBC application (such as Access).

@item
Create a new file in Windows and link to MySQL using the ODBC
driver the same way you normally do, except type in @code{localhost}
for the MySQL host server, not @code{yourmysqlservername}.
@end enumerate

You should now have an ODBC connection to MySQL, encrypted using SSH.


@node Disaster Prevention, Localisation, User Account Management, MySQL Database Administration
@section Disaster Prevention and Recovery

@c TODO: a lot of the information here assumes MyISAM implicitly and won't
@c necessarily work for other storage engines.

@c help_category Recovery

This section discusses how to make database backups (full and incremental)
and how to perform
table maintenance.  The syntax of the SQL statements described here is
given in @ref{Database Administration}.
Much of the information here pertains primarily to @code{MyISAM} tables.
@code{InnoDB} backup procedures are given in @ref{Backing up}.

@menu
* Backup::                      Database Backups
* Table maintenance::           Table Maintenance and Crash Recovery
* Maintenance schedule::        Setting Up a Table Maintenance Schedule
* Table-info::                  Getting Information About a Table
@end menu


@node Backup, Table maintenance, Disaster Prevention, Disaster Prevention
@subsection Database Backups

@cindex databases, backups
@cindex backups

Because MySQL tables are stored as files, it is easy to do a
backup. To get a consistent backup, do a @code{LOCK TABLES} on the
relevant tables, followed by @code{FLUSH TABLES} for the tables.
See @ref{LOCK TABLES, , @code{LOCK TABLES}} and
@ref{FLUSH, , @code{FLUSH}}.
You need only a read lock; this allows other clients to continue to
query the tables while you are making a copy of the files in the
database directory.  The @code{FLUSH TABLES} statement is needed to ensure that
the all active index pages are written to disk before you start the backup.


If you want to make an SQL-level backup of a table, you can use
@code{SELECT INTO ... OUTFILE} or @code{BACKUP TABLE}.
For @code{SELECT INTO ... OUTFILE}, the output file cannot already exist.
For @code{BACKUP TABLE}, the same is true as of
MySQL 3.23.56 and 4.0.12, because this would be a security risk.
See @ref{SELECT,  , @code{SELECT}} and
@ref{BACKUP TABLE,  , @code{BACKUP TABLE}}.

Another way to back up a database is to use the @command{mysqldump} program or
the @command{mysqlhotcopy script}.
See @ref{mysqldump, , @command{mysqldump}} and
@ref{mysqlhotcopy, , @command{mysqlhotcopy}}.

@enumerate
@item
Do a full backup of your database:

@example
shell> mysqldump --tab=@var{/path/to/some/dir} --opt @var{db_name}
@end example

Or:

@example
shell> mysqlhotcopy @var{db_name} @var{/path/to/some/dir}
@end example

You can also simply copy all table files (@file{*.frm}, @file{*.MYD}, and
@file{*.MYI} files) as long as the server isn't updating anything.
The @command{mysqlhotcopy} script uses this method.  (But note that these
methods
will not work if your database contains @code{InnoDB} tables.  @code{InnoDB}
does not store table contents in database directories, and @command{mysqlhotcopy}
works only for @code{MyISAM} and @code{ISAM} tables.)

@item
@cindex log files, names
Stop @command{mysqld} if it's running, then start it with the
@code{--log-bin[=file_name]} option.  @xref{Binary log}. The binary
log files provide you with the information you need to replicate
changes to the database that are made subsequent to the point at which
you executed @command{mysqldump}.
@end enumerate

For @code{InnoDB} tables, it's possible to perform an online backup that
takes no locks on tables; see @ref{mysqldump, , @command{mysqldump}}

MySQL supports incremental backups: You need to start the server with the
@code{--log-bin} option to enable binary logging; see @ref{Binary log}.
At the moment you want to make an incremental backup (containing all
changes that happened since the last full or incremental backup), you should
rotate the binary log by using @code{FLUSH LOGS}. This done, you need to
copy to the backup location all binary logs which range from the one of the
moment of the last full or incremental backup to the last but one. These
binary logs are the incremental backup; at restore time, you apply them
as explained further below. The next time you do a full backup, you should
also rotate the binary log using @code{FLUSH LOGS}, @code{mysqldump
--flush-logs}, or @code{mysqlhotcopy --flushlogs}. See @ref{mysqldump, ,
@command{mysqldump}} and @ref{mysqlhotcopy, , @command{mysqlhotcopy}}.

If your MySQL server is a slave replication server, then regardless of the
backup method you choose, you should also back up the
@file{master.info} and @file{relay-log.info} files
when you back up your slave's data. These files
are always needed to resume replication after you restore
the slave's data. If your slave is subject to replicating @code{LOAD
DATA INFILE} commands, you should also back up any @file{SQL_LOAD-*} files
that may exist in the directory specified by the @code{--slave-load-tmpdir}
option. (This location defaults to the value of the @code{tmpdir} variable
if not specified.) The slave needs these files to resume
replication of any interrupted @code{LOAD DATA INFILE} operations. 

If you have to restore @code{MyISAM} tables, try to recover them using
@code{REPAIR TABLE} or @command{myisamchk -r} first.  That should work in
99.9% of all cases.  If @command{myisamchk} fails, try the following procedure.
Note that it will work only if you have enabled binary logging by starting
MySQL with the @code{--log-bin} option; see @ref{Binary log}.

@enumerate
@item
Restore the original @command{mysqldump} backup, or binary backup.
@item
Execute the following command to re-run the updates in the binary logs:

@example
shell> mysqlbinlog hostname-bin.[0-9]* | mysql
@end example

In your case, you may want to re-run only certain binary logs, from
certain positions (usually you want to re-run all binary logs from the
date of the restored backup, excepting possibly some incorrect queries).
See @ref{mysqlbinlog,  , @command{mysqlbinlog}} for more information on
the @command{mysqlbinlog} utility and how to use it.

If you are using the update logs instead (which is a deprecated feature removed
in MySQL 5.0), you can process their contents like this:

@example
shell> ls -1 -t -r hostname.[0-9]* | xargs cat | mysql
@end example

@code{ls} is used to sort the update log filenames into the right order.

@end enumerate

You can also do selective backups of individual files:

@itemize @bullet
@item
To dump the table, use
@code{SELECT * INTO OUTFILE '@var{file_name}' FROM @var{tbl_name}}.

@item
To reload the table, use and restore with
@code{LOAD DATA INFILE 'file_name' REPLACE ...}
To avoid duplicate records, the table must have a @code{PRIMARY KEY} or a
@code{UNIQUE} index. The @code{REPLACE} keyword causes old records
to be replaced with new ones when a new record duplicates an old record on
a unique key value.

@end itemize

If you have performance problems with your server while making backups, one
strategy that can help is to set up replication and perform backups on the
slave rather than on the master.
@xref{Replication Intro}.

If you are using a Veritas filesystem, you can make a backup like this:

@enumerate
@item
From a client program, execute @code{FLUSH TABLES WITH READ LOCK}.

@item
From another shell, execute @code{mount vxfs snapshot}.

@item
From the first client, execute @code{UNLOCK TABLES}.

@item
Copy files from the snapshot.

@item
Unmount the snapshot.
@end enumerate


@node Table maintenance, Maintenance schedule, Backup, Disaster Prevention
@subsection Table Maintenance and Crash Recovery

The following text discusses how to use @command{myisamchk} to check or repair
@code{MyISAM} tables (tables with @file{.MYI} and @file{.MYD} files).
The same concepts apply to using @command{isamchk} to check or repair
@code{ISAM} tables (tables with @file{.ISM} and @file{.ISD} files).
@xref{Storage engines}.

You can use the @command{myisamchk} utility to get information about your
database tables or to check, repair, or optimize them.  The following
sections describe how to invoke @command{myisamchk} (including a
description of its options), how to set up a table maintenance schedule,
and how to use @command{myisamchk} to perform its various functions.

Even though table repair with @command{myisamchk} is quite secure, it's
always a good idea to make a backup @emph{before} doing a repair (or any
maintenance operation that could make a lot of changes to a table)

@command{myisamchk} operations that affect indexes can cause
@code{FULLTEXT} indexes to be rebuilt with full-text parameters that
are incompatible with the values used by the MySQL server. To avoid this,
read the instructions in
@ref{myisamchk general options,  , @command{myisamchk} general options}.

In many cases, you may find it simpler to do @code{MyISAM} table maintenance
using the SQL statements that perform operations that @command{myisamchk} can
do:

@itemize @bullet
@item
To check or repair @code{MyISAM} tables, use @code{CHECK TABLE} or
@code{REPAIR TABLE}.

@item
To optimize @code{MyISAM} tables, use @code{OPTIMIZE TABLE}.

@item
To analyze @code{MyISAM} tables, use @code{ANALYZE TABLE}.

@end itemize

These statements were introduced in different versions, but all are available
from MySQL 3.23.14 on.
See
@ref{ANALYZE TABLE,  , @code{ANALYZE TABLE}},
@ref{CHECK TABLE,  , @code{CHECK TABLE}},
@ref{OPTIMIZE TABLE, , @code{OPTIMIZE TABLE}},
and @ref{REPAIR TABLE,  , @code{REPAIR TABLE}}.
The statements can be used directly, or by means of the @command{mysqlcheck}
client program, which provides a command-line interface to them.

One advantage of these statements over @command{myisamchk} is that the server
does all the work. With @command{myisamchk}, you must make sure that the server
does not use the tables at the same time. Otherwise, there can be unwanted
interaction betweeen @command{myisamchk} and the server.


@menu
* myisamchk syntax::            @command{myisamchk} Invocation Syntax
* myisamchk general options::   General Options for @command{myisamchk}
* myisamchk check options::     Check Options for @command{myisamchk}
* myisamchk repair options::    Repair Options for @command{myisamchk}
* myisamchk other options::     Other Options for @command{myisamchk}
* myisamchk memory::            @command{myisamchk} Memory Usage
* Crash recovery::              Using @command{myisamchk} for Crash Recovery
* Check::                       How to Check @code{MyISAM} Tables for Errors
* Repair::                      How to Repair Tables
* Optimization::                Table Optimization
@end menu


@node myisamchk syntax, myisamchk general options, Table maintenance, Table maintenance
@subsubsection @command{myisamchk} Invocation Syntax

Invoke @command{myisamchk} like this:

@example
shell> myisamchk [@var{options}] @var{tbl_name}
@end example

The @var{options} specify what you want @command{myisamchk} to do.  They are
described in the following sections.  You can also get a list of options by
invoking @command{myisamchk --help}.

With no options, @command{myisamchk} simply checks your table as the default
operation.  To get more information or to tell @command{myisamchk} to take
corrective action, specify options as described in the following discussion.

@var{tbl_name} is the database table you want to check or repair.  If you run
@command{myisamchk} somewhere other than in the database directory, you must
specify the path to the database directory, because @command{myisamchk} has no
idea where the
database is located.  In fact, @command{myisamchk} doesn't actually care whether
the files you are working on are located in a database directory. You can
copy the files that correspond to a database table into some other location and
perform recovery operations on them there.

You can name several tables on the @command{myisamchk} command line if you
wish.  You can also specify a table by naming its index file (the file with
the @file{.MYI} suffix). This allows you to specify all tables in a
directory by using the pattern @file{*.MYI}.  For example, if you are in a
database directory, you can check all the @code{MyISAM} tables in that
directory like this:

@example
shell> myisamchk *.MYI
@end example

If you are not in the database directory, you can check all the tables there
by specifying the path to the directory:

@example
shell> myisamchk /path/to/database_dir/*.MYI
@end example

You can even check all tables in all databases by specifying a wildcard
with the path to the MySQL data directory:

@example
shell> myisamchk /path/to/datadir/*/*.MYI
@end example

The recommended way to quickly check all @code{MyISAM} and @code{ISAM}
tables is:

@example
shell> myisamchk --silent --fast /path/to/datadir/*/*.MYI
shell> isamchk --silent /path/to/datadir/*/*.ISM
@end example

If you want to check all @code{MyISAM} and @code{ISAM} tables and repair any
that are corrupted, you can use the following commands:

@example
shell> myisamchk --silent --force --fast --update-state \
          -O key_buffer=64M -O sort_buffer=64M \
          -O read_buffer=1M -O write_buffer=1M \
          /path/to/datadir/*/*.MYI
shell> isamchk --silent --force -O key_buffer=64M \
          -O sort_buffer=64M -O read_buffer=1M -O write_buffer=1M \
          /path/to/datadir/*/*.ISM
@end example

These commands assume that you have more than 64MB free.
For more information about memory allocation with @command{myisamchk}, see
@ref{myisamchk memory}.

You must ensure that no other program is using the tables while you are
running @command{myisamchk}.  Otherwise, when you run @command{myisamchk}, it may
display the following error message:

@example
warning: clients are using or haven't closed the table properly
@end example

This means that you are trying to check a table that has been updated by
another program (such as the @command{mysqld} server) that hasn't yet closed
the file or that has died without closing the file properly.

If @command{mysqld} is running, you must force it to flush any table
modifications that are still buffered in memory by using @code{FLUSH
TABLES}. You should then ensure that no one is using the tables while you
are running @command{myisamchk}.  The easiest way to
avoid this problem is to use @code{CHECK TABLE} instead of @command{myisamchk}
to check tables.

@node myisamchk general options, myisamchk check options, myisamchk syntax, Table maintenance
@subsubsection General Options for @command{myisamchk}

@cindex options, @command{myisamchk}
@cindex @command{myisamchk}, options

The options described in this section can be used for any
type of table maintenance operation performed by @command{myisamchk}.
The sections following this one describe options that pertain only to specific
operations, such as table checking or repairing.

@table @code

@item --help, -?
Display a help message and exit.

@item --debug=@var{debug_options}, -# @var{debug_options}
Write a debugging log. The @var{debug_options} string often is
@code{'d:t:o,@var{file_name}'}.

@item --silent, -s
Silent mode.  Write output only when errors occur. You can use @code{-s}
twice (@code{-ss}) to make @command{myisamchk} very silent.

@item --verbose, -v
Verbose mode.  Print more information. This can be used with @code{-d} and
@code{-e}. Use @code{-v} multiple times (@code{-vv}, @code{-vvv}) for even
more output.

@item --version, -V
Display version information and exit.

@item --wait, -w
Instead of terminating with an error if the table is locked, wait until the
table is unlocked before continuing.  Note that if you are running
@command{mysqld} with the @code{--skip-external-locking} option, the table can
be locked only by another @command{myisamchk} command.

@end table

You can also set the following variables by using @code{--@var{var_name}=@var{value}}
options:

@cindex @code{decode_bits} @command{myisamchk} variable
@cindex @code{ft_max_word_len} @command{myisamchk} variable
@cindex @code{ft_min_word_len} @command{myisamchk} variable
@cindex @code{ft_stopword_file} @command{myisamchk} variable
@cindex @code{key_buffer_size} @command{myisamchk} variable
@cindex @code{myisam_block_size} @command{myisamchk} variable
@cindex @code{read_buffer_size} @command{myisamchk} variable
@cindex @code{sort_buffer_size} @command{myisamchk} variable
@cindex @code{sort_key_blocks} @command{myisamchk} variable
@cindex @code{write_buffer_size} @command{myisamchk} variable

@multitable @columnfractions .35 .35
@item @strong{Variable} @tab @strong{Default Value}
@item @code{decode_bits} @tab 9
@item @code{ft_max_word_len} @tab version-dependent
@item @code{ft_min_word_len} @tab 4
@item @code{ft_stopword_file} @tab built-in list
@item @code{key_buffer_size} @tab 523264
@item @code{myisam_block_size} @tab 1024
@item @code{read_buffer_size} @tab 262136
@item @code{sort_buffer_size} @tab 2097144
@item @code{sort_key_blocks} @tab 16
@item @code{write_buffer_size} @tab 262136
@end multitable

It is also possible to set variables by using
@code{--set-variable=@var{var_name}=@var{value}} or @code{-O @var{var_name}=@var{value}}
syntax. However, this syntax is deprecated as of MySQL 4.0.

The possible @command{myisamchk} variables and their default values
can be examined with @command{myisamchk --help}:

@code{sort_buffer_size} is used when the keys are repaired by sorting
keys, which is the normal case when you use @code{--recover}.

@code{key_buffer_size} is used when you are checking the table with
@code{--extend-check} or when the keys are repaired by inserting keys
row by row into the table (like when doing normal inserts). Repairing
through the key buffer is used in the following cases:

@itemize @bullet

@item
You use @code{--safe-recover}.

@item
The temporary files needed to sort the keys would be more than twice as
big as when creating the key file directly.  This is often the case when you
have large key values for  @code{CHAR}, @code{VARCHAR}, or @code{TEXT}
columns, because the sort operation needs to store the complete key values
as it proceeds. If you have lots of temporary space and you can force
@command{myisamchk} to repair by sorting, you can use the @code{--sort-recover}
option.

@end itemize

Repairing through the key buffer takes much less disk space than using
sorting, but is also much slower.

If you want a faster repair, set the @code{key_buffer_size} and
@code{sort_buffer_size} variables to about 25% of your available memory.
You can set both variables to large values, because only one of them is used
at a time.

@code{myisam_block_size} is the size used for index blocks. It is available
as of MySQL 4.0.0.

The @code{ft_min_word_len} and @code{ft_max_word_len} variables are
available as of MySQL 4.0.0.  @code{ft_stopword_file} is available as of
MySQL 4.0.19.

@code{ft_min_word_len} and @code{ft_max_word_len} indicate the minimum and
maximum word length for @code{FULLTEXT} indexes. @code{ft_stopword_file}
names the stopword file. These need to be set under the following
circumstances.

If you use @command{myisamchk} to perform an operation that modifies
table indexes (such as repair or analyze), the @code{FULLTEXT} indexes
are rebuilt using the default full-text parameter values for minimum and
maximum word length and the stopword file unless you specify otherwise.
This can result in queries failing.

The problem occurs because these parameters are known only by the server.
They are not stored in @code{MyISAM} index files.  To avoid the problem if
you have modified the minimum or maximum word length or the stopword file in
the server, specify the same @code{ft_min_word_len}, @code{ft_max_word_len},
and @code{ft_stopword_file} values to @command{myisamchk} that you use for
@command{mysqld}. For example, if you have set the minimum word length to 3,
you can repair a table with @command{myisamchk} like this:

@example
shell> myisamchk --recover --ft_min_word_len=3 @var{tbl_name}.MYI
@end example

To ensure that @command{myisamchk} and the server use the same values for
full-text parameters, you can place each one in both the @code{[mysqld]}
and @code{[myisamchk]} sections of an option file:

@example
[mysqld]
ft_min_word_len=3

[myisamchk]
ft_min_word_len=3
@end example

An alternative to using @command{myisamchk} is to use the @code{REPAIR TABLE},
@code{ANALYZE TABLE}, @code{OPTIMIZE TABLE}, or @code{ALTER TABLE}.
These statements are performed by the server, which knows the proper
full-text parameter values to use.


@node myisamchk check options, myisamchk repair options, myisamchk general options, Table maintenance
@subsubsection Check Options for @command{myisamchk}

@cindex check options, myisamchk
@cindex tables, checking

@command{myisamchk} supports the following options for table checking operations:

@table @code

@item --check, -c
Check the table for errors. This is the default operation if you specify no
option that selects an operation type explicitly.

@item --check-only-changed, -C
Check only tables that have changed since the last check.

@item --extend-check, -e
Check the table very thoroughly. This is quite slow if the table has many
indexes.  This option should only be used in extreme cases.  Normally,
@command{myisamchk} or @command{myisamchk --medium-check} should
be able to determine whether there are any errors in the table.

If you are using @code{--extend-check} and have plenty of memory, setting
the @code{key_buffer_size} variable to a large value will help the repair
operation run faster.

@item --fast, -F
Check only tables that haven't been closed properly.

@item --force, -f
Do a repair operation automatically if
@command{myisamchk} finds any errors in the table.
The repair type is the same as that specified with the @code{--repair} or
@code{-r} option.

@item --information, -i
Print informational statistics about the table that is checked.

@item --medium-check, -m
Do a check that is faster than an @code{--extend-check} operation.
This finds only 99.99% of all errors, which should be good enough in most cases.

@item --read-only, -T
Don't mark the table as checked. This is useful if you use @command{myisamchk}
to check a table that is in use by some other application that doesn't
use locking, such as @command{mysqld} when run with the
@code{--skip-external-locking} option.

@item --update-state, -U
Store information in the @file{.MYI} file to indicate when the table was
checked and whether the table crashed.  This should be used to get full benefit of the
@code{--check-only-changed} option, but you shouldn't use this
option if the @command{mysqld} server is using the table and you are
running it with the @code{--skip-external-locking} option.

@end table


@node myisamchk repair options, myisamchk other options, myisamchk check options, Table maintenance
@subsubsection Repair Options for @command{myisamchk}

@cindex repair options, myisamchk
@cindex files, repairing

@command{myisamchk} supports the following options for table repair operations:

@table @code
@item --backup, -B
Make a backup of the @file{.MYD} file as @file{file_name-time.BAK}

@item --character-sets-dir=@var{path}
The directory where character sets are installed.  @xref{Character sets}.

@item --correct-checksum
Correct the checksum information for the table.

@item --data-file-length=@var{#}, -D @var{#}
Maximum length of the data file (when re-creating data file when it's ``full'').

@item --extend-check, -e
Do a repair that tries to
to recover every possible row from the data file.
Normally this will also find a lot of garbage rows. Don't use this option
unless you are totally desperate.

@item --force, -f
Overwrite old temporary files (files with names like @file{@var{tbl_name}.TMD})
instead of aborting.

@item --keys-used=@var{#}, -k @var{#}
For @command{myisamchk}, the option value indicates which indexes to update.
Each binary bit of the option value corresponds to a table index, where the
first index is bit 0.
For @command{isamchk}, the option value indicates that only the first @var{#} of
the table indexes should be updated.
In either case, an option value of 0 disables updates to all indexes, which
can be used to get faster inserts.
Deactivated indexes can be reactivated by using @command{myisamchk -r}
or (@command{isamchk -r}).

@item --no-symlinks, -l
Do not follow symbolic links. Normally @command{myisamchk} repairs the
table that a symlink points to.  This option doesn't exist as of MySQL 4.0,
because versions from 4.0 on will not remove symlinks during repair operations.

@item --parallel-recover, -p
Uses the same technique as @code{-r} and @code{-n}, but creates
all the keys in parallel, using different threads.
This option was added in MySQL 4.0.2.
@emph{This is alpha code. Use at your own risk!}

@item --quick, -q
Achieve a faster repair by not modifying the data file. You can specify this
option twice to force @command{myisamchk} to modify the original data file in
case of duplicate keys.

@item --recover, -r
Do a repair that can fix almost any problem except unique keys that aren't
unique (which is an extremely unlikely error with @code{ISAM}/@code{MyISAM}
tables).  If you want to recover a table, this is the option to try
first. You should try @code{-o} only if @command{myisamchk} reports that the
table can't be recovered by @code{-r}.  (In the unlikely case
that @code{-r} fails, the data file is still intact.)

If you have lots of memory, you should increase the value of
@code{sort_buffer_size}.

@item --safe-recover, -o
Do a repair using
an old recovery method that reads through all rows in order and updates
all index trees based on the rows found.  This is an order of magnitude
slower than @code{-r}, but can handle a couple of very unlikely cases that
@code{-r} cannot.  This recovery method also uses much less disk
space than @code{-r}. Normally, you should repair first with
@code{-r}, and then with @code{-o} only if @code{-r} fails.

If you have lots of memory, you should increase the value of
@code{key_buffer_size}.

@item --set-character-set=@var{name}
Change the character set used by the table indexes.

@item --sort-recover, -n
Force @command{myisamchk} to use sorting to resolve the keys even if the
temporary files should be very big.

@item --tmpdir=@var{path}, -t @var{path}
Path of the directory to be used for storing temporary files. If this is not
set, @command{myisamchk} uses the value of the @code{TMPDIR} environment variable.
Starting from MySQL 4.1, @code{tmpdir} can be set to a list of directory paths
that will be used successively in round-robin fashion for creating
temporary files. The separator character between directory names should be
colon (@samp{:}) on Unix and semicolon (@samp{;}) on Windows, NetWare, and
OS/2.

@item --unpack, -u
Unpack a table that was packed with @command{myisampack}.
@end table


@node myisamchk other options, myisamchk memory, myisamchk repair options, Table maintenance
@subsubsection Other Options for @command{myisamchk}

@command{myisamchk} supports the following options for actions other than
table checks and repairs:

@table @code
@item --analyze, -a
Analyze the distribution of keys. This improves join performance by enabling
the join optimizer to better choose the order in which to join the tables
and which keys it should use. To obtain information about the distribution,
use a @command{myisamchk --description --verbose @var{tbl_name}} command or the
@code{SHOW KEYS FROM @var{tbl_name}} statement.

@item --description, -d
Print some descriptive information about the table.

@item --set-auto-increment[=@var{value}], -A[@var{value}]
Force @code{AUTO_INCREMENT} numbering for new records to start at the given
value (or higher, if there are already records with @code{AUTO_INCREMENT}
values this large). If @var{value} is not specified, @code{AUTO_INCREMENT}
number for new records begins with the largest value currently in the table,
plus one.

@item --sort-index, -S
Sort the index tree blocks in high-low order.
This optimizes seeks and makes table scanning by key faster.

@item --sort-records=@var{#}, -R @var{#}
Sort records according to a particular index.  This makes your data much
more localized and may speed up range-based @code{SELECT} and @code{ORDER
BY} operations that use this index. (The first time you use this option to
sort a table, it may be very slow.) To determine a table's index numbers,
use @code{SHOW KEYS}, which displays a table's indexes in the same order
that @command{myisamchk} sees them.  Indexes are numbered beginning with 1.

@end table


@node myisamchk memory, Crash recovery, myisamchk other options, Table maintenance
@subsubsection @command{myisamchk} Memory Usage

@cindex memory usage, myisamchk

Memory allocation is important when you run @command{myisamchk}.
@command{myisamchk} uses no more memory than you specify with the @code{-O}
options.  If you are going to use @command{myisamchk} on very large tables,
you should first decide how much memory you want it to use.  The default
is to use only about 3MB to perform repairs.  By using larger values, you can
get @command{myisamchk} to operate faster.  For example, if you have more
than 32MB RAM, you could use options such as these (in addition to any
other options you might specify):

@example
shell> myisamchk -O sort=16M -O key=16M -O read=1M -O write=1M ...
@end example

Using @code{-O sort=16M} should probably be enough for most cases.

Be aware that @command{myisamchk} uses temporary files in @code{TMPDIR}. If
@code{TMPDIR} points to a memory filesystem, you may easily get out of
memory errors. If this happens, set @code{TMPDIR} to point at some directory
located on a filesystem
with more space and run @command{myisamchk} again.

When repairing, @command{myisamchk} will also need a lot of disk space:

@itemize @bullet
@item
Double the size of the data file (the original one and a copy).  This
space is not needed if you do a repair with @code{--quick}; in this
case, only the index file is re-created.  This space is needed on the same
filesystem as the original data file! (The copy is created in the
same directory as the original.)

@item
Space for the new index file that replaces the old one. The old index file
is truncated at the start of the repair operation, so you usually ignore
this space.  This space is needed on the same filesystem as the original
index file!

@item
When using @code{--recover} or @code{--sort-recover}
(but not when using @code{--safe-recover}), you will need space for a
sort buffer. The amount of space required is:

@example
(@var{largest_key} + @var{row_pointer_length}) * @var{number_of_rows} * 2
@end example

You can check the length of the keys and the @code{row_pointer_length}
with @command{myisamchk -dv @var{tbl_name}}.  This space is allocated in the temporary
directory (specified by @code{TMPDIR} or @code{--tmpdir=@var{path}}).

@end itemize

If you have a problem with disk space during repair, you can try to use
@code{--safe-recover} instead of @code{--recover}.


@node Crash recovery, Check, myisamchk memory, Table maintenance
@subsubsection Using @command{myisamchk} for Crash Recovery

@cindex crash, recovery
@cindex recovery, from crash

If you run @command{mysqld} with @code{--skip-external-locking} (which is the
default on some systems, such as Linux), you can't reliably use @command{myisamchk}
to check a table when @command{mysqld} is using the same table.  If you
can be sure that no one is accessing the tables through @command{mysqld}
while you run @command{myisamchk}, you only have to do @command{mysqladmin
flush-tables} before you start checking the tables.  If you can't
guarantee this, then you must stop @command{mysqld} while you
check the tables.  If you run @command{myisamchk} while @command{mysqld} is updating
the tables, you may get a warning that a table is corrupt even when it
isn't.

If you are not using @code{--skip-external-locking}, you can use
@command{myisamchk} to check tables at any time.  While you do this, all clients
that try to update the table will wait until @command{myisamchk} is ready before
continuing.

If you use @command{myisamchk} to repair or optimize tables, you
@emph{must} always ensure that the @command{mysqld} server is not using
the table (this also applies if you are using @code{--skip-external-locking}).
If you don't take down @command{mysqld}, you should at least do a
@command{mysqladmin flush-tables} before you run @command{myisamchk}.
Your tables @emph{may become corrupted} if the server and @command{myisamchk}
access the tables simultaneously.

This section describes how to check for and deal with data corruption
in MySQL databases.  If your tables get corrupted frequently you should
try to find the reason why.
@xref{Crashing}.

The @code{MyISAM} table section contains reason for why a table could be
corrupted. @xref{MyISAM table problems,  , @code{MyISAM} table problems}.

When performing crash recovery, it is important to understand that each
@code{MyISAM} table @var{tbl_name} in a database corresponds to three files
in the database directory:

@multitable @columnfractions .20 .40
@item @strong{File} @tab @strong{Purpose}
@item @file{@var{tbl_name}.frm} @tab Definition (format) file
@item @file{@var{tbl_name}.MYD} @tab Data file
@item @file{@var{tbl_name}.MYI} @tab Index file
@end multitable

Each of these three file types is subject to corruption in various ways, but
problems occur most often in data files and index files.

@command{myisamchk} works by creating a copy of the @file{.MYD} data file
row by row. It ends the repair stage by removing the old @file{.MYD}
file and renaming the new file to the original file name.  If you use
@code{--quick}, @command{myisamchk} does not create a temporary @file{.MYD}
file, but instead assumes that the @file{.MYD} file is correct and only
generates a new index file without touching the @file{.MYD} file. This is
safe, because @command{myisamchk} automatically detects whether the @file{.MYD}
file is corrupt and aborts the repair if it is.  You can also specify
the @code{--quick} option twice to @command{myisamchk}.  In this case,
@command{myisamchk} does not abort on some errors (such as duplicate-key
errors) but instead tries to resolve them by modifying the @file{.MYD}
file. Normally the use of two @code{--quick} options is useful only if you
have too little free disk space to perform a normal repair.  In this case,
you should at least make a backup before running @command{myisamchk}.


@node Check, Repair, Crash recovery, Table maintenance
@subsubsection How to Check @code{MyISAM} Tables for Errors

@cindex checking, tables for errors
@cindex tables, error checking
@cindex errors, checking tables for

To check a @code{MyISAM} table, use the following commands:

@table @code
@item myisamchk @var{tbl_name}
This finds 99.99% of all errors. What it can't find is corruption that
involves @emph{only} the data file (which is very unusual). If you want
to check a table, you should normally run @command{myisamchk} without options or
with either the @code{-s} or @code{--silent} option.

@item myisamchk -m @var{tbl_name}
This finds 99.999% of all errors. It first checks all index entries for
errors and then reads through all rows. It calculates a checksum for
all keys in the rows and verifies that the checksum matches the checksum
for the keys in the index tree.

@item myisamchk -e @var{tbl_name}
This does a complete and thorough check of all data (@code{-e} means
``extended check''). It does a check-read of every key for each row to verify
that they indeed point to the correct row.  This may take a long time for a
large table that has many indexes.  Normally, @command{myisamchk} stops after
the first error it finds. If you want to obtain more information, you can
add the @code{--verbose} (@code{-v}) option.  This causes @command{myisamchk}
to keep going, up through a maximum of 20 errors.

@item myisamchk -e -i @var{tbl_name}
Like the previous command, but the @code{-i} option tells @command{myisamchk} to
print some informational statistics, too.

@end table

In most cases, a simple @command{myisamchk} with no arguments other than the
table name is sufficient to check a table.


@node Repair, Optimization, Check, Table maintenance
@subsubsection How to Repair Tables

@cindex tables, repairing
@cindex repairing, tables

The discussion in this section describes how to use @command{myisamchk} on
@code{MyISAM} tables (extensions @file{.MYI} and @file{.MYD}).  If you
are using @code{ISAM} tables (extensions @file{.ISM} and @file{.ISD}),
you should use @command{isamchk} instead; the concepts are similar.

If you are using MySQL 3.23.16 and above, you can (and
should) use the @code{CHECK TABLE} and @code{REPAIR TABLE} statements to
check and repair @code{MyISAM} tables.
See @ref{CHECK TABLE,  , @code{CHECK TABLE}}
and @ref{REPAIR TABLE,  , @code{REPAIR TABLE}}.

The symptoms of a corrupted table include queries that abort unexpectedly
and observable errors such as these:

@itemize @bullet
@item
@file{@var{tbl_name}.frm} is locked against change
@item
Can't find file @file{@var{tbl_name}.MYI} (Errcode: @var{###})
@item
Unexpected end of file
@item
Record file is crashed
@item
Got error @var{###} from table handler
@end itemize

To get more information about the error you can run @command{perror} @var{###},
where @var{###} is the error number. The following example shows how to use
@command{perror} to find the meanings for the most common error numbers that
indicate a problem with a table:

@example
shell> perror 126 127 132 134 135 136 141 144 145
126 = Index file is crashed / Wrong file format
127 = Record-file is crashed
132 = Old database file
134 = Record was already deleted (or record file crashed)
135 = No more room in record file
136 = No more room in index file
141 = Duplicate unique key or constraint on write or update
144 = Table is crashed and last repair failed
145 = Table was marked as crashed and should be repaired
@end example

Note that error 135 (no more room in record file) and error 136 (no more
room in index file) are not errors that can be fixed by a simple repair. In
this case, you have to use @code{ALTER TABLE} to increase the
@code{MAX_ROWS} and @code{AVG_ROW_LENGTH} table option values:

@example
ALTER TABLE @var{tbl_name} MAX_ROWS=@var{xxx} AVG_ROW_LENGTH=@var{yyy};
@end example

If you don't know the current table option values, use @code{SHOW CREATE TABLE
tbl_name}.

For the other errors, you must repair your tables. @command{myisamchk} can
usually detect and fix most problems that occur.

The repair process involves up to four stages, described here. Before you
begin, you should change location to the database directory and check the
permissions of the table files. On Unix, make sure that they are readable by
the user that @command{mysqld} runs as (and to you, because you need to access
the files you are checking).  If it turns out you need to modify files, they
must also be writable by you.

The options that you can use for table maintenance with @command{myisamchk}
and @command{isamchk} are described in several of the earlier subsections of
@ref{Table maintenance}.

The following section is for the cases where the above command fails or
if you want to use the extended features that @command{myisamchk} and
@command{isamchk} provide.

If you are going to repair a table from the command line, you must first
stop the @command{mysqld} server. Note that when you do
@command{mysqladmin shutdown} on a remote server, the @command{mysqld} server
will still be alive for a while after @command{mysqladmin} returns, until
all queries are stopped and all keys have been flushed to disk.

@noindent
@strong{Stage 1: Checking your tables}

Run @command{myisamchk *.MYI} or @command{myisamchk -e *.MYI} if you have
more time.  Use the @code{-s} (silent) option to suppress unnecessary
information.

If the @command{mysqld} server is down, you should use the @code{--update-state}
option to tell @command{myisamchk} to mark the table as 'checked'.

You have to repair only those tables for which @command{myisamchk} announces an
error.  For such tables, proceed to Stage 2.

If you get weird errors when checking (such as @code{out of
memory} errors), or if @command{myisamchk} crashes, go to Stage 3.

@noindent
@strong{Stage 2: Easy safe repair}

Note: If you want a repair operation to go much faster, you should set the
values of the @code{sort_buffer_size} and @code{key_buffer_size} variables
each to about 25% of your available memory when running @command{myisamchk}
or @command{isamchk}.

First, try @command{myisamchk -r -q @var{tbl_name}} (@code{-r -q} means ``quick
recovery mode''). This will attempt to repair the index file without
touching the data file.  If the data file contains everything that it
should and the delete links point at the correct locations within the
data file, this should work, and the table is fixed. Start repairing the
next table.  Otherwise, use the following procedure:

@enumerate
@item
Make a backup of the data file before continuing.

@item
Use @command{myisamchk -r @var{tbl_name}} (@code{-r} means ``recovery mode''). This will
remove incorrect records and deleted records from the data file and
reconstruct the index file.

@item
If the preceding step fails, use @command{myisamchk --safe-recover @var{tbl_name}}.
Safe recovery mode uses an old recovery method that handles a few cases that
regular recovery mode doesn't (but is slower).
@end enumerate

If you get weird errors when repairing (such as @code{out of
memory} errors), or if @command{myisamchk} crashes, go to Stage 3.

@noindent
@strong{Stage 3: Difficult repair}

You should reach this stage only if the first 16KB block in the index file is
destroyed or contains incorrect information, or if the index file is
missing.  In this case, it's necessary to create a new index file. Do so as
follows:

@enumerate
@item
Move the data file to some safe place.

@item
Use the table description file to create new (empty) data and index files:

@example
shell> mysql @var{db_name}
mysql> SET AUTOCOMMIT=1;
mysql> TRUNCATE TABLE @var{tbl_name};
mysql> quit
@end example

If your version of MySQL doesn't have @code{TRUNCATE TABLE}, use
@code{DELETE FROM @var{tbl_name}} instead.

@item
Copy the old data file back onto the newly created data file.
(Don't just move the old file back onto the new file; you want to retain
a copy in case something goes wrong.)
@end enumerate

Go back to Stage 2.  @command{myisamchk -r -q} should work now.  (This shouldn't
be an endless loop.)

As of MySQL 4.0.2, you can also use @code{REPAIR TABLE @var{tbl_name} USE_FRM},
which performs the whole procedure automatically.

@noindent
@strong{Stage 4: Very difficult repair}

You should reach this stage only if the @file{.frm} description file has also
crashed. That should never happen, because the description file isn't changed
after the table is created:

@enumerate
@item
Restore the description file from a backup and go back to Stage 3.  You can
also restore the index file and go back to Stage 2.  In the latter case, you
should start with @command{myisamchk -r}.

@item
If you don't have a backup but know exactly how the table was created,
create a copy of the table in another database.  Remove the new data file,
then move the @file{.frm} description and @file{.MYI} index files from the
other database to your crashed database.  This gives you new description
and index files, but leaves the @file{.MYD} data file alone.  Go back to
Stage 2 and attempt to reconstruct the index file.

@end enumerate


@node Optimization,  , Repair, Table maintenance
@subsubsection Table Optimization

@cindex tables, optimizing
@cindex optimizing, tables

To coalesce fragmented records and eliminate wasted space resulting from
deleting or updating records, run @command{myisamchk} in recovery mode:

@example
shell> myisamchk -r @var{tbl_name}
@end example

You can optimize a table in the same way by using the SQL @code{OPTIMIZE TABLE}
statement.  @code{OPTIMIZE TABLE} does a repair of the table and a key
analysis, and also sorts the index tree to give faster key lookups.
There is also no possibility of unwanted interaction between a utility
and the server, because the server does all the work when you use
@code{OPTIMIZE TABLE}. @xref{OPTIMIZE TABLE,  , @code{OPTIMIZE TABLE}}.

@command{myisamchk} also has a number of other options you can use to improve
the performance of a table:

@itemize @bullet
@item @code{-S}, @code{--sort-index}
@item @code{-R @var{index_num}}, @code{--sort-records=@var{index_num}}
@item @code{-a}, @code{--analyze}
@end itemize

For a full description of the options, see @ref{myisamchk syntax}.


@node Maintenance schedule, Table-info, Table maintenance, Disaster Prevention
@subsection Setting Up a Table Maintenance Schedule

@cindex maintaining, tables
@cindex tables, maintenance regimen

It is a good idea to perform table checks on a regular basis rather than
waiting for problems to occur.
One way to check and repair @code{MyISAM} tables is
with the @code{CHECK TABLE} and @code{REPAIR TABLE} statements.
These are available starting with MySQL 3.23.16.
See @ref{CHECK TABLE,  , @code{CHECK TABLE}} and
@ref{REPAIR TABLE,  , @code{REPAIR TABLE}}.

Another way to check tables is to use @command{myisamchk}.  For maintenance
purposes, you can use @command{myisamchk -s}.  The @code{-s} option (short for
@code{--silent}) causes @command{myisamchk} to run in silent mode, printing
messages only when errors occur.

@tindex .pid (process ID) file
It's also a good idea to check tables when the server starts.
For example, whenever the machine has done a restart in the middle of an
update, you usually need to check all the tables that could have been
affected. (These are ``expected crashed tables.'')
To check @code{MyISAM} tables automatically, start the server with the @code{--myisam-recover} option, available as of MySQL 3.23.25.
If your server is too old to support this option, you could
add a test to
@command{mysqld_safe} that runs @command{myisamchk} to check all tables that have
been modified during the last 24 hours if there is an old @file{.pid}
(process ID) file left after a restart.  (The @file{.pid} file is created by
@command{mysqld} when it starts and removed when it terminates normally.  The
presence of a @file{.pid} file at system startup time indicates that
@command{mysqld} terminated abnormally.)

An even better test would be to check any table whose last-modified time
is more recent than that of the @file{.pid} file.

You should also check your tables regularly during normal system
operation.  At MySQL AB, we run a @command{cron} job to check all
our important tables once a week, using a line like this in a @file{crontab}
file:

@example
35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI
@end example

This prints out information about crashed tables so that we can examine and
repair them when needed.

Because we haven't had any unexpectedly crashed tables (tables that become
corrupted for reasons other than hardware trouble)
for a couple of years now (this is really true), once a week is
more than enough for us.

We recommend that to start with, you execute @command{myisamchk -s} each
night on all tables that have been updated during the last 24 hours,
until you come to trust MySQL as much as we do.

@cindex tables, defragment
Normally, MySQL tables need little maintenance.  If you are changing
@code{MyISAM} tables with dynamic-sized rows (tables with @code{VARCHAR},
@code{BLOB}, or @code{TEXT} columns) or have tables with many deleted rows
you may want to defragment/reclaim space from the tables
from time to time (once a month?).

You can do this by using @code{OPTIMIZE TABLE} on the tables in question.
Or, if you can stop the @command{mysqld} server for a while, change location
into the data directory and use this command while the server is stopped:

@example
shell> myisamchk -r -s --sort-index -O sort_buffer_size=16M */*.MYI
@end example

For @code{ISAM} tables, the command is similar:

@example
shell> isamchk -r -s --sort-index -O sort_buffer_size=16M */*.ISM
@end example


@node Table-info,  , Maintenance schedule, Disaster Prevention
@subsection Getting Information About a Table

@cindex tables, information

To obtain a description of a table or statistics about it, use the commands shown
here. We explain some of the information in more detail later:

@itemize @bullet
@item @command{myisamchk -d @var{tbl_name}}

Runs @command{myisamchk} in ``describe mode'' to produce a description of
your table. If you start the MySQL server using the
@code{--skip-external-locking} option, @command{myisamchk} may report an error
for a table that is updated while it runs.  However, because @command{myisamchk}
doesn't change the table in describe mode, there is no risk of
destroying data.

@item @command{myisamchk -d -v @var{tbl_name}}

Adding @code{-v} runs @command{myisamchk} in verbose mode so that it produces
more information about what it is doing.

@item @command{myisamchk -eis @var{tbl_name}}

Shows only the most important information from a table. This operation is slow
because it must read the entire table.

@item @command{myisamchk -eiv @var{tbl_name}}

This is like @code{-eis}, but tells you what is being done.

@end itemize

@cindex examples, @command{myisamchk} output
@cindex @command{myisamchk}, example output

Sample output for some of these commands follows. They are based on a table
with these data and index file sizes:

@example
-rw-rw-r--   1 monty    tcx     317235748 Jan 12 17:30 company.MYD
-rw-rw-r--   1 davida   tcx      96482304 Jan 12 18:35 company.MYM
@end example

Example of @command{myisamchk -d} output:

@example
MyISAM file:     company.MYI
Record format:   Fixed length
Data records:    1403698  Deleted blocks:         0
Recordlength:    226

table description:
Key Start Len Index   Type
1   2     8   unique  double
2   15    10  multip. text packed stripped
3   219   8   multip. double
4   63    10  multip. text packed stripped
5   167   2   multip. unsigned short
6   177   4   multip. unsigned long
7   155   4   multip. text
8   138   4   multip. unsigned long
9   177   4   multip. unsigned long
    193   1           text
@end example

Example of @command{myisamchk -d -v} output:

@example
MyISAM file:         company
Record format:       Fixed length
File-version:        1
Creation time:       1999-10-30 12:12:51
Recover time:        1999-10-31 19:13:01
Status:              checked
Data records:            1403698  Deleted blocks:              0
Datafile parts:          1403698  Deleted data:                0
Datafile pointer (bytes):      3  Keyfile pointer (bytes):     3
Max datafile length:  3791650815  Max keyfile length: 4294967294
Recordlength:                226

table description:
Key Start Len Index   Type                  Rec/key     Root Blocksize
1   2     8   unique  double                      1 15845376      1024
2   15    10  multip. text packed stripped        2 25062400      1024
3   219   8   multip. double                     73 40907776      1024
4   63    10  multip. text packed stripped        5 48097280      1024
5   167   2   multip. unsigned short           4840 55200768      1024
6   177   4   multip. unsigned long            1346 65145856      1024
7   155   4   multip. text                     4995 75090944      1024
8   138   4   multip. unsigned long              87 85036032      1024
9   177   4   multip. unsigned long             178 96481280      1024
    193   1           text
@end example

Example of @command{myisamchk -eis} output:

@example
Checking MyISAM file: company
Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
Total:    Keyblocks used:  98%  Packed:   17%

Records:          1403698    M.recordlength:     226
Packed:             0%
Recordspace used:     100%   Empty space:          0%
Blocks/Record:   1.00
Record blocks:    1403698    Delete blocks:        0
Recorddata:     317235748    Deleted data:         0
Lost space:             0    Linkdata:             0

User time 1626.51, System time 232.36
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 627, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 639, Involuntary context switches 28966
@end example

Example of @command{myisamchk -eiv} output:

@example
Checking MyISAM file: company
Data records: 1403698   Deleted blocks:       0
- check file-size
- check delete-chain
block_size 1024:
index  1:
index  2:
index  3:
index  4:
index  5:
index  6:
index  7:
index  8:
index  9:
No recordlinks
- check index reference
- check data record references index: 1
Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
- check data record references index: 2
Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
- check data record references index: 3
Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
- check data record references index: 4
Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
- check data record references index: 5
Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 6
Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 7
Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 8
Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 9
Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
Total:    Keyblocks used:   9%  Packed:   17%

- check records and index references
[LOTS OF ROW NUMBERS DELETED]

Records:         1403698   M.recordlength:   226   Packed:           0%
Recordspace used:    100%  Empty space:        0%  Blocks/Record: 1.00
Record blocks:   1403698   Delete blocks:      0
Recorddata:    317235748   Deleted data:       0
Lost space:            0   Linkdata:           0

User time 1639.63, System time 251.61
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0
Blocks in 4 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 10604, Involuntary context switches 122798
@end example

Explanations for the types of information @command{myisamchk} produces are
given here.  ``Keyfile'' refers to the index file.  ``Record'' and ``row''
are synonymous.

@itemize @bullet
@item @code{MyISAM file}

Name of the @code{MyISAM} (index) file.

@item @code{File-version}

Version of @code{MyISAM} format. Currently always 2.

@item @code{Creation time}

When the data file was created.

@item @code{Recover time}

When the index/data file was last reconstructed.

@item @code{Data records}

How many records are in the table.

@item @code{Deleted blocks}

How many deleted blocks still have reserved space.
You can optimize your table to minimize this space.
@xref{Optimization}.

@item @code{Datafile parts}

For dynamic record format, this indicates how many data blocks there are. For
an optimized table without fragmented records, this is the same as @code{Data
records}.

@item @code{Deleted data}

How many bytes of unreclaimed deleted data there are.
You can optimize your table to minimize this space.
@xref{Optimization}.

@item @code{Datafile pointer}

The size of the data file pointer, in bytes. It is usually 2, 3, 4, or 5
bytes. Most tables manage with 2 bytes, but this cannot be controlled
from MySQL yet. For fixed tables, this is a record address. For
dynamic tables, this is a byte address.

@item @code{Keyfile pointer}

The size of the index file pointer, in bytes. It is usually 1, 2, or 3
bytes. Most tables manage with 2 bytes, but this is calculated
automatically by MySQL. It is always a block address.

@item @code{Max datafile length}

How long the table data file can become, in bytes.

@item @code{Max keyfile length}

How long the table index file can become, in bytes.

@item @code{Recordlength}

How much space each record takes, in bytes.

@item @code{Record format}

The format used to store table rows.
The preceding examples use @code{Fixed length}.
Other possible values are @code{Compressed} and @code{Packed}.

@item @code{table description}

A list of all keys in the table. For each key, @command{myisamchk} displays
some low-level information:

@itemize @minus
@item @code{Key}

This key's number.

@item @code{Start}

Where in the record this index part starts.

@item @code{Len}

How long this index part is. For packed numbers, this should always be
the full length of the column. For strings, it may be shorter than the full
length of the indexed column, because you can index a prefix of a string
column.

@item @code{Index}

Whether a key value can exist multiple times in the index. Values are
@code{unique} or @code{multip.} (multiple).

@item @code{Type}

What data type this index part has. This is a @code{MyISAM} data type
with the options @code{packed}, @code{stripped}, or @code{empty}.

@item @code{Root}

Address of the root index block.

@item @code{Blocksize}

The size of each index block. By default this is 1024, but the value may be
changed at compile time when MySQL is built from source.

@item @code{Rec/key}

This is a statistical value used by the optimizer. It tells how many
records there are per value for this key. A unique key always has a
value of 1. This may be updated after a table is loaded (or greatly
changed) with @command{myisamchk -a}. If this is not updated at all, a default
value of 30 is given.
@end itemize

For the table shown in the examples, there are two @code{table description}
lines for the ninth index. This indicates that it is a multiple-part index
with two parts.

@item @code{Keyblocks used}

What percentage of the keyblocks are used. When a table has just been
reorganized with @command{myisamchk}, as for the table in the examples, the
values are very high (very near the theoretical maximum).

@item @code{Packed}

MySQL tries to pack keys with a common suffix. This can only be used
for indexes on @code{CHAR}, @code{VARCHAR}, or @code{DECIMAL} columns. For
long indexed strings that have similar leftmost parts,
this can significantly reduce the space used. In the third example
above, the fourth key is 10 characters long and a 60% reduction in space is
achieved.

@item @code{Max levels}

How deep the B-tree for this key is. Large tables with long key values get high
values.

@item @code{Records}

How many rows are in the table.

@item @code{M.recordlength}

The average record length.  This is the exact record length for tables
with fixed-length records, because all records have the same length.

@item @code{Packed}

MySQL strips spaces from the end of strings. The @code{Packed}
value indicates the percentage of savings achieved by doing this.

@item @code{Recordspace used}

What percentage of the data file is used.

@item @code{Empty space}

What percentage of the data file is unused.

@item @code{Blocks/Record}

Average number of blocks per record (that is, how many links a fragmented
record is composed of). This is always 1.0 for fixed-format tables. This
value should stay as close to 1.0 as possible. If it gets too big, you can
reorganize the table.
@xref{Optimization}.

@item @code{Recordblocks}

How many blocks (links) are used. For fixed format, this is the same as the number
of records.

@item @code{Deleteblocks}

How many blocks (links) are deleted.

@item @code{Recorddata}

How many bytes in the data file are used.

@item @code{Deleted data}

How many bytes in the data file are deleted (unused).

@item @code{Lost space}

If a record is updated to a shorter length, some space is lost. This is
the sum of all such losses, in bytes.

@item @code{Linkdata}

When the dynamic table format is used, record fragments are linked with
pointers (4 to 7 bytes each). @code{Linkdata} is the sum of the amount of
storage used by all such pointers.

@end itemize

If a table has been compressed with @command{myisampack}, @command{myisamchk
-d} prints additional information about each table column.  See
@ref{myisampack, , @command{myisampack}}, for an example of this
information and a description of what it means.

@node Localisation, Log Files, Disaster Prevention, MySQL Database Administration
@section MySQL Localization and International Usage

This section describes how to configure the server to use different
character sets.  It also discusses how to set the server's time zone
and enable per-connection time zone support.

@menu
* Character sets::              The Character Set Used for Data and Sorting
* Languages::                   Setting the Error Message Language
* Adding character set::        Adding a New Character Set
* Character arrays::            The Character Definition Arrays
* String collating::            String Collating Support
* Multi-byte characters::       Multi-Byte Character Support
* Problems with character sets::  Problems With Character Sets
* Time zone support::           MySQL Server Time Zone Support
@end menu


@node Character sets, Languages, Localisation, Localisation
@subsection The Character Set Used for Data and Sorting

@cindex character sets
@cindex data, character sets
@cindex sorting, character sets

By default, MySQL uses the ISO-8859-1 (Latin1) character set
with sorting according to Swedish/Finnish rules. These defaults are suitable
for the United States and most of western Europe.

All MySQL binary distributions are compiled with
@code{--with-extra-charsets=complex}.  This adds code to all
standard programs that enables them to handle @code{latin1} and all multi-byte
character sets within the binary. Other character sets will be
loaded from a character-set definition file when needed.

The character set determines what characters are allowed in names. It also
determines how strings are sorted by the @code{ORDER BY} and @code{GROUP
BY} clauses of the @code{SELECT} statement.

You can change the character set with the @code{--default-character-set}
option when you start the server.  The character sets available depend
on the @code{--with-charset=@var{charset}} and @code{--with-extra-charsets=
@var{list-of-charsets} | complex | all | none} options to @command{configure}, and the
character set configuration files listed in
@file{SHAREDIR/charsets/Index}.
@xref{configure options,  , @command{configure} options}.

As of MySQL 4.1.1, you can also change the character set collation with the
@code{--default-collation} option when you start the server.  The collation
must be a legal collation for the default character set.  (Use the
@code{SHOW COLLATION} statement to determine which collations are available
for each character set.)
@xref{configure options,  , @command{configure} options}.

If you change the character set when running MySQL, that may also
change the sort order.  Consequently, you must run @command{myisamchk -r -q
--set-character-set=@var{charset}} on all tables, or your indexes may not be
ordered correctly.

When a client connects to a MySQL server, the server indicates to the
client what the server's default character set is.  The client will switch
to use this character set for this connection.

You should use @code{mysql_real_escape_string()} when escaping strings
for an SQL query.  @code{mysql_real_escape_string()} is identical to the
old @code{mysql_escape_string()} function, except that it takes the @code{MYSQL}
connection handle as the first parameter so that the appropriate character set
can be taken into account when escaping characters.

If the client is compiled with different paths than where the server is
installed and the user who configured MySQL didn't include all character
sets in the MySQL binary, you must tell the client where it can find the
additional character sets it will need if the server runs with a different
character set than the client.

You can do this by specifying a @code{--character-sets-dir} option to
indicate the path to the directory in which the dynamic MySQL character
sets are stored. For example, you can put the following in an option file:

@example
[client]
character-sets-dir=/usr/local/mysql/share/mysql/charsets
@end example

You can force the client to use specific character set as follows:

@example
[client]
default-character-set=@var{charset}
@end example

This is normally unnecessary, however.

@menu
* German character set::        Using the German Character Set
@end menu

@node German character set,  , Character sets, Character sets
@subsubsection Using the German Character Set

In MySQL 4.0, to get German sorting order, you should start @command{mysqld}
with a @code{--default-character-set=latin1_de} option.  This affects server
behavior in several ways:

@itemize @bullet
@item
When sorting and comparing strings, the following mapping is performed on the
strings before doing the comparison:

@example
@"a  ->  ae
@"o  ->  oe
@"u  ->  ue
@ss{}  ->  ss
@end example

@item
All accented characters are converted to their unaccented uppercase
counterpart.  All letters are converted to uppercase.

@item
When comparing strings with @code{LIKE}, the one-character to two-character mapping
is not done. All letters are converted to uppercase. Accents are removed
from all letters except @code{@"U}, @code{@"u}, @code{@"O}, @code{@"o},
@code{@"A}, and @code{@"a}.

@end itemize

In MySQL 4.1 and up, character set and collation are specified separately.
You should select the @code{latin1} character set and either the
@code{latin1_german1_ci} or @code{latin1_german2_ci} collation.  For
example, to start the server with the @code{latin1_german1_ci} collation,
use the @code{--character-set-server=latin1} and
@code{--collation-server=latin1_german1_ci} options.

For information on the differences between these two collations, see
@ref{Charset-we-sets}.


@node Languages, Adding character set, Character sets, Localisation
@subsection Setting the Error Message Language

@cindex error messages, languages
@cindex messages, languages
@cindex files, error messages
@cindex language support

By default, @command{mysqld} produces error messages in English, but they can
also be displayed in any of these other languages:
Czech, Danish, Dutch, Estonian, French, German, Greek,
Hungarian, Italian, Japanese, Korean, Norwegian, Norwegian-ny, Polish,
Portuguese, Romanian, Russian, Slovak, Spanish, or Swedish.

To start @command{mysqld} with a particular language for error messages, use the
@code{--language} or @code{-L} option. The option value can be a language name
or the full path to the error message file.
For example:

@example
shell> mysqld --language=swedish
@end example

Or:

@example
shell> mysqld --language=/usr/local/share/swedish
@end example

The language name should be specified in lowercase.

The language files are located (by default) in the
@file{share/@var{LANGUAGE}} directory under the MySQL base
directory.

To change the error message file, you should edit the @file{errmsg.txt} file,
and then execute the following command to generate the @file{errmsg.sys} file:

@example
shell> comp_err errmsg.txt errmsg.sys
@end example

If you upgrade to a newer version of MySQL, remember to repeat
your changes with the new @file{errmsg.txt} file.


@node Adding character set, Character arrays, Languages, Localisation
@subsection Adding a New Character Set

@cindex character sets, adding
@cindex adding, character sets

This section discusses the procedure for adding add another character set to
MySQL.  You must have a MySQL source distribution to use these instructions.

To choose the proper procedure, decide whether the character
set is simple or complex:

@itemize @bullet

@item
If the character set does not need to use special string collating routines
for sorting and does not need multi-byte character support, it is simple.

@item
If it needs either of those features, it is complex.

@end itemize

For example, @code{latin1} and @code{danish} are simple character sets,
whereas @code{big5} and @code{czech} are complex character sets.

In the following procedures, the name of your character
set is represented by @var{MYSET}.

For a simple character set, do the following:

@enumerate
@item
Add @var{MYSET} to the end of the @file{sql/share/charsets/Index} file.
Assign a unique number to it.

@item
Create the file @file{sql/share/charsets/@var{MYSET}.conf}.
(You can use a copy of @file{sql/share/charsets/latin1.conf} as the basis for
this file.)

The syntax for the file is very simple:

@itemize @bullet
@item
Comments start with a @samp{#} character and proceed to the end of the line.
@item
Words are separated by arbitrary amounts of whitespace.
@item
When defining the character set, every word must be a number in hexadecimal
format.
@item
The @code{ctype} array takes up the first 257 words. The
@code{to_lower[]}, @code{to_upper[]} and @code{sort_order[]} arrays take up
256 words each after that.
@end itemize

@xref{Character arrays}.

@item
Add the character set name to the @code{CHARSETS_AVAILABLE} and
@code{COMPILED_CHARSETS} lists in @code{configure.in}.

@item
Reconfigure, recompile, and test.

@end enumerate

For a complex character set, do the following:

@enumerate
@item
Create the file @file{strings/ctype-@var{MYSET}.c} in the MySQL source
distribution.

@item
Add @var{MYSET} to the end of the @file{sql/share/charsets/Index} file.
Assign a unique number to it.

@item
Look at one of the existing @file{ctype-*.c} files (such as
@file{strings/ctype-big5.c}) to see what needs to be defined.
Note that the
arrays in your file must have names like @code{ctype_@var{MYSET}},
@code{to_lower_@var{MYSET}}, and so on.  These correspond to the arrays
for a simple character set. @xref{Character arrays}.

@item
Near the top of the file, place a special comment like this:

@example
/*
 * This comment is parsed by configure to create ctype.c,
 * so don't change it unless you know what you are doing.
 *
 * .configure. number_@var{MYSET}=@var{MYNUMBER}
 * .configure. strxfrm_multiply_@var{MYSET}=@var{N}
 * .configure. mbmaxlen_@var{MYSET}=@var{N}
 */
@end example

The @command{configure} program uses this comment to include
the character set into the MySQL library automatically.

The @code{strxfrm_multiply} and @code{mbmaxlen} lines are explained in
the following sections.  You need include them only if you need the string
collating functions or the multi-byte character set functions,
respectively.

@item
You should then create some of the following functions:

@itemize @bullet
@item @code{my_strncoll_@var{MYSET}()}
@item @code{my_strcoll_@var{MYSET}()}
@item @code{my_strxfrm_@var{MYSET}()}
@item @code{my_like_range_@var{MYSET}()}
@end itemize

@xref{String collating}.

@item
Add the character set name to the @code{CHARSETS_AVAILABLE} and
@code{COMPILED_CHARSETS} lists in @code{configure.in}.

@item
Reconfigure, recompile, and test.
@end enumerate

The @file{sql/share/charsets/README} file includes additional instructions.

If you want to have the character set included in the MySQL
distribution, mail a patch to the MySQL @code{internals} mailing list.
@xref{Mailing-list}.


@node Character arrays, String collating, Adding character set, Localisation
@subsection The Character Definition Arrays

@code{to_lower[]} and @code{to_upper[]} are simple arrays that hold the
lowercase and uppercase characters corresponding to each member of the
character set.  For example:

@example
to_lower['A'] should contain 'a'
to_upper['a'] should contain 'A'
@end example

@code{sort_order[]} is a map indicating how characters should be ordered for
comparison and sorting purposes. Quite often (but not for all character sets)
this is the same as @code{to_upper[]}, which means that sorting will be
case-insensitive. MySQL will sort characters based on the values of
@code{sort_order[]} elements.  For more complicated sorting rules, see
the discussion of string collating in @ref{String collating}.

@code{ctype[]} is an array of bit values, with one element for one character.
(Note that @code{to_lower[]}, @code{to_upper[]}, and @code{sort_order[]}
are indexed by character value, but @code{ctype[]} is indexed by character
value + 1.  This is an old legacy convention to be able to handle @code{EOF}.)

You can find the following bitmask definitions in @file{m_ctype.h}:

@example
#define _U      01      /* Uppercase */
#define _L      02      /* Lowercase */
#define _N      04      /* Numeral (digit) */
#define _S      010     /* Spacing character */
#define _P      020     /* Punctuation */
#define _C      040     /* Control character */
#define _B      0100    /* Blank */
#define _X      0200    /* heXadecimal digit */
@end example

The @code{ctype[]} entry for each character should be the union of the
applicable bitmask values that describe the character.  For example,
@code{'A'} is an uppercase character (@code{_U}) as well as a
hexadecimal digit (@code{_X}), so @code{ctype['A'+1]} should contain the
value:

@example
_U + _X = 01 + 0200 = 0201
@end example


@node String collating, Multi-byte characters, Character arrays, Localisation
@subsection String Collating Support

@cindex collating, strings
@cindex string collating

If the sorting rules for your language are too complex to be handled
with the simple @code{sort_order[]} table, you need to use the string
collating functions.

Right now the best documentation for this is the character sets that are
already implemented.  Look at the @code{big5}, @code{czech}, @code{gbk},
@code{sjis}, and @code{tis160} character sets for examples.

You must specify the @code{strxfrm_multiply_@var{MYSET}=@var{N}} value in the
special comment at the top of the file.  @var{N} should be set to
the maximum ratio the strings may grow during @code{my_strxfrm_@var{MYSET}} (it
must be a positive integer).


@node Multi-byte characters, Problems with character sets, String collating, Localisation
@subsection Multi-Byte Character Support

@cindex characters, multi-byte
@cindex multi-byte characters

If you want to add support for a new character set that includes
multi-byte characters, you need to use the multi-byte character
functions.

Right now the best documentation on this consists of the character sets that are
already implemented.  Look at the @code{euc_kr}, @code{gb2312},
@code{gbk}, @code{sjis}, and @code{ujis} character sets for
examples. These are implemented in the @file{ctype-@var{charset}.c} files
in the @file{strings} directory.

You must specify the @code{mbmaxlen_@var{MYSET}=@var{N}} value in the special
comment at the top of the source file.  @var{N} should be set to the
size in bytes of the largest character in the set.

@node Problems with character sets, Time zone support, Multi-byte characters, Localisation
@subsection Problems With Character Sets

If you try to use a character set that is not compiled into your binary,
you might run into the following problems:

@itemize @bullet
@item
Your program has an incorrect path to where the character sets are stored.
(Default @file{/usr/local/mysql/share/mysql/charsets}).
This can be fixed by using the @code{--character-sets-dir}
option when you run the program in question.
@item
The character set is a multi-byte character set that can't be loaded
dynamically.  In this case, you must recompile the program with
support for the character set.
@item
@c TODO: dynamic = not compiled in?
The character set is a dynamic character set, but you don't have a
configure file for it.  In this case, you should install the configure
file for the character set from a new MySQL distribution.
@item
If your @file{Index} file doesn't contain the name for the character set, your
program will display the following error message:

@example
ERROR 1105: File '/usr/local/share/mysql/charsets/?.conf'
not found (Errcode: 2)
@end example

In this case, you should either get a new @code{Index} file or manually add
the name of any missing character sets to the current file.
@end itemize

For @code{MyISAM} tables, you can check the character set name and number for a
table with @command{myisamchk -dvv @var{tbl_name}}.


@node Time zone support,  , Problems with character sets, Localisation
@subsection MySQL Server Time Zone Support

Before MySQL 4.1.3, you can set the time zone for the server with the
@code{--timezone=@var{timezone_name}} option to @command{mysqld_safe}.  You can
also set it by setting the @code{TZ} environment variable before you
start @command{mysqld}.

The allowable values for @code{--timezone} or @code{TZ} are
system-dependent. Consult your operating system documentation to see
what values are acceptable.

Beginning with MySQL 4.1.3, the server maintains several time zone settings:

@itemize @bullet
@item
The system time zone.  When the server starts, it attempts to determine the
time zone of the host machine and uses it to set the @code{system_time_zone}
system variable.

@item
The server's current time zone. The global @code{time_zone} system variable
indicates the time zone the server currently is operating in. The initial
value is @code{'SYSTEM'}, which indicates that the server time zone is the
same as the system time zone. The initial value can be specified explicitly
with the @code{--default-time-zone=@var{timezone}} option.  If you have the
@code{SUPER} privilege, you can set the global value at runtime with this
statement:

@example
mysql> SET GLOBAL time_zone = @var{timezone};
@end example

@item
Per-connection time zones. Each client that connects has its own time
zone setting, given by the session @code{time_zone} variable. Initially
this is the same as the global @code{time_zone} variable, but can be
reset with this statement:

@example
mysql> SET time_zone = @var{timezone};
@end example

@end itemize

The current values of the global and per-connection time zones can be
retrieved like this:

@example
mysql> SELECT @@@@global.time_zone, @@@@session.time_zone;
@end example

@var{timezone} values can be given as strings indicating an offset
from UTC, such as @code{'+10:00'} or @code{'-6:00'}. If the time zone-related
tables in the @code{mysql} database have been created and populated, you
can also used named time zones, such as @code{'Europe/Helsinki'},
@code{'US/Eastern'}, or @code{'MET'}. The value @code{'SYSTEM'} indicates
that the time zone should be the same as the system time zone.  Time zone
names are not case sensitive.

The MySQL installation procedure creates the time zone tables in the
@code{mysql} database, but does not load them. You must do so manually.
(If you are upgrading to MySQL 4.1.3 or later from an earlier version, you
should create the tables by upgrading your @code{mysql} database. Use the
instructions in @ref{Upgrading-grant-tables}.)

If your system has its own zoneinfo database (the set of files describing
time zones), you should use the @command{mysql_tzinfo_to_sql} program for
filling the time zone tables. Examples of such systems are Linux, FreeBSD,
Sun Solaris, and Mac OS X. One likely location for these files is the
@file{/usr/share/zoneinfo} directory. If your system does not have a
zoneinfo database, you can use the downloadable package described later in
this section.

The @command{mysql_tzinfo_to_sql} program is used to load the time zone
tables.  On the command line, pass the zoneinfo directory pathname to
@command{mysql_tzinfo_to_sql} and send the output into the @command{mysql}
program. For example:

@example
shell> mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
@end example

@command{mysql_tzinfo_to_sql} reads your system's time zone files and
generates SQL statements from them.  @command{mysql} processes those
statements to load the time zone tables.

@command{mysql_tzinfo_to_sql} also can be used to load a single time zone
file, and to generate leap second information.

To load a single time zone file @var{tz_file} that corresponds to a
time zone name @var{tz_name}, invoke @command{mysql_tzinfo_to_sql} like this:

@example
shell> mysql_tzinfo_to_sql @var{tz_file} @var{tz_name} | mysql -u root mysql
@end example

If your time zone needs to account for leap seconds, initialize the
leap second information like this, where @var{tz_file} is the name of
your time zone file:

@example
shell> mysql_tzinfo_to_sql --leap @var{tz_file} | mysql -u root mysql
@end example

If your system doesn't have a zoneinfo database (for example, Windows or
HP-UX), you can use the package of pre-built time zone tables that is
available for download at
@uref{http://dev.mysql.com/downloads/timezones.html}.  This package contains
@file{.frm}, @file{.MYD}, and @file{.MYI} files for the @code{MyISAM} time
zone tables.  These tables should belong to the @code{mysql} database, so
you should place the files in the @file{mysql} subdirectory of your MySQL
server's data directory. The server should be shut down while you do this.

@strong{Warning!} Please don't use the downloadable package if your system
has a zoneinfo database. Use the @command{mysql_tzinfo_to_sql} utility
instead! Otherwise, you may cause a difference in datetime handling between
MySQL and other applications on your system.



@node Log Files, Multiple servers, Localisation, MySQL Database Administration
@section The MySQL Log Files

@cindex Log files

MySQL has several different log files that can help you find
out what's going on inside @command{mysqld}:

@multitable @columnfractions .20 .80
@item @strong{Log File} @tab @strong{Types of Information Logged to File}
@item The error log @tab Logs problems encountered starting, running, or
stopping @command{mysqld}.
@item The isam log @tab Logs all changes to the @code{ISAM} tables. Used only for debugging the isam code.
@item The query log @tab Logs established client connections and executed statements.
@item The update log @tab Logs statements that change data. This log is deprecated.
@item The binary log @tab Logs all statements that change data. Also used for replication.
@item The slow log @tab Logs all queries that took more than @code{long_query_time} seconds to execute or didn't use indexes.
@end multitable

By default, all logs are created in the @command{mysqld} data directory.  You can
force @command{mysqld} to close and reopen the log files (or in some cases
switch to a new log) by flushing the logs. Log flushing occurs when you
issue a @code{FLUSH LOGS} statement or execute @command{mysqladmin flush-logs} or
@command{mysqladmin refresh}.
@xref{FLUSH}.

If you are using MySQL replication capabilities, slave replication servers
maintain additional log files called relay logs. These are discussed in
@ref{Replication}.

@menu
* Error log::                   The Error Log
* Query log::                   The General Query Log
* Update log::                  The Update Log
* Binary log::                  The Binary Log
* Slow query log::              The Slow Query Log
* Log file maintenance::        Log File Maintenance
@end menu


@node Error log, Query log, Log Files, Log Files
@subsection The Error Log

The error log file contains information indicating when @command{mysqld}
was started and stopped and also any critical errors that occur while the
server is running.

If @command{mysqld} dies unexpectedly and @command{mysqld_safe} needs to
restart it, @command{mysqld_safe} will write a @code{restarted
mysqld} message to the error log.  If
@command{mysqld} notices a table that needs to be automatically checked or
repaired, it writes a message to the error log.

On some operating systems, the error log will contain a stack trace if
@command{mysqld} dies. The trace can be used to determine where
@command{mysqld} died.  @xref{Using stack trace}.

Beginning with MySQL 4.0.10, you can specify where @command{mysqld} stores the
error log file with the @code{--log-error[=@var{file_name}]} option. If no
@var{file_name} value is given, @command{mysqld} uses the name
@file{@var{host_name}.err} and writes the file in the data directory.
(Prior to MySQL 4.0.10, the Windows error log name is @file{mysql.err}.)
If you execute @code{FLUSH LOGS}, the error log is renamed with a suffix
of @code{-old} and @command{mysqld} creates a new empty log file.

In older MySQL versions on Unix, error log handling was done by
@command{mysqld_safe} which redirected the error file to
@code{@var{host_name}.err}.  You could change this filename by specifying a
@code{--err-log=@var{file_name}} option to @command{mysqld_safe}.

If you don't specify @code{--log-error}, or (on Windows) if you use the
@code{--console} option, errors are written to stderr, the standard error
output. Usually this is your terminal.

On Windows, error output is always written to the @code{.err} file if
@code{--console} is not given.

@node Query log, Update log, Error log, Log Files
@subsection The General Query Log

@cindex query log
@cindex files, query log

If you want to know what happens within @command{mysqld}, you should start
it with the @code{--log[=@var{file_name}]} or @code{-l [@var{file_name}]} option.
If no @var{file_name} value is given, the default name is
@file{@var{host_name}.log}
This will log all connections and statements to the log file.
This log can be very useful when you suspect an error in a client and want
to know exactly what the client sent to @command{mysqld}.

@c Note: This instance of "safe_mysql" should not be changed to "mysqld_safe"
@c because it's a 3.23.x-specific command
Older versions of the @command{mysql.server} script (from MySQL 3.23.4 to 3.23.8)
pass a @code{--log} option to @command{safe_mysqld} to enable the general query log.
If you need better performance when you start using MySQL in a production
environment, you can remove the @code{--log} option from @command{mysql.server}
or change it to @code{--log-bin}. @xref{Binary log}.

@command{mysqld} writes statements to the query log in the order that it
receives them.  This may be different from the order in which they are
executed.  This is in contrast to the update log and the binary log, which
are written after the query is executed, but before any locks are released.
(The query log also contains all statements, whereas the update and binary
logs do not contain statements that only select data.)

Server restarts and log flushing do not cause a new general query log file
to be generated (although flushing closes and reopens it). On Unix, you can
rename the file and create a new one by using the following commands:

@example
shell> mv hostname.log hostname-old.log
shell> mysqladmin flush-logs
shell> cp hostname-old.log to-backup-directory
shell> rm hostname-old.log
@end example

On Windows, you cannot rename the log file while the server has it open.
You must stop the server and rename the log. Then restart the server to create
a new log.


@node Update log, Binary log, Query log, Log Files
@subsection The Update Log

@cindex update log
@cindex files, update log

@strong{Note}: The update log has been deprecated and replaced by the binary
log. @xref{Binary log}.  The binary log can do anything the old update log
could do, and more. @emph{The update log is unavailable as of MySQL
5.0.0}.

When started with the @code{--log-update[=@var{file_name}]} option,
@command{mysqld} writes a log file containing all SQL statements that update
data. If no @var{file_name} value is given, the default name is name of the host
machine. If a filename is given, but it doesn't contain a leading path, the file
is written in the data directory. If @file{file_name} doesn't have an
extension, @command{mysqld} creates log files with names of the form
@var{file_name.###}, where @var{###} is a number that is incremented each
time you start the server or flush the logs.

@strong{Note}: For this naming scheme to work, you must not create
your own files with the same names as those that might be used for the log
file sequence.

Update logging is smart because it logs only statements that really update
data. So, an @code{UPDATE} or a @code{DELETE} with a @code{WHERE} that finds no
rows is not written to the log. It even skips @code{UPDATE} statements that
set a column to the value it already has.

The update logging is done immediately after a query completes but before
any locks are released or any commit is done. This ensures that statements
are logged in execution order.

If you want to update a database from update log files, you could do the
following (assuming that your update logs have names of the form
@file{file_name.###}):

@example
shell> ls -1 -t -r file_name.[0-9]* | xargs cat | mysql
@end example

@code{ls} is used to sort the update log filenames into the right order.

This can be useful if you have to revert to backup files after a crash
and you want to redo the updates that occurred between the time of the backup
and the crash.


@node Binary log, Slow query log, Update log, Log Files
@subsection The Binary Log

@cindex binary log
@cindex files, binary log

The binary log has replaced the old update log, which is unavailable
starting from MySQL 5.0. The binary log contains all information that is
available in the update log in a more efficient format and in a manner
that is transactionally safe.

The binary log contains all statements which updated data or (starting from
MySQL 4.1.3) could potentially have updated it (for example, a @code{DELETE}
which matched no rows).

The binary log also contains information about how long each statement took
that updated the database.  It doesn't contain statements that don't modify
any data.  If you want to log all statements (for example, to identify a problem
query) you should use the general query log. @xref{Query log}.

The primary purpose of the binary log is to be able to update the database
during a restore operation as fully as possible, because the binary log will
contain all updates done after a backup was made.

The binary log is also used on master replication servers as a record of the
statements to be sent to slave servers.
@xref{Replication}.

Running the server with the binary log enabled makes performance about 1%
slower. However, the benefits of the binary log for restore operations and
in allowing you to set up replication generally outweigh this minor
performance decrement.

When started with the @code{--log-bin[=@var{file_name}]} option, @command{mysqld}
writes a log file containing all SQL commands that update data. If no
@var{file_name} value is given, the default name is the name of the host machine followed
by @code{-bin}. If file name is given, but it doesn't contain a path, the
file is written in the data directory.

If you supply an extension in the log name (for example,
@code{--log-bin=@var{file_name.extension}}), the
extension is silently removed and ignored.

@command{mysqld} appends a numeric extension to the binary log name. The number
is incremented each time you start the server or flush the logs.
A new binary log also is created
automatically when the current log's size reaches 
@code{max_binlog_size}. A binary log may become larger than
@code{max_binlog_size} if you are using large transactions: A transaction is
written to the binary log in one piece, never split between binary logs.

To be able to know which different binary log files have been used,
@command{mysqld} also creates a binary log index file that
contains the name of all used binary log files. By default this has the
same name as the binary log file, with the extension @code{'.index'}.
You can change the name of the binary log index file with the
@code{--log-bin-index[=@var{file_name}]} option.
You should not manually edit this file while @command{mysqld} is running;
doing so would confuse @command{mysqld}.

You can delete all binary log files with the @code{RESET MASTER} statement,
or only some of them with @code{PURGE MASTER LOGS}.
See @ref{RESET, , @code{RESET}} and @ref{Replication Master SQL}.

The binary log format has some known limitations which can affect recovery from
backups, especially in old versions. These caveats which also affect
replication are listed at @ref{Replication Features}. One caveat which does not
affect replication but only recovery with @code{mysqlbinlog}: before MySQL 4.1,
@command{mysqlbinlog} could not prepare output suitable for @command{mysql} if
the binary log contained interlaced statements originating from different
clients that used temporary tables of the same name. This is fixed in MySQL
4.1. However, the problem still existed for @code{LOAD DATA INFILE} statements
until it was fixed in MySQL 4.1.8.

You can use the following options to @command{mysqld} to affect what is logged
to the binary log. See also the discussion that follows this option list.

@table @code

@item --binlog-do-db=@var{db_name}
Tells the master that it should log updates to the binary log if the current
database (that is, the one selected by @code{USE}) is @var{db_name}. All
other databases that are not explicitly mentioned are ignored.  If you use
this, you should ensure that you only do updates in the current database.

Observe that there is an exception to the @code{CREATE/ALTER/DROP
DATABASE} statements, which use the database manipulated to decide if
it should log the statement rather than the current database.

An example of what does not work as you might expect: If the server is
started with @code{binlog-do-db=sales}, and you do
@code{USE prices; UPDATE sales.january SET amount=amount+1000;},
this statement will not be written into the binary log.

@item --binlog-ignore-db=@var{db_name}
Tells the master that updates where the current database
(that is, the one selected by @code{USE}) is
@var{db_name} should not be stored in the binary log.  If
you use this, you should ensure that you only do updates in the current
database.

An example of what does not work as you might expect: If the server is
started with @code{binlog-ignore-db=sales}, and you do
@code{USE prices; UPDATE sales.january SET amount=amount+1000;},
this statement will be written into the binary log.

Similar to the case for @code{--binlog-do-db}, there is an exception
to the @code{CREATE/ALTER/DROP DATABASE} statements, which use the
database manipulated to decide if it should log the statement rather
than the current database.

@end table

To log or ignore multiple databases, specify the appropriate option multiple
times, once for each database.

The rules for logging or ignoring updates to the binary log are
evaluated according to the following rules. Observe that there is an
exception for @code{CREATE/ALTER/DROP DATABASE} statements. In those
cases, the database being @emph{created/altered/dropped} replace the
current database in the rules below.

@enumerate
@item
Are there @code{binlog-do-db} or @code{binlog-ignore-db} rules?
@itemize @bullet
@item No:
Write the statement to the binary log and exit.
@item Yes:
Go to the next step.
@end itemize
@item
There are some rules (@code{binlog-do-db} or
@code{binlog-ignore-db} or both). Is there a current database (has any
database been selected by @code{USE}?)?
@itemize @bullet
@item No:
Do @emph{not} write the statement, and exit.
@item Yes:
Go to the next step.
@end itemize
@item
There is a current database. Are there some @code{binlog-do-db} rules?
@itemize @bullet
@item Yes:
Does the current database match any of the @code{binlog-do-db}
rules?
@itemize @bullet
@item Yes:
Write the statement and exit.
@item No:
Do @emph{not} write the statement, and exit.
@end itemize 
@item No:
Go to the next step.
@end itemize
@item
There are some @code{binlog-ignore-db} rules.
Does the current database match any of the @code{binlog-ignore-db}
rules?
@itemize @bullet
@item Yes:
Do not write the statement, and exit.
@item No:
Write the query and exit.
@end itemize 
@end enumerate

For example, a slave running with only @code{binlog-do-db=sales}
will not write to the binary log any statement whose current database is
different from @code{sales} (in other words, @code{binlog-do-db} can
sometimes mean ``ignore other databases'').

If you are using replication, you should not delete old binary log
files until you are sure that no slave still needs to use them.
One way to do this is to do @command{mysqladmin flush-logs} once a day and then
remove any logs that are more than three days old. You can remove them
manually, or preferably using @code{PURGE MASTER LOGS}
(@pxref{Replication Master SQL}), which will also safely update the binary 
log index file for you  (and which can take a date argument since
MySQL 4.1)

A client with the @code{SUPER} privilege can disable binary
logging of its own statements by using a @code{SET
SQL_LOG_BIN=0} statement. @xref{SET OPTION,  , @code{SET}}.

You can examine the binary log file with the @command{mysqlbinlog} utility.
This can be useful when you want to reprocess statements in the log.
For example, you can update a MySQL server from the binary log
as follows:

@example
shell> mysqlbinlog log-file | mysql -h server_name
@end example

See @ref{mysqlbinlog,  , @command{mysqlbinlog}} for more information on the
@command{mysqlbinlog} utility and how to use it.

If you are using transactions, you must
use the MySQL binary log for backups instead of the old update log.

The binary logging is done immediately after a query completes but before
any locks are released or any commit is done. This ensures that the log
will be logged in the execution order.

Updates to non-transactional tables are stored in the binary log
immediately after execution.  For transactional tables such as @code{BDB}
or @code{InnoDB} tables, all updates (@code{UPDATE}, @code{DELETE},
or @code{INSERT}) that change tables are cached until a @code{COMMIT}
statement is received by the server. At that point, @command{mysqld} writes the
whole transaction to the binary log before the @code{COMMIT} is executed.
When the thread that handles the transaction starts, it allocates a buffer
of @code{binlog_cache_size} to buffer queries.  If a statement is bigger
than this, the thread opens a temporary file to store the transaction.  The
temporary file is deleted when the thread ends.

The @code{Binlog_cache_use} status variable shows the number of transactions
that used this buffer (and possibly a temporary file) for storing statements.
The @code{Binlog_cache_disk_use} status variable shows how many of those
transactions actually did have to use a temporary file. These two variables
can be used for tuning @code{binlog_cache_size} to a large enough value that
avoids the use of temporary files.

The @code{max_binlog_cache_size} (default 4GB) can be used to restrict the
total size used to cache a multiple-statement transaction.  If a transaction
is larger than this, it will fail and roll back.

If you are using the update log or binary log, concurrent inserts will
be converted to normal inserts when using @code{CREATE ... SELECT} or
@code{INSERT ... SELECT}.
This is to ensure that you can re-create an exact copy of your tables by
applying the log on a backup.

The binary log format is different in versions 3.23, 4.0, and 5.0.0.
Those format changes were required to implement enhancements to replication.
MySQL 4.1 has the same binary log format as 4.0.
@xref{Replication Compatibility}.

By default, the binary log is not synchronized to disk at each write. So
if the operating system or machine (not only the MySQL server) crashes
there is a chance that the last statements of the binary log are lost. To
prevent this, you can make the binary log be synchronized to disk after
every Nth binary log write, with the @code{sync_binlog} global variable
(1 being the safest value, but also the slowest). @xref{Server system
variables}.  Even with this set to 1, there is still the chance of an
inconsistency between the tables content and the binary log content in
case of crash. For example, if using @code{InnoDB} tables, and the MySQL
server processes a @code{COMMIT} statement, it writes the whole transaction
to the binary log and then commits this transaction into @code{InnoDB}. If
it crashes between those two operations, at restart the transaction will be
rolled back by InnoDB but still exist in the binary log. This problem can be
solved with the @code{--innodb-safe-binlog} option (available starting from
MySQL 4.1.3), which adds consistency between the content of @code{InnoDB}
tables and the binary log. For this option to really bring safety to you,
the MySQL server should also be configured to synchronize to disk, at every
transaction, the binary log (@code{sync_binlog=1}) and (which is true by
default) the @code{InnoDB} logs.  The effect of this option is that at restart
after a crash,
after doing a rollback of transactions, the MySQL server will cut rolled
back @code{InnoDB} transactions from the binary log. This ensures that the
binary log reflects the exact data of @code{InnoDB} tables, and so, that
the slave remains in sync with the master (not receiving a statement which
has been rolled back).  Note that @code{--innodb-safe-binlog} can be used
even if the MySQL server updates other storage engines than InnoDB. Only
statements/transactions affecting @code{InnoDB} tables are subject to
being removed from the binary log at @code{InnoDB}'s crash recovery.  If at
crash recovery the MySQL server discovers that the binary log is shorter
than it should have been (that is, it lacks at least one successfully committed
@code{InnoDB} transaction), which should not happen if @code{sync_binlog=1}
and the disk/filesystem do an actual sync when they are requested to (some
don't), it will print an error message ("The binary log <name> is shorter
than its expected size"). In this case, this binary log is not correct,
replication should be restarted from a fresh master's data snapshot.

@node Slow query log, Log file maintenance, Binary log, Log Files
@subsection The Slow Query Log

@cindex slow query log
@cindex files, slow query log

When started with the @code{--log-slow-queries[=@var{file_name}]} option,
@command{mysqld} writes a log file containing all SQL statements that took
more than @code{long_query_time} seconds to execute. The time to acquire
the initial table locks are not counted as execution time.

If no @var{file_name} value is given, the default is the name of the
host machine with a suffix of @code{-slow.log}. If a filename is given,
but doesn't contain a path, the file is written in the data directory.

A statement is logged to the slow query log after it has been executed
and after all locks have been released. Log order may be different from
execution order.

The slow query log can be used to find queries that take a long time to
execute and are therefore candidates for optimization. However, examining a long
slow query log can become a difficult task. To make this easier, you
can pipe the slow query log through the @command{mysqldumpslow} command to
get a summary of the queries that appear in the log.

@c TODO: this differs now in 4.1, I believe

If you also use the @code{--log-long-format} when logging slow queries,
then queries that are not using indexes are logged as well.  @xref{Server
options}.


@node Log file maintenance,  , Slow query log, Log Files
@subsection Log File Maintenance

@cindex files, log
@cindex maintaining, log files
@cindex log files, maintaining

The MySQL Server can create a number of different log files that make
it easy to see what is going on. @xref{Log Files}. However, you must
clean up these files regularly to ensure that the logs don't take up
too much disk space.

When using MySQL with logging enabled, you will want to back up and remove
old log files from time to time and tell MySQL to start logging to new files.
@xref{Backup}.

On a Linux (Red Hat) installation, you can use the
@code{mysql-log-rotate} script for this. If you installed MySQL
from an RPM distribution, the script should have been installed
automatically.  You should be careful with this script if you are
using the binary log for replication! (You should not remove binary logs until
you are certain that their contents have been processed by all slaves.)

On other systems, you must install a short script yourself that you
start from @command{cron} to handle log files.

You can force MySQL to start using new log files by using
@command{mysqladmin flush-logs} or by using the SQL statement @code{FLUSH LOGS}.
If you are using MySQL 3.21, you must use @command{mysqladmin refresh}.

A log flushing operation does the following:

@itemize @bullet
@item
If standard logging (@code{--log}) or slow query logging
(@code{--log-slow-queries}) is used, closes and reopens the log file
(@file{mysql.log} and @file{`hostname`-slow.log} as default).
@item
If update logging (@code{--log-update}) or binary logging (@code{--log-bin})
is used, closes the log and opens a new log file with a higher sequence number.
@end itemize

If you are using only an update log, you only have to rename the log file
and then flush the logs before making a backup. For example, you can do
something like this:

@example
shell> cd mysql-data-directory
shell> mv mysql.log mysql.old
shell> mysqladmin flush-logs
@end example

Then make a backup and remove @file{mysql.old}.


@node Multiple servers, Query Cache, Log Files, MySQL Database Administration
@section Running Multiple MySQL Servers on the Same Machine

@cindex post-install, multiple servers
@cindex Starting many servers
@cindex multiple servers
@cindex servers, multiple
@cindex running, multiple servers

@menu
* Multiple Windows servers::    Running Multiple Servers on Windows
* Multiple Unix servers::       Running Multiple Servers on Unix
* Multiple-server clients::     Using Client Programs in a Multiple-Server Environment
@end menu

In some cases, you might want to run multiple @command{mysqld} servers
on the same machine.  You might want to test a new
MySQL release while leaving your existing production setup undisturbed.
Or you may want to give different users access to different @command{mysqld}
servers that they manage themselves.  (For example, you might be an
Internet Service Provider that wants to provide independent MySQL
installations for different customers.)

To run multiple servers on a single machine, each server must have
unique values for several operating parameters. These can be set on the
command line or in option files.
@xref{Program Options}.

At least the following options must be different for each server:

@table @code
@item --port=@var{port_num}
@code{--port} controls the port number for TCP/IP connections.

@item --socket=@var{path}
@code{--socket} controls the Unix socket file path on Unix and the name of the
named pipe on Windows. On Windows, it's necessary to specify distinct pipe names
only for those servers that support named pipe connections.

@item --shared-memory-base-name=@var{name}
This option currently is used only on Windows.
It designates the shared memory name used by a
Windows server to allow clients to connect via shared memory.
This option is new in MySQL 4.1.

@item --pid-file=@var{path}
This option is used only on Unix.
It indicates the name of the file in which the server writes its process ID.

@end table


If you use the following log file options, they must be different for
each server:

@c TODO: InnoDB options needed here?

@itemize @bullet
@item @code{--log=@var{path}}
@item @code{--log-bin=@var{path}}
@item @code{--log-update=@var{path}}
@item @code{--log-error=@var{path}}
@item @code{--log-isam=@var{path}}
@item @code{--bdb-logdir=@var{path}}
@end itemize

Log file options are described in @ref{Log file maintenance}.

If you want more performance, you can also specify the following options
differently for each server, to spread the load between several physical disks:

@itemize @bullet
@item @code{--tmpdir=@var{path}}
@item @code{--bdb-tmpdir=@var{path}}
@end itemize

Having different temporary directories is also recommended, to make
it easier to determine which MySQL server created any given
temporary file.

Generally, each server should also use a different data directory, which is
specified using the @code{--datadir=path} option.

@strong{Warning:} Normally you should never have two servers that
update data in the same databases!  This may lead to unpleasant
surprises if your operating system doesn't support fault-free system
locking!
If (despite this warning) you run multiple servers using
the same data directory and they have logging enabled, you must
use the appropriate options to specify log filenames that are
unique to each server.  Otherwise, the servers will try to log to
the same files.
Please note that this kind of setup will only work with @code{ISAM},
@code{MyISAM} and @code{MERGE} tables, and not with any of the other
storage engines.

The warning against sharing a data directory among servers also applies
in an NFS environment.  Allowing multiple MySQL servers to access a common
data directory over NFS is a @emph{bad idea}!

@itemize @bullet

@item
The primary problem is that NFS will become the speed bottleneck.
It is not meant for such use.

@item
Another risk with NFS is that you will have to come up with a way
to make sure that two or more servers do not interfere with each
other.  Usually NFS file locking is handled by the @code{lockd}
daemon, but at the moment there is no platform that will perform
locking 100% reliably in every situation.

@end itemize

Make it easy for yourself: Forget about sharing a data directory
among servers over NFS. A better solution is to have one computer
that contains several CPUs and use an operating system that
handles threads efficiently.

If you have multiple MySQL installations in different locations, normally
you can specify the base installation directory for each server with the
@code{--basedir=path} option to cause each server to use a different data
directory, log files, and PID file. (The defaults for all these values are
determined relative to the base directory). In that case, the only other
options you need to specify are the @code{--socket} and @code{--port}
options.  For example, suppose that you install different versions of MySQL using
@file{tar} file binary distributions. These will install in different
locations, so you can start the server for each installation using the
command @command{bin/mysqld_safe} under its corresponding base directory.
@command{mysqld_safe} will determine the proper
@code{--basedir} option to pass to @command{mysqld}, and you need specify
only the @code{--socket} and @code{--port} options to @command{mysqld_safe}.
(For versions of MySQL older than 4.0, use @command{safe_mysqld}
rather than @command{mysqld_safe}.)

As discussed in the following sections, it is possible to start additional
servers by setting environment variables or by specifying appropriate
command-line options.  However, if you need to run multiple servers on
a more permanent basis, it will be more convenient to use option files
to specify for each server those option values that must be unique to it.


@node Multiple Windows servers, Multiple Unix servers, Multiple servers, Multiple servers
@subsection Running Multiple Servers on Windows

You can run multiple servers on Windows by starting them manually from the
command line, each with appropriate operating parameters. On Windows NT-based
systems, you also have the option of installing several servers as Windows services
and running them that way. General instructions for running MySQL servers
from the command line or as services are given in @ref{Windows installation}. This section
describes how to make sure that you start each server with different values for
those startup options that must be unique per server, such as the data
directory.  These options are described in @ref{Multiple servers}.

@menu
* Multiple Windows command-line servers::  Starting Multiple Windows Servers at the Command Line
* Multiple Windows services::   Starting Multiple Windows Servers as Services
@end menu

@node Multiple Windows command-line servers, Multiple Windows services, Multiple Windows servers, Multiple Windows servers
@subsubsection Starting Multiple Windows Servers at the Command Line

To start multiple servers manually from the command line, you can specify the appropriate options on
the command line or in an option file. It's more convenient to place the
options in an option file, but it's necessary to make sure that each server
gets its own set of options. To do this, create an option file for each
server and tell the server the filename with a @code{--defaults-file} option
when you run it.

Suppose that you want to run @command{mysqld} on port 3307 with a
data directory of @file{C:\mydata1}, and @command{mysqld-max} on port 3308 with a
data directory of @file{C:\mydata2}. (To do this, make sure that before you
start the servers, each data directory exists and has its own copy of the
@code{mysql} database that contains the grant tables.)

Then create two option
files. For example, create one file named @file{C:\my-opts1.cnf} that looks
like this:

@example
[mysqld]
datadir = C:/mydata1
port = 3307
@end example

Create a second file named @file{C:\my-opts2.cnf} that looks like this:

@example
[mysqld]
datadir = C:/mydata2
port = 3308
@end example

Then start each server with its own option file:

@example
C:\> C:\mysql\bin\mysqld --defaults-file=C:\my-opts1.cnf
C:\> C:\mysql\bin\mysqld-max --defaults-file=C:\my-opts2.cnf
@end example

On NT, each server will start in the foreground (no new prompt appears until
the server exits later); you'll need to issue those two commands in separate
console windows.

To shut down the servers, you must connect to the appropriate port number:

@example
C:\> C:\mysql\bin\mysqladmin --port=3307 shutdown
C:\> C:\mysql\bin\mysqladmin --port=3308 shutdown
@end example

Servers configured as just described will allow clients to connect over
TCP/IP.  If your version of Windows supports named pipes and you also want
to allow named pipe connections, use the @command{mysqld-nt} or
@command{mysqld-max-nt} servers and specify options that enable the named pipe
and specify its name. Each server that supports named pipe connections must
use a unique pipe name.  For example, the @file{C:\my-opts1.cnf} file might
be written like this:

@example
[mysqld]
datadir = C:/mydata1
port = 3307
enable-named-pipe
socket = mypipe1
@end example

Then start the server this way:

@example
C:\> C:\mysql\bin\mysqld-nt --defaults-file=C:\my-opts1.cnf
@end example

Modify @file{C:\my-opts2.cnf} similarly for use by the second server.

@node Multiple Windows services,  , Multiple Windows command-line servers, Multiple Windows servers
@subsubsection Starting Multiple Windows Servers as Services

On NT-based systems, a MySQL server can be run as a Windows service. The
procedures for installing, controlling, and removing a single MySQL service are
described in @ref{Windows start service}.

As of MySQL 4.0.2, you can install multiple servers as services.
In this case, you must make sure that each server uses a different
service name in addition to all the other parameters that must be unique per
server.

For the following instructions, assume that you want to run the @command{mysqld-nt}
server from two different versions of MySQL that are installed at
@file{C:\mysql-4.0.8} and @file{C:\mysql-4.0.17}, respectively. (This might be
the case if you're running 4.0.8 as your production server, but want to test
4.0.17 before upgrading to it.)

The following principles apply when installing a MySQL service with the
@code{--install} or @code{--install-manual} option:

@itemize @bullet

@item
If you specify no service name, the server uses the default service name of
@code{MySQL} and the server reads options from the @code{[mysqld]} group in
the standard option files.

@item
@c TODO change this back after bug gets fixed
@c If you specify a service name different than @code{MySQL} after the
If you specify a service name after the
@code{--install} option, the server ignores the @code{[mysqld]} option
group and instead reads options from the group that has the same name as the
service. The server reads options from the standard option files.

@item
If you specify a @code{--defaults-file} option after the service name,
the server ignores the standard option files and reads options only from the
@code{[mysqld]} group of the named file.

@end itemize

@strong{Note}: Before MySQL 4.0.17, only a server installed using the default service
name (@code{MySQL}) or one installed explicitly with a service name of
@command{mysqld} will read the @code{[mysqld]} group in the standard option
files. As of 4.0.17, all servers read the @code{[mysqld]} group if they read
the standard option files, even if they are installed using another service
name. This allows you to use the @code{[mysqld]} group for options that should
be used by all MySQL services, and an option group named after each service
for use by the server installed with that service name.

@c TODO:
@c The following should, I think, be uncommented when the bug is fixed? -- PD
@c (The exception is that if you use an explicit service name of @code{MySQL}
@c or any lettercase variation thereof, only the @code{[mysqld]} group is
@c read. This is because option group names are not case sensitive, and the
@c @code{[mysql]} group is to be used by the @command{mysql} client program, not
@c by any server.)

Based on the preceding information, you have several ways to set
up multiple services.  The following instructions describe some
examples. Before trying any of them, be sure that you shut down and
remove any existing MySQL services first.

@itemize @bullet

@item
@strong{Approach 1:}
Specify the options for all services in one of the standard option files.
To do this, use a different service name for each server.
Suppose that you want to run the 4.0.8 @command{mysqld-nt} using the service
name of @code{mysqld1} and the 4.0.17 @command{mysqld-nt} using the service name @code{mysqld2}.
In this case, you can use the @code{[mysqld1]} group for 4.0.8 and the
@code{[mysqld2]} group for 4.0.17.
For example, you can set up @file{C:\my.cnf} like this:

@example
# options for mysqld1 service
[mysqld1]
basedir = C:/mysql-4.0.8
port = 3307
enable-named-pipe
socket = mypipe1

# options for mysqld2 service
[mysqld2]
basedir = C:/mysql-4.0.17
port = 3308
enable-named-pipe
socket = mypipe2
@end example

Install the services as follows, using the full server pathnames to ensure
that Windows registers the correct executable program for each service:

@example
C:\> C:\mysql-4.0.8\bin\mysqld-nt --install mysqld1
C:\> C:\mysql-4.0.17\bin\mysqld-nt --install mysqld2
@end example

To start the services, use the services manager, or use @command{NET START}
with the appropriate service names:

@example
C:\> NET START mysqld1
C:\> NET START mysqld2
@end example

To stop the services, use the services manager, or use @command{NET STOP}
with the appropriate service names:

@example
C:\> NET STOP mysqld1
C:\> NET STOP mysqld2
@end example

@item
@strong{Approach 2:}
Specify options for each server in separate files and use
@code{--defaults-file} when you install the services to tell each server
what file to use.  In this case, each file should list options using a
@code{[mysqld]} group.

With this approach, to specify options for the 4.0.8 @command{mysqld-nt},
create a file @file{C:\my-opts1.cnf} that looks like this:

@example
[mysqld]
basedir = C:/mysql-4.0.8
port = 3307
enable-named-pipe
socket = mypipe1
@end example

For the 4.0.17 @command{mysqld-nt}, create a file
@file{C:\my-opts2.cnf} that looks like this:

@example
[mysqld]
basedir = C:/mysql-4.0.17
port = 3308
enable-named-pipe
socket = mypipe2
@end example

Install the services as follows (enter each command on a single line):

@example
C:\> C:\mysql-4.0.8\bin\mysqld-nt --install mysqld1
           --defaults-file=C:\my-opts1.cnf
C:\> C:\mysql-4.0.17\bin\mysqld-nt --install mysqld2
           --defaults-file=C:\my-opts2.cnf
@end example

To use a @code{--defaults-file} option when you install a MySQL server as a
service, you must precede the option with the service name.

After installing the services, start and stop them the same way as in the
preceding example.

@end itemize

To remove multiple services, use @command{mysqld --remove} for each one,
specifying a service name following the @code{--remove} option. If the
service name is the default (@code{MySQL}), you can omit it.


@node Multiple Unix servers, Multiple-server clients, Multiple Windows servers, Multiple servers
@subsection Running Multiple Servers on Unix

The easiest way is to run multiple servers on Unix is to compile them
with different TCP/IP ports and Unix socket files so that each one is listening on
different network interfaces. Also, by compiling in different base directories
for each installation, that automatically results in different compiled-in
data directory, log file, and PID file locations for each of your servers.

Assume that an existing server is configured for the default TCP/IP port
number (3306) and Unix socket file (@file{/tmp/mysql.sock}).  To configure a
new server to have different operating parameters, use a @command{configure}
command something like this:

@example
shell> ./configure --with-tcp-port=@var{port_number} \
             --with-unix-socket-path=@var{file_name} \
             --prefix=/usr/local/mysql-4.0.17
@end example

Here, @var{port_number} and @var{file_name} must be different from the
default TCP/IP port number and Unix socket file pathname, and the
@code{--prefix} value should specify an installation directory different
than the one under which the existing MySQL installation is located.

If you have a MySQL server listening on a given port number, you can use the
following command to find out what operating parameters it is using for
several important configurable variables, including the base directory and
Unix socket filename:

@example
shell> mysqladmin --host=@var{host_name} --port=@var{port_number} variables
@end example

With the information displayed by that command, you can tell what option
values @emph{not} to use when configuring an additional server.

Note that if you specify @code{localhost} as a hostname, @command{mysqladmin}
will default to using a Unix socket file connection rather than TCP/IP.
In MySQL 4.1, you can explicitly specify the connection protocol to use by
using the @code{--protocol=@{TCP | SOCKET | PIPE | MEMORY@}} option.

You don't have to compile a new MySQL server just to start with a different
Unix socket file and TCP/IP port number.  It is also possible to specify
those values at runtime. One way to do so is by using command-line options:

@example
shell> mysqld_safe --socket=@var{file_name} --port=@var{port_number}
@end example

To start a second server, provide different @code{--socket} and
@code{--port} option values, and pass a a @code{--datadir=@var{path}} option to
@command{mysqld_safe} so that the server uses a different data directory.

Another way to achieve a similar effect is to use environment variables
to set the Unix socket filename and TCP/IP port number:

@tindex @code{MYSQL_UNIX_PORT} environment variable
@tindex @code{MYSQL_TCP_PORT} environment variable
@tindex environment variable, @code{MYSQL_UNIX_PORT}
@tindex environment variable, @code{MYSQL_TCP_PORT}
@example
shell> MYSQL_UNIX_PORT=/tmp/mysqld-new.sock
shell> MYSQL_TCP_PORT=3307
shell> export MYSQL_UNIX_PORT MYSQL_TCP_PORT
shell> mysql_install_db --user=mysql
shell> mysqld_safe --datadir=/path/to/datadir &
@end example

This is a quick way of starting a second server to use
for testing.  The nice thing about this method is that the environment
variable settings will apply to any client programs that you invoke from
the same shell. Thus, connections for those clients automatically will
be directed to the second server!

@ref{Environment variables} includes a list of other environment
variables you can use to affect @command{mysqld}.

For automatic server execution, your startup script that is executed
at boot time should execute the following command once for each
server with an appropriate option file path for each command:

@example
mysqld_safe --defaults-file=path
@end example

Each option file should contain option values specific to a given server.

On Unix,
the @command{mysqld_multi} script is another way to start multiple servers.
@xref{mysqld_multi, , @command{mysqld_multi}}.


@node Multiple-server clients,  , Multiple Unix servers, Multiple servers
@subsection Using Client Programs in a Multiple-Server Environment

When you want to connect with a client program to a MySQL server that is
listening to different network interfaces than those compiled into your
client, you can use one of the following methods:

@itemize @bullet
@item
Start the client with @code{--host=@var{host_name} --port=@var{port_number}} to connect
via TCP/IP to a remote server, with @code{--host=127.0.0.1
--port=port_number} to connect via TCP/IP to a local server, or with
@code{--host=localhost --socket=@var{file_name}} to connect to a local server via
a Unix socket file or a Windows named pipe.

@item
As of MySQL 4.1, start the client with @code{--protocol=tcp} to connect
via TCP/IP, @code{--protocol=socket} to connect via a Unix socket file,
@code{--protocol=pipe} to connect via a named pipe, or
@code{--protocol=memory} to connect via shared memory.  For TCP/IP
connections, you may also need to specify @code{--host} and @code{--port}
options.  For the other types of connections, you may need to specify
a @code{--socket} option to specify a Unix socket file or named pipe name, or a
@code{--shared-memory-base-name} option to specify the shared memory name.
Shared memory connections are supported only on Windows.

@item
@tindex MYSQL_UNIX_PORT environment variable
@tindex MYSQL_TCP_PORT environment variable
@tindex environment variable, MYSQL_UNIX_PORT
@tindex environment variable, MYSQL_TCP_PORT
On Unix, set the @code{MYSQL_UNIX_PORT} and @code{MYSQL_TCP_PORT}
environment variables to point to the Unix socket file and TCP/IP port
number before you start your clients.  If you normally use a specific socket
file or port number, you can place commands to set these environment
variables in your @file{.login} file so that they apply each time you log
in.
@xref{Environment variables}.

@item
@tindex C:\my.cnf file
@tindex .my.cnf file
Specify the default Unix socket file and TCP/IP port number in the
@code{[client]} group of an option file. For example, you can use
@file{C:\my.cnf} on Windows, or the @file{.my.cnf} file in your home
directory on Unix.
@xref{Option files}.

@item
In a C program, you can specify the socket file or port number arguments in the
@code{mysql_real_connect()} call.  You can also have the program read
option files by calling @code{mysql_options()}.
@xref{C API functions}.

@item
If you are using the Perl @code{DBD::mysql} module, you can read options
from MySQL option files. For example:

@example
$dsn = "DBI:mysql:test;mysql_read_default_group=client;"
        . "mysql_read_default_file=/usr/local/mysql/data/my.cnf";
$dbh = DBI->connect($dsn, $user, $password);
@end example

@xref{Perl}.

Other programming interfaces may provide similar capabilities for reading
option files.

@end itemize


@node Query Cache,  , Multiple servers, MySQL Database Administration
@section The MySQL Query Cache

@cindex Query Cache
@cindex @code{SELECT}, Query Cache

From version 4.0.1 on, MySQL Server features a query cache.
When in use, the query cache stores the text of a @code{SELECT} query
together with the corresponding result that was sent to the client.
If the identical query is received later, the server retrieves
the results from the query cache rather than parsing and executing the
query again.

The query cache is extremely useful in an environment where (some)
tables don't change very often and you have a lot of identical queries.
This is a typical situation for many Web servers that generate a lot of
dynamic pages based on database content.

@strong{Note}: The query cache does not return stale data. When tables
are modified, any relevant entries in the query cache are flushed.

@strong{Note}: The query cache does not work in an environment where you
have many @command{mysqld} servers updating the same @code{MyISAM} tables.

Some performance data for the query cache follow. These results were 
generated by running the MySQL benchmark suite on a Linux Alpha
2 x 500MHz system with 2GB RAM and a 64MB query cache.

@itemize @bullet

@item
If all the queries you're performing are simple (such as selecting a row
from a table with one row), but still differ so that the queries cannot be
cached, the overhead for having the query cache active is 13%.  This could
be regarded as the worst case scenario. In real life, queries tend to be
much more complicated, so the overhead normally is significantly lower.

@item
Searches for a single row in a single-row table are 238% faster with the
query cache than without it.  This can be regarded as close to the minimum
speedup to be expected for a query that is cached.

@end itemize

To disable the query cache at server startup, set the
@code{query_cache_size} system variable to 0.  By disabling the query cache
code, there is no noticeable overhead.  Query cache capabilities can be
excluded from the server entirely by using the @code{--without-query-cache}
option to @command{configure} when compiling MySQL.

@menu
* Query Cache How::             How the Query Cache Operates
* Query Cache in SELECT::       Query Cache @code{SELECT} Options
* Query Cache Configuration::   Query Cache Configuration
* Query Cache Status and Maintenance::  Query Cache Status and Maintenance
@end menu


@node Query Cache How, Query Cache in SELECT, Query Cache, Query Cache
@subsection How the Query Cache Operates

This section describes how the query cache works when it is operational.
@ref{Query Cache Configuration} describes how to control whether or not it
is operational.

Queries are compared before parsing, so the following two queries are
regarded as different by the query cache:

@example
SELECT * FROM @var{tbl_name}
Select * from @var{tbl_name}
@end example

Queries must be exactly the same (byte for byte) to be seen as identical.
In addition, query strings that are identical may be treated as different
for other reasons.  Queries that use different databases, different protocol
versions, or different default character sets are considered different
queries and are cached separately.

If a query result is returned from query cache, the server increments the
@code{Qcache_hits} status variable, not @code{Com_select}.
@xref{Query Cache Status and Maintenance}.

If a table changes, then all cached queries that use the table become
invalid and are removed from the cache.  This includes queries that use
@code{MERGE} tables that map to the changed table.  A table can be changed
by many types of statements, such as @code{INSERT}, @code{UPDATE},
@code{DELETE}, @code{TRUNCATE}, @code{ALTER TABLE}, @code{DROP TABLE}, or
@code{DROP DATABASE}.

Transactional @code{InnoDB} tables that have been changed are invalidated
when a @code{COMMIT} is performed.

In MySQL 4.0, the query cache is disabled within transactions (it does
not return results). Beginning with MySQL 4.1.1, the query cache also
works within transactions when using @code{InnoDB} tables (it uses the
table version number to detect whether or not its contents are still current).

Before MySQL 5.0, a query that begins with a leading comment might be cached,
but could not be fetched from the cache. This problem is fixed in MySQL 5.0.

The query cache works for @code{SELECT SQL_CALC_FOUND_ROWS ...} and
@code{SELECT FOUND_ROWS()} type queries.  @code{FOUND_ROWS()} returns
the correct value even if the preceding query was fetched from the cache
because the number of found rows is also stored in the cache.

A query cannot be cached if it contains any of the following functions:

@multitable @columnfractions .33 .33 .34
@item @code{BENCHMARK()}
 @tab @code{CONNECTION_ID()}
 @tab @code{CURDATE()}
@item @code{CURRENT_DATE()}
 @tab @code{CURRENT_TIME()}
 @tab @code{CURRENT_TIMESTAMP()}
@item @code{CURTIME()}
 @tab @code{DATABASE()}
 @tab @code{ENCRYPT()} with one parameter
@item @code{FOUND_ROWS()}
 @tab @code{GET_LOCK()}
 @tab @code{LAST_INSERT_ID()}
@item @code{LOAD_FILE()}
 @tab @code{MASTER_POS_WAIT()}
 @tab @code{NOW()}
@item @code{RAND()}
 @tab @code{RELEASE_LOCK()}
 @tab @code{SYSDATE()}
@item @code{UNIX_TIMESTAMP()} with no parameters
 @tab @code{USER()}
@end multitable

A query also will not be cached under these conditions:

@itemize @bullet
@item
It contains user-defined functions (UDFs).

@item
It contains user variables.

@item
It refers to the tables in the @code{mysql} system database.

@item
It is of any of the following forms:

@example
SELECT ... IN SHARE MODE
SELECT ... INTO OUTFILE ...
SELECT ... INTO DUMPFILE ...
SELECT * FROM ... WHERE autoincrement_col IS NULL
@end example

The last form is not cached because it is used as the ODBC workaround for
obtaining the last insert ID value.
@xref{ODBC and last_insert_id}.

@item
It uses @code{TEMPORARY} tables.

@item
It does not use any tables.

@item
The user has a column-level privilege for any of the involved tables.

@item
Before a query is fetched from the query cache, MySQL checks that
the user has @code{SELECT} privilege for all the involved databases and
tables. If this is not the case, the cached result is not used.

@end itemize


@node Query Cache in SELECT, Query Cache Configuration, Query Cache How, Query Cache
@subsection Query Cache @code{SELECT} Options

There are two query cache-related options that may be
specified in a @code{SELECT} statement:

@findex SQL_CACHE
@findex SQL_NO_CACHE

@table @code

@item SQL_CACHE
The query result is cached if the value of the @code{query_cache_type}
system variable is @code{ON} or @code{DEMAND}.

@item SQL_NO_CACHE
The query result is not cached.

@end table

Examples:

@example
SELECT SQL_CACHE id, name FROM customer;
SELECT SQL_NO_CACHE id, name FROM customer;
@end example


@node Query Cache Configuration, Query Cache Status and Maintenance, Query Cache in SELECT, Query Cache
@subsection Query Cache Configuration

The @code{have_query_cache} server system variable indicates whether the query
cache is available:

@example
mysql> SHOW VARIABLES LIKE 'have_query_cache';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| have_query_cache | YES   |
+------------------+-------+
@end example

Several other system variables control query cache operation.
These can be set in an option file or on the command line
when starting @command{mysqld}.
The query cache-related system variables all have names that begin with
@code{query_cache_}. They are described briefly in @ref{Server system
variables}, with additional configuration information given here.

To set the size of the query cache, set the @code{query_cache_size} system
variable. Setting it to 0 disables the query cache. The default cache size
is 0; that is, the query cache is disabled.

If the query cache is enabled, the @code{query_cache_type} variable
influences how it works. This variable can be set to the following values:

@itemize @bullet
@item
A value of @code{0} or @code{OFF} prevents caching or retrieval of cached
results.

@item
A value of @code{1} or @code{ON} allows caching except of those statements
that begin with @code{SELECT SQL_NO_CACHE}.

@item
A value of @code{2} or @code{DEMAND} causes caching of only those statements
that begin with @code{SELECT SQL_CACHE}.

@end itemize

Setting the @code{GLOBAL} value of @code{query_cache_type} determines query
cache behavior for all clients that connect after the change is made.
Individual clients can control cache behavior for their own connection by
setting the @code{SESSION} value of @code{query_cache_type}. For example, a
client can disable use of the query cache for its own queries like this:

@example
mysql> SET SESSION query_cache_type = OFF;
@end example

To control the maximum size of individual query results that can be cached,
set the @code{query_cache_limit} variable. The default value is 1MB.

The result of a query (the data sent to the client) is stored in the query
cache during result retrieval. Therefore the data usually is not handled in
one big chunk. The query cache allocates blocks for storing this data on
demand, so when one block is filled, a new block is allocated.  Because
memory allocation operation is costly (timewise), the query cache allocates
blocks with a minimum size given by the @code{query_cache_min_res_unit}
system variable.  When a query is executed, the last result block is trimmed
to the actual data size so that unused memory is freed.
Depending on the types of queries your server executes, you might find it
helpful to tune the value of @code{query_cache_min_res_unit}:

@itemize @bullet

@item
The default value of @code{query_cache_min_res_unit} is 4KB. This should
be adequate for most cases.

@item
If you have a lot of queries with small results, the default block size may
lead to memory fragmentation, as indicated by a large number of free blocks.
Fragmentation can force the query cache to prune (delete) queries from the
cache due to lack of memory.  In this case, you should decrease the value of
@code{query_cache_min_res_unit}.  The number of free blocks and queries
removed due to pruning are given by the values of the
@code{Qcache_free_blocks} and @code{Qcache_lowmem_prunes} status variables.

@item
If most of your queries have large results (check the
@code{Qcache_total_blocks} and @code{Qcache_queries_in_cache} status
variables), you can increase performance by increasing
@code{query_cache_min_res_unit}. However, be careful to not make it too
large (see the previous item).

@end itemize

@code{query_cache_min_res_unit} is present from MySQL 4.1.


@node Query Cache Status and Maintenance,  , Query Cache Configuration, Query Cache
@subsection Query Cache Status and Maintenance

@c help_category Administration

You can check whether the query cache is present in your MySQL server using
the following statement:

@example
mysql> SHOW VARIABLES LIKE 'have_query_cache';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| have_query_cache | YES   |
+------------------+-------+
@end example

@c description_for_help_topic FLUSH QUERY CACHE  CACHE QUERY FLUSH RESET
You can defragment the query cache to better utilize its memory
with the @code{FLUSH QUERY CACHE} statement.
The statement does not remove any queries from the cache.

The @code{RESET QUERY CACHE} statement removes all query results from the
query cache.  The @code{FLUSH TABLES} statement also does this.
@c end_description_for_help_topic

To monitor query cache performance, use @code{SHOW STATUS} to view
the cache status variables:

@example
mysql> SHOW STATUS LIKE 'Qcache%';
+-------------------------+--------+
| Variable_name           | Value  |
+-------------------------+--------+
| Qcache_free_blocks      | 36     |
| Qcache_free_memory      | 138488 |
| Qcache_hits             | 79570  |
| Qcache_inserts          | 27087  |
| Qcache_lowmem_prunes    | 3114   |
| Qcache_not_cached       | 22989  |
| Qcache_queries_in_cache | 415    |
| Qcache_total_blocks     | 912    |
+-------------------------+--------+
@end example

Descriptions of each of these variables are given in
@ref{Server status variables}.  Some uses for them are described here.

The total number of @code{SELECT} queries is equal to:

@example
  Com_select
+ Qcache_hits
+ queries with errors found by parser
@end example

The @code{Com_select} value is equal to:

@example
  Qcache_inserts
+ Qcache_not_cached
+ queries with errors found during columns/rights check
@end example

The query cache uses variable-length blocks, so @code{Qcache_total_blocks}
and @code{Qcache_free_blocks} may indicate query cache memory fragmentation.
After @code{FLUSH QUERY CACHE}, only a single free block remains.

Every cached query requires a minimum of two blocks (one for the query
text and one or more for the query results). Also, every table that is used
by a query requires one block. However, if two or more queries use the same
table, only one block needs to be allocated.

The information provided by the @code{Qcache_lowmem_prunes} status variable
can help you tune the query cache size. It counts the number of queries that
have been removed from the cache to free up memory for caching new queries.
The query cache uses a least recently used (LRU) strategy to decide which
queries to remove from the cache. Tuning information is given in @ref{Query
Cache Configuration}.


@node Replication, MySQL Optimization, MySQL Database Administration, Top
@chapter Replication in MySQL

@cindex replication
@cindex databases, replicating
@cindex increasing with replication, speed
@cindex speed, increasing with replication

@menu
* Replication Intro::           Introduction to Replication
* Replication Implementation::  Replication Implementation Overview
* Replication Implementation Details::  Replication Implementation Details
* Replication HOWTO::           How to Set Up Replication
* Replication Compatibility::   Replication Compatibility Between MySQL Versions
* Replication Upgrade::         Upgrading a Replication Setup
* Replication Features::        Replication Features and Known Problems
* Replication Options::         Replication Startup Options
* Replication FAQ::             Replication FAQ
* Replication Problems::        Troubleshooting Replication
* Replication Bugs::            Reporting Replication Bugs
@end menu

@c Need better intro summary of what the sections here are

Replication capabilities allowing the databases on one MySQL server to be
duplicated on another were introduced in MySQL 3.23.15.
This chapter describes the various replication features provided by MySQL.
It introduces replication concepts, shows how to set up replication servers,
and serves as a reference to the available replication options.
It also provides a list of
frequently asked questions (with answers), and troubleshooting advice for
solving problems.

For a description of the syntax of replication-related SQL statements, see
@ref{Replication SQL}.

We suggest that you visit our Web site at @uref{http://www.mysql.com}
often and read updates to this chapter. Replication is constantly being
improved, and we update the manual frequently with the most current
information.

@node Replication Intro, Replication Implementation, Replication, Replication
@section Introduction to Replication

MySQL 3.23.15 and up features support for one-way replication.
One server acts as the master, while one or more other servers
act as slaves.  The master server writes updates to its binary log files,
and maintains an index of the files to keep track of log rotation.  These logs
serve as a record of updates to be sent to slave servers.  When a
slave server connects to the master server, it informs the master of its last
position within the logs since the last successfully propagated update.
The slave catches up any updates that have occurred since then, and then
blocks and waits for the master to notify it of new updates.

A slave server can also serve as a master if you want to set up chained
replication servers.

Note that when you are using replication, all updates to the
tables that are replicated
should be performed on the master server. Otherwise, you must always be
careful to avoid conflicts between updates that users make to tables on the
master and updates that they make to tables on the slave.

One-way replication has benefits for robustness, speed, and system
administration:

@itemize @bullet

@item
Robustness is increased with a master/slave setup.
In the event of problems with the master, you can switch to the slave as a
backup.

@item
Better response time for clients can be achieved by splitting the load
for processing client queries between the master and slave servers.
@code{SELECT} queries may be sent to the slave to reduce the query
processing load of the master. Statements that modify data should still
be sent to the master so that the master and slave do not get out of sync.
This load-balancing strategy is effective if non-updating queries dominate,
but that is the normal case.

@item
Another benefit of using replication is that you can perform backups using a
slave server without disturbing the master. The master continues to process
updates while the backup is being made.
@xref{Backup}.

@end itemize


@node Replication Implementation, Replication Implementation Details, Replication Intro, Replication
@section Replication Implementation Overview

@cindex master/slave setup

MySQL replication is based on the master server keeping track of all changes
to your databases (updates, deletes, and so on) in the binary logs. Therefore,
to use replication, you must enable binary logging on the master server.
@xref{Binary log}.

Each slave server receives from the master the saved updates that the
master has recorded in its binary log, so that the slave can execute the
same updates on its copy of the data.

It is @strong{very important} to realize that the binary log is simply a
record starting from the fixed point in time at which you enable binary
logging. Any slaves that you set up will need copies of the databases on
your master as they existed at the moment you enabled binary
logging on the master. If you start your slaves with databases that are not the same
as what was on the master @strong{when the binary log was
started}, your slaves may fail.

One way to copy the master's data to the slave is to use the @code{LOAD
DATA FROM MASTER} statement.  Be aware that @code{LOAD DATA FROM MASTER}
is available only as of MySQL 4.0.0 and currently works only if all the
tables on the master are @code{MyISAM} type. Also, this statement acquires a
global read lock, so no updates on the master are possible while the tables
are being transferred to the slave. When we implement lock-free hot table
backup (in MySQL 5.0), this global read lock will no longer be necessary.

Due to these limitations, we recommend that at this point  you use
@code{LOAD DATA FROM MASTER} only if the dataset on the master is relatively
small, or if a prolonged read lock on the master is acceptable. While the
actual speed of @code{LOAD DATA FROM MASTER} may vary from system to system,
a good rule of thumb for how long it will take is 1 second per 1MB of data.
That is only a rough estimate, but you should get close to it if both
master and slave are equivalent to 700MHz Pentium performance and are
connected through a 100MBit/s network.

After the slave has been set up with a copy of the master's data, it
will simply connect to the master and wait for updates to process. If
the master goes away or the slave loses connectivity with your master,
it will keep trying to connect periodically until it is able to reconnect
and resume listening for updates. The retry interval is controlled by the
@code{--master-connect-retry} option. The default is 60 seconds.

Each slave keeps track of where it left off. The master server has no
knowledge of how many slaves there are or which ones are up to date at
any given time.


@node Replication Implementation Details, Replication HOWTO, Replication Implementation, Replication
@section Replication Implementation Details

@menu
* Master thread states::        Replication Master Thread States
* Slave I/O thread states::     Replication Slave I/O Thread States
* Slave SQL thread states::     Replication Slave SQL Thread States
* Slave logs::                  Replication Relay and Status Files
@end menu

MySQL replication capabilities are implemented using three threads (one
on the master server and two on the slave).  When @code{START SLAVE} is
issued, the slave creates an I/O thread.  The I/O thread connects to the
master and asks it to send the statements recorded in its binary logs. The
master creates a thread to send the binary log contents to the slave.
This thread can be identified as the @code{Binlog Dump} thread in the
output of @code{SHOW PROCESSLIST} on the master.  The slave I/O thread
reads what the master @code{Binlog Dump} thread sends and simply copies
it to some local files in the slave's data directory called relay logs.
The third thread is the SQL thread, which the slave creates to read the
relay logs and execute the updates they contain.

In the preceding description, there are three threads per slave. For a
master that has multiple slaves, it creates one thread for each currently
connected slave, and each slave has its own I/O and SQL threads.

For versions of MySQL before 4.0.2, replication involves only two threads
(one on the master and one on the slave). The slave I/O and SQL threads
are combined as a single thread, and no relay log files are used.

The advantage of using two slave threads is that statement reading and
execution are separated into two independent tasks. The task of reading
statements is not slowed down if statement execution is slow.  For example,
if the slave server has not been running for a while, its I/O thread can
quickly fetch all the binary log contents from the master when the slave starts,
even if the SQL thread lags far behind and may take hours to catch up.
If the slave stops before the SQL thread has executed all the fetched
statements, the I/O thread has at least fetched everything so that a
safe copy of the statements is locally stored in the slave's relay logs
for execution when next the slave starts. This allows the binary logs to be
purged on the master, because it no longer need wait for the slave to
fetch their contents.

The @code{SHOW PROCESSLIST} statement provides information that tells you
what is happening on the master and on the slave regarding replication.

The following example illustrates how the three threads show up in
@code{SHOW PROCESSLIST}.  The output format is that used by @code{SHOW
PROCESSLIST} as of MySQL version 4.0.15, when the content of the
@code{State} column was changed to be more meaningful compared to
earlier versions.

On the master server, the output from @code{SHOW PROCESSLIST} looks like this:

@example
mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
     Id: 2
   User: root
   Host: localhost:32931
     db: NULL
Command: Binlog Dump
   Time: 94
  State: Has sent all binlog to slave; waiting for binlog to
         be updated
   Info: NULL
@end example

Here, thread 2 is a replication thread for a connected slave. The information
indicates that all outstanding updates have been sent to the slave and that
the master is waiting for more updates to occur.

On the slave server, the output from @code{SHOW PROCESSLIST} looks like this:

@example
mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
     Id: 10
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 11
  State: Waiting for master to send event
   Info: NULL
*************************** 2. row ***************************
     Id: 11
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 11
  State: Has read all relay log; waiting for the slave I/O
         thread to update it
   Info: NULL
@end example

This information indicates that thread 10 is the I/O thread that is
communicating with the master server, and thread 11 is the SQL thread that
is processing the updates stored in the relay logs.  Currently, both threads
are idle, waiting for further updates.

Note that the value in the @code{Time} column can tell how late the slave
is compared to the master.
@xref{Replication FAQ}.


@node Master thread states, Slave I/O thread states, Replication Implementation Details, Replication Implementation Details
@subsection Replication Master Thread States

The following list shows the most common states you will see in the
@code{State} column for the master's @code{Binlog Dump} thread. If you
don't see any @code{Binlog Dump} threads on a master server, replication
is not running. That is, no slaves currently are connected.

@table @code

@item Sending binlog event to slave

Binary logs consist of events, where an event is usually an update statement
plus some other information. The thread has read an event from the binary
log and is sending it to the slave.

@item Finished reading one binlog; switching to next binlog

The thread has finished reading a binary log file and is opening
the next one to send to the slave.

@item Has sent all binlog to slave; waiting for binlog to be updated

The thread has read all outstanding updates from the binary logs and sent
them to the slave. It is idle, waiting for new events to appear in the
binary log resulting from new update statements being executed on the master.

@item Waiting to finalize termination

A very brief state that occurs as the thread is stopping.

@end table


@node Slave I/O thread states, Slave SQL thread states, Master thread states, Replication Implementation Details
@subsection Replication Slave I/O Thread States

The following list shows the most common states you will see in the
@code{State} column for a slave server I/O thread. Beginning with MySQL
4.1.1, this state also appears in the @code{Slave_IO_State} column displayed
by the @code{SHOW SLAVE STATUS} statement. This means that you can get a
good view of what is happening by using only @code{SHOW SLAVE STATUS}.

@table @code

@item Connecting to master

The thread is attempting to connect to the master.

@item Checking master version

A very brief state that occurs just after the connection to the master
is established.

@item Registering slave on master

A very brief state that occurs just after the connection to the master
is established.

@item Requesting binlog dump

A very brief state that occurs just after the connection to the master is
established.  The thread sends to the master a request for the contents
of its binary logs, starting from the requested binary log filename and
position.

@item Waiting to reconnect after a failed binlog dump request

If the binary log dump request failed (due to disconnection), the
thread goes into this state while it sleeps, then tries to reconnect
periodically. The interval between retries can
be specified using the
@code{--master-connect-retry} option.

@item Reconnecting after a failed binlog dump request

The thread is trying to reconnect to the master.

@item Waiting for master to send event

The thread has connected to the master and is waiting for binary log events
to arrive. This can last for a long time if the master is idle. If the
wait lasts for @code{slave_read_timeout} seconds, a timeout will occur.
At that point, the thread will consider the connection to be broken and
make an attempt to reconnect.

@item Queueing master event to the relay log

The thread has read an event and is copying it to the relay log so that the SQL
thread can process it.

@item Waiting to reconnect after a failed master event read

An error occurred while reading (due to disconnection). The thread is sleeping
for @code{master-connect-retry} seconds before attempting to reconnect.

@item Reconnecting after a failed master event read

The thread is trying to reconnect to the master. When connection is established
again, the state will become @code{Waiting for master to send event}.

@item Waiting for the slave SQL thread to free enough relay log space

You are using a non-zero @code{relay_log_space_limit} value, and the relay
logs have grown so much that their combined size exceeds this value.
The I/O thread is waiting until the SQL
thread frees enough space by processing relay log contents so that it can
delete some relay log files.

@item Waiting for slave mutex on exit

A very brief state that occurs as the thread is stopping.

@end table


@node Slave SQL thread states, Slave logs, Slave I/O thread states, Replication Implementation Details
@subsection Replication Slave SQL Thread States

The following list shows the most common states you will see in the
@code{State} column for a slave server SQL thread:

@table @code

@item Reading event from the relay log

The thread has read an event from the relay log so that it can process it.

@item Has read all relay log; waiting for the slave I/O thread to update it

The thread has processed all events in the relay log files and is waiting for
the I/O thread to write new events to the relay log.

@item Waiting for slave mutex on exit

A very brief state that occurs as the thread is stopping.

@end table

The @code{State} column for the I/O thread may also show the text of
a statement.  This indicates that the thread has read an event from the
relay log, extracted the statement from it, and is executing it.


@node Slave logs,  , Slave SQL thread states, Replication Implementation Details
@subsection Replication Relay and Status Files

By default, relay logs are named using filenames of the form
@file{@var{host_name}-relay-bin.@var{nnnnnn}}, where @var{host_name} is the name of the
slave server host and @var{nnnnnn} is a sequence number.
Successive relay log files are created using successive sequence numbers,
beginning with @code{000001} (@code{001} in MySQL 4.0 or older).
The slave keeps track of relay logs currently in use in an index file.
The default relay log index filename is
@file{@var{host_name}-relay-bin.index}.
By default, these files are created in the slave's data directory.
The default filenames may be overridden with the @code{--relay-log} and
@code{--relay-log-index} server options.
@xref{Replication Options}.

Relay logs have the same format as binary logs, so you can use
@command{mysqlbinlog} to read them.  A relay log is automatically deleted by
the SQL thread as soon as it has executed all its events and no longer needs
it). There is no explicit mechanism for deleting relay logs, because the SQL
thread takes care of doing so. However, from MySQL 4.0.14, @code{FLUSH LOGS}
rotates relay logs, which will influence when the SQL thread deletes them.

A new relay log is created under the following conditions:

@itemize @bullet

@item
When the I/O thread starts for the first time
after the slave server starts.
(In MySQL 5.0, a new relay log is created each time the I/O thread
starts, not just the first time.)

@item
When the logs are flushed; for example, with @code{FLUSH LOGS} or
@command{mysqladmin flush-logs}. (This creates a new relay log only as of MySQL
4.0.14.)

@item
When the size of the current relay log file becomes too large. The meaning of
``too large'' is determined as follows:
@itemize @minus
@item
@code{max_relay_log_size}, if @code{max_relay_log_size} > 0
@item
@code{max_binlog_size}, if @code{max_relay_log_size} = 0
or MySQL is older than 4.0.14
@end itemize

@end itemize

A slave replication server creates two additional small files in the
data directory.  These are status files and are named @file{master.info}
and @file{relay-log.info} by default.  They contain information like
that shown in the output of the @code{SHOW SLAVE STATUS} statement
(@pxref{Replication Slave SQL} for a description of this statement).
As disk files, they survive a slave server's shutdown. The next time the
slave starts up, it reads these files to determine how far it has proceeded
in reading binary logs from the master and in processing its own relay logs.

The @file{master.info} file is updated by the I/O thread.
Before MySQL 4.1,
the correspondence between the lines in the file and the
columns displayed by @code{SHOW SLAVE STATUS} is as follows:

@multitable @columnfractions .15 .85
@item @strong{Line} @tab @strong{Description}
@item 1              @tab @code{Master_Log_File}
@item 2              @tab @code{Read_Master_Log_Pos}
@item 3              @tab @code{Master_Host}
@item 4              @tab @code{Master_User}
@item 5              @tab Password (not shown by @code{SHOW SLAVE STATUS})
@item 6              @tab @code{Master_Port}
@item 7              @tab @code{Connect_Retry}
@end multitable

As of MySQL 4.1, the file includes a line count and information about
SSL options:

@multitable @columnfractions .15 .85
@item @strong{Line} @tab @strong{Description}
@item 1              @tab Number of lines in the file
@item 2              @tab @code{Master_Log_File}
@item 3              @tab @code{Read_Master_Log_Pos}
@item 4              @tab @code{Master_Host}
@item 5              @tab @code{Master_User}
@item 6              @tab Password (not shown by @code{SHOW SLAVE STATUS})
@item 7              @tab @code{Master_Port}
@item 8              @tab @code{Connect_Retry}
@item 9              @tab @code{Master_SSL_Allowed}
@item 10              @tab @code{Master_SSL_CA_File}
@item 11              @tab @code{Master_SSL_CA_Path}
@item 12              @tab @code{Master_SSL_Cert}
@item 13              @tab @code{Master_SSL_Cipher}
@item 14              @tab @code{Master_SSL_Key}
@end multitable

The @file{relay-log.info} file is updated by the SQL thread.
The correspondence between the lines in the file and the
columns displayed by @code{SHOW SLAVE STATUS} is as follows:

@multitable @columnfractions .15 .85
@item @strong{Line} @tab @strong{Description}
@item 1              @tab @code{Relay_Log_File}
@item 2              @tab @code{Relay_Log_Pos}
@item 3              @tab @code{Relay_Master_Log_File}
@item 4              @tab @code{Exec_Master_Log_Pos}
@end multitable

@c TODO: This stuff about backups is out of place. We haven't even
@c described how to set up replication yet, much less worry about backups.
@c Create a new Backup Issues within this chapter?

When you back up your slave's data, you should back up these two small files
as well, along with the relay log files. They are needed to resume
replication after you restore the slave's data.  If you lose the relay logs
but still have the @file{relay-log.info} file, you can check it to determine
how far the SQL thread has executed in the master binary logs. Then you
can use @code{CHANGE MASTER TO} with the @code{MASTER_LOG_FILE} and
@code{MASTER_LOG_POS} options to tell the slave to re-read the binary
logs from that point.  This requires that the binary logs still exist on
the master server.

If your slave is subject to replicating @code{LOAD DATA INFILE} statements,
you should also back up any @file{SQL_LOAD-*} files that exist in the
directory that the slave uses for this purpose.  The slave needs these files
to resume replication of any interrupted @code{LOAD DATA INFILE} operations.
The directory location is specified using the @code{--slave-load-tmpdir}
option.  Its default value, if not specified, is the value of the @code{tmpdir}
variable.

@node Replication HOWTO, Replication Compatibility, Replication Implementation Details, Replication
@section How to Set Up Replication

@c TODO: somewhere mention in here that --slave-load-tmpdir should be set
@c to a disk-based directory that isn't cleared when machine restarts.
@c /tmp not a good choice.

Here is a quick description of how to set up complete replication of
your current MySQL server. It assumes that you want to replicate all
your databases and have not configured replication before. You will need
to shut down your master server briefly to complete the steps outlined
here.

The procedure is written in terms of setting up a single slave, but you can
use it to set up multiple slaves.

While this method is the most straightforward way to set up a slave,
it is not the only one. For example, if you already have a snapshot
of the master's data, and
the master already has its server ID set and binary logging enabled, you can
set up a slave without shutting down the master or even blocking updates to it.
For more details, please see @ref{Replication FAQ}.

If you want to administer a MySQL replication setup, we suggest that
you read this entire chapter through and try all statements mentioned in
@ref{Replication Master SQL} and @ref{Replication Slave SQL}.  You should
also familiarize yourself with replication startup options described in
@ref{Replication Options}.

Note that this procedure and some of the replication SQL statements
in later sections refer to the @code{SUPER} privilege. Prior to MySQL
4.0.2, use the @code{PROCESS} privilege instead.

@enumerate
@item
Make sure that you have a recent version of MySQL installed on the master
and slaves, and that these versions are compatible according to the table
shown in @ref{Replication Compatibility}.

Please do not report bugs until you have verified that the problem is present
in the latest release.

@item
Set up an account on the master server that the slave server can use to
connect. This account must be given the @code{REPLICATION SLAVE} privilege.
If the account is used only for replication
(which is recommended), you don't need to grant any additional privileges.

Suppose that your domain is @code{mydomain.com} and you want to create an
account with a username of @code{repl} such that slave servers can use the
account to access the master server from any host in your domain using a
password of @code{slavepass}.
To create the account, this use @code{GRANT} statement:

@example
mysql> GRANT REPLICATION SLAVE ON *.*
    -> TO 'repl'@@'%.mydomain.com' IDENTIFIED BY 'slavepass';
@end example

For MySQL versions older than 4.0.2, the @code{REPLICATION SLAVE} privilege
does not exist. Grant the @code{FILE} privilege instead:

@example
mysql> GRANT FILE ON *.*
    -> TO 'repl'@@'%.mydomain.com' IDENTIFIED BY 'slavepass';
@end example

If you plan to use the @code{LOAD TABLE FROM MASTER} or @code{LOAD DATA
FROM MASTER} statements from the slave host, you will need to grant this
account additional privileges:

@itemize @bullet

@item
Grant the account the @code{SUPER} and @code{RELOAD} global privileges.

@item
Grant the @code{SELECT} privilege for all tables that
you want to load. Any master tables from which the account cannot
@code{SELECT} will be ignored by @code{LOAD DATA FROM MASTER}.
@end itemize

@item
If you are using only @code{MyISAM} tables, flush all the tables and block
write statements by executing a @code{FLUSH TABLES WITH READ LOCK} statement.

@example
mysql> FLUSH TABLES WITH READ LOCK;
@end example

Leave the client running from which you issue the @code{FLUSH TABLES}
statement so that the read lock remains in effect. (If you exit the client,
the lock is released.) Then take a snapshot of the data on your master server.

The easiest way to create a snapshot is to use an archiving program to make a
binary backup of the databases in your master's data directory. 
For example, use @command{tar} on Unix, or @command{PowerArchiver}, @command{WinRAR},
@command{WinZip}, or any similar software on Windows.
To use @command{tar} to create an archive that includes all
databases, change location into the master server's data directory, then
execute this command:

@example
shell> tar -cvf /tmp/mysql-snapshot.tar .
@end example

If you want the archive to include only a database called @code{this_db}, use
this command instead:

@example
shell> tar -cvf /tmp/mysql-snapshot.tar ./this_db
@end example

Then copy the archive file to the @file{/tmp} directory on the slave server
host. On that machine, change location into the slave's data directory, and
unpack the archive file using this command:

@example
shell> tar -xvf /tmp/mysql-snapshot.tar
@end example

You may not want to replicate the @code{mysql} database if the slave
server has a different set of user accounts from those that exist on the
master. In this case, you should exclude it from the archive. You also
need not include any log files in the archive, or the @file{master.info}
or @file{relay-log.info} files.

While the read lock placed by @code{FLUSH TABLES WITH READ LOCK} is in effect,
read the value of the current binary log name and offset on the master:

@example
mysql > SHOW MASTER STATUS;
+---------------+----------+--------------+------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+---------------+----------+--------------+------------------+
| mysql-bin.003 | 73       | test         | manual,mysql     |
+---------------+----------+--------------+------------------+
@end example

The @code{File} column shows the name of the log,  while @code{Position} shows
the offset. In this example, the binary log value is
@code{mysql-bin.003} and the offset is 73. Record the values. You will need
to use them later when you are setting up the slave. They represent the
replication coordinates at which the slave should begin processing new updates
from the master.

After you have taken the snapshot and recorded the log name and offset,
you can re-enable write activity on the master:

@example
mysql> UNLOCK TABLES;
@end example

If you are using @code{InnoDB} tables, ideally you should use the @code{InnoDB Hot
Backup} tool.  It takes a consistent snapshot without acquiring any locks on
the master server, and records the log name and offset corresponding to the
snapshot to be later used on the slave.  @code{InnoDB Hot Backup} is a non-free
(commercial) additional tool that is not included in the standard MySQL distribution.
See the @code{InnoDB Hot Backup} home page at @uref{http://www.innodb.com/manual.php}
for detailed information and screenshots.

Without the @code{Hot Backup} tool, the quickest way to take a binary snapshot
of @code{InnoDB} tables is to shut down the master server and copy the
@code{InnoDB} data files, log files, and table definition files (@file{.frm}
files). To record the current log file name and offset, you should issue
the following statements before you shut down the server:

@example
mysql> FLUSH TABLES WITH READ LOCK;
mysql> SHOW MASTER STATUS;
@end example

Then record the log name and the offset from the output of @code{SHOW MASTER
STATUS} as was shown earlier. After recording the log name and the offset,
shut down the server @emph{without} unlocking the tables to make sure that the
server goes down with the snapshot corresponding to the current log file
and offset:

@example
shell> mysqladmin -u root shutdown
@end example

An alternative that works for both @code{MyISAM} and @code{InnoDB}
tables is to take an SQL dump of the master instead of a binary copy as
described in the preceding discussion. For this, you can use @command{mysqldump
--master-data} on your master and later load the SQL dump file into your
slave. However, this is slower than doing a binary copy.

If the master has been previously running without @code{--log-bin} enabled,
the log name and position values displayed by @code{SHOW MASTER STATUS}
or @command{mysqldump --master-data} will be empty. In that case, the values
that you will need to use later when specifying the slave's log file and
position are the empty string (@code{''}) and @code{4}.

@item
Make sure that the @code{[mysqld]} section of the @file{my.cnf} file on
the master host includes a @code{log-bin} option. The section should also
have a @code{server-id=master_id} option, where @code{master_id} must be
a positive integer value from 1 to 2^32 @minus{} 1. For example:

@example
[mysqld]
log-bin
server-id=1
@end example

If those options are not present, add them and restart the server.


@item
Stop the server that is to be used as a slave server and add the following to
its @file{my.cnf} file:

@example
[mysqld]
server-id=slave_id
@end example

The @code{slave_id} value, like the @code{master_id} value, must
be a positive integer value from 1 to 2^32 @minus{} 1. In addition, it is very
important that the ID of the slave be different from the ID of the
master. For example:

@example
[mysqld]
server-id=2
@end example

If you are setting up multiple slaves, each one must have a unique
@code{server-id} value that differs from that of the master and from each
of the other slaves.  Think of @code{server-id} values as something similar
to IP addresses: These IDs uniquely identify each server instance in the
community of replication partners.

If you don't specify a @code{server-id} value, it will be set to 1 if
you have not defined @code{master-host}, else it will be set to 2. Note
that in the case of @code{server-id} omission, a master will refuse
connections from all slaves, and a slave will refuse to connect to a
master. Thus, omitting @code{server-id} is good only for backup with a
binary log.

@item
If you made a binary backup of the master server's data, copy it to the
slave server's data directory before starting the slave.  Make sure that the
privileges on the files and directories are correct. The user that the server
MySQL runs as must able to read and write the files, just as on the master.

If you made a backup using @command{mysqldump}, start the slave first (see next
step).

@item
Start the slave server. If it has been replicating previously,
start the slave server with the @code{--skip-slave-start} option so that it
doesn't immediately try to connect to its master.
You also may want to start the slave server with the
@code{--log-warnings} option (enabled by default as of MySQL 4.0.19 and 4.1.2),
to get more messages in the error log about 
problems (for example, network or connection problems).
As of MySQL 4.0.21 and 4.1.3, aborted connections are not logged to the error
log unless the value is greater than 1.

@item
If you made a backup of the master server's data using @command{mysqldump}, load
the dump file into the slave server:

@example
shell> mysql -u root -p < dump_file.sql
@end example

@item
Execute the following statement on the slave, replacing the option values
with the actual values relevant to your system:

@example
mysql> CHANGE MASTER TO
    ->     MASTER_HOST='master_host_name',
    ->     MASTER_USER='replication_user_name',
    ->     MASTER_PASSWORD='replication_password',
    ->     MASTER_LOG_FILE='recorded_log_file_name',
    ->     MASTER_LOG_POS=recorded_log_position;
@end example

The following table shows the maximum length for the string options:

@multitable @columnfractions .40 .20
@item @code{MASTER_HOST}     @tab 60
@item @code{MASTER_USER}     @tab 16
@item @code{MASTER_PASSWORD} @tab 32
@item @code{MASTER_LOG_FILE} @tab 255
@end multitable

@item
Start the slave threads:

@example
mysql> START SLAVE; 
@end example

@end enumerate

After you have performed this procedure, the slave should connect to the master
and catch up on any updates that have occurred since the snapshot was taken.

If you have forgotten to set the @code{server-id} value for the master, slaves will
not be able to connect to it.

If you have forgotten to set the @code{server-id} value for the slave, you will get
the following error in its error log:

@example
Warning: You should set server-id to a non-0 value if master_host is set;
we force server id to 2, but this MySQL server will not act as a slave.
@end example

You will also find error messages in the slave's error log if it
is not able to replicate for any other reason.

Once a slave is replicating, you will find in its data directory one
file named
@file{master.info} and another named @file{relay-log.info}.
The slave uses these two files to keep track of how much
of the master's binary log it has processed. @strong{Do not} remove or
edit these files, unless you really know what you are doing and understand
the implications. Even in that case,
it is preferred that you use the @code{CHANGE MASTER TO} statement.

@strong{Note}: The content of @file{master.info} overrides some
options specified on the command line or in @file{my.cnf}.
See @ref{Replication Options} for more details.

Once you have a snapshot, you can use it to set up other slaves by
following the slave portion of the procedure just described. You do not need to
take another snapshot of the master; you can use the same one for each slave.


@node Replication Compatibility, Replication Upgrade, Replication HOWTO, Replication
@section Replication Compatibility Between MySQL Versions

The original binary log format was developed in MySQL 3.23. It changed in
MySQL 4.0, and again in MySQL 5.0. This has consequences when you upgrade
servers in a replication setup, as described in @ref{Replication Upgrade}.

As far as replication is concerned, any MySQL 4.1.x version and any 4.0.x
version are identical, because they all use the same binary log format.
Thus, any servers from these versions are compatible, and replication between
them should work seamlessly.
The exceptions to this compatibility is that versions from MySQL 4.0.0 to
4.0.2 were very early development versions that should not be used anymore.
(These were the alpha versions in the 4.0 release series.  Compatibility for
them is still documented in the manual included with their distributions.)

The following table indicates master/slave replication compatibility between
different versions of MySQL.

@c FIX arjen 2002-07-17 new table, not yet measured for XML/DocBook.
@multitable @columnfractions .10 .20 .20 .20 .20
@item                @tab                         @tab @strong{Master}         @tab @strong{Master}                    @tab @strong{Master}
@item                @tab                         @tab @strong{3.23.33 and up} @tab @strong{4.0.3 and up or any 4.1.x} @tab @strong{5.0.0}
@item @strong{Slave} @tab @strong{3.23.33 and up} @tab yes                     @tab no                                 @tab no
@item @strong{Slave} @tab @strong{4.0.3 and up}   @tab yes                     @tab yes                                @tab no
@item @strong{Slave} @tab @strong{5.0.0}          @tab yes                     @tab yes                                @tab yes
@end multitable

As a general rule, we recommended using recent MySQL versions,
because replication capabilities are continually being improved.
We also recommend using the same version for both the master and the slave.


@node Replication Upgrade, Replication Features, Replication Compatibility, Replication
@section Upgrading a Replication Setup

When you upgrade servers that participate in a replication setup, the
procedure for upgrading depends on the current server versions and the
version to which you are upgrading.

@menu
* Replication upgrade 4.0::     Upgrading Replication to 4.0 or 4.1
* Replication upgrade 5.0::     Upgrading Replication to 5.0
@end menu


@node Replication upgrade 4.0, Replication upgrade 5.0, Replication Upgrade, Replication Upgrade
@subsection Upgrading Replication to 4.0 or 4.1

This section applies to upgrading replication from MySQL 3.23 to 4.0 or 4.1.
A 4.0 server should be 4.0.3 or newer, as mentioned in @ref{Replication
Compatibility}.

When you upgrade a master from MySQL 3.23 to MySQL 4.0 or 4.1, you should
first ensure that all the slaves of this master are already at 4.0 or 4.1. If
that is not the case, you should first upgrade your slaves: Shut down each
one, upgrade it, restart it, and restart replication.


The upgrade can safely be done using the following procedure, assuming that you
have a 3.23 master to upgrade and the slaves are 4.0 or 4.1.  Note that
after the master has been upgraded, you should not restart replication using
any old 3.23 binary logs, because this will unfortunately confuse the 4.0 or
4.1 slave.

@enumerate
@item
Block all updates on the master by issuing a @code{FLUSH TABLES WITH READ LOCK}
statement.
@item
Wait until all the slaves have caught up with all changes from the master
server.
Use @code{SHOW MASTER STATUS} on the master to obtain its current binary log
file and position. Then, for each slave, use those values with a @code{SELECT
MASTER_POS_WAIT()} statement. The statement will block on the slave and return
when the slave has caught up. Then run @code{STOP SLAVE} on the slave.
@item
Stop the master server and upgrade it to MySQL 4.0 or 4.1.
@item
Restart the master server and record the name of its newly
created binary log. You can obtain the name of the file by issuing a
@code{SHOW MASTER STATUS} statement on the master. Then issue these
statements on each slave:

@example
mysql> CHANGE MASTER TO MASTER_LOG_FILE='binary_log_name',
    ->     MASTER_LOG_POS=4;
mysql> START SLAVE;
@end example

@end enumerate


@node Replication upgrade 5.0,  , Replication upgrade 4.0, Replication Upgrade
@subsection Upgrading Replication to 5.0

This section applies to upgrading replication from MySQL 3.23, 4.0, or 4.1
to 5.0.0.  A 4.0 server should be 4.0.3 or newer, as mentioned in
@ref{Replication Compatibility}.

First, note that MySQL 5.0.0 is an alpha release. It is intended to work
better than older versions (easier upgrade, replication of some important
session variables such as @code{sql_mode}; see @ref{News-5.0.0}).  However
it has not yet been extensively tested. As with any alpha release, we
recommend that you not use it in critical production environments yet.

When you upgrade a master from MySQL 3.23, 4.0, or 4.1 to 5.0.0, you should
first ensure that all the slaves of this master are already 5.0.0. If that's
not the case, you should first upgrade your slaves.  To upgrade each slave,
just shut it down, upgrade it to 5.0.0, restart it, and restart replication.
The 5.0.0 slave will be able to read its old relay logs that were written
before the upgrade and execute the statements they contain. Relay logs
created by the slave after the upgrade will be in 5.0.0 format.

After the slaves have been upgraded, shut down your master, upgrade it to
5.0.0, and restart it.  The 5.0.0 master will be able to read its old binary
logs that were written before the upgrade and send them to the 5.0.0 slaves.
The slaves will recognize the old format and handle it properly. Binary logs
created by master after the upgrade will be in 5.0.0 format. These too will
be recognized by the 5.0.0 slaves.

In other words, there are no measures to take when upgrading to 5.0.0,
except that slaves must be 5.0.0 before you can upgrade the master to 5.0.0.
Note that downgrading from 5.0.0 to older versions does not work so
automatically: You must ensure that any 5.0.0 binary logs or relay logs have
been fully processed, so that you can remove them before proceeding with the
downgrade.


@node Replication Features, Replication Options, Replication Upgrade, Replication
@section Replication Features and Known Problems

@cindex options, replication
@cindex replication options
@cindex limitations, replication
@cindex replication limitations
@cindex @file{my.cnf} file
@cindex files, @file{my.cnf}

The following list explains
what is supported and what is not.
Additional @code{InnoDB}-specific information about replication is given in
@ref{InnoDB and MySQL Replication,  , @code{InnoDB} and MySQL Replication}.

@itemize @bullet

@item
Replication will be done correctly with @code{AUTO_INCREMENT},
@code{LAST_INSERT_ID()}, and @code{TIMESTAMP} values.

@item
The @code{USER()}, @code{UUID()}, and @code{LOAD_FILE()} functions
are replicated without changes and will thus not work reliably on the
slave. This is also true for @code{CONNECTION_ID()} in slave versions
older than 4.1.1.
The @strong{new} @code{PASSWORD()} function in MySQL 4.1 is well
replicated in masters from 4.1.1 and up; your slaves also must be 4.1.1 or above
to replicate it. If you have older slaves and need to replicate
@code{PASSWORD()} from your 4.1.x master, you must start your master
with the @code{--old-password} option, so that it uses the old implementation
of @code{PASSWORD()}. (Note that the @code{PASSWORD()} implementation in
MySQL 4.1.0 differs from every other version of MySQL. It is best to avoid
4.1.0 in a replication situation.)

@item
The @code{FOREIGN_KEY_CHECKS} variable is replicated as of MySQL 4.0.14.
The @code{sql_mode}, @code{UNIQUE_CHECKS}, and @code{SQL_AUTO_IS_NULL}
variables are replicated as of 5.0.0.  The @code{SQL_SELECT_LIMIT} and
@code{table_type} variables are not yet replicated.

@item
Replication between MySQL servers using different character sets is discussed
here. First, you must ALWAYS use the same @strong{global} character set and
collation (@code{--default-character-set}, @code{--default-collation}) on the
master and the slave. Otherwise, you may get duplicate-key errors on 
the slave, because a key that is regarded as unique in the master's character
set may not be unique in the slave's character set.
Second, if the master is strictly older than MySQL 4.1.3, the character set of
the session should never be made different from its global value (in other words, don't
use @code{SET NAMES}, @code{SET CHARACTER SET} etc) because this character set
change will not be known to the slave. If the master is 4.1.3 or newer, and the
slave too, the session can freely set its local value of character set
variables (@code{NAMES}, @code{CHARACTER SET}, @code{COLLATION_CLIENT},
@code{COLLATION_SERVER} etc) as these settings will be written to the binary
log and then known to the slave. The session will however be prevented from
changing the @strong{global} value of these; as said already the master and
slave must always have identical global character set values. There also is one
last limitation: if on the master you have databases with different character
sets from the global @code{collation_server} value, you should design your
@code{CREATE TABLE} statements so that they don't implicitely rely on the
default database's character set, because there currently is a bug (Bug #2326);
a good workaround is to explicitely state the character set and collation in a
clause of the @code{CREATE TABLE}.

@item
It is possible to replicate transactional tables on the master using
non-transactional tables on the slave. For example, you can replicate an
@code{InnoDB} master table as a @code{MyISAM} slave table. However, if you do
this, you will have problems if
the slave is stopped in the middle of a @code{BEGIN/COMMIT} block, because
the slave will restart at the beginning of the @code{BEGIN} block.
This issue is on our TODO and will be fixed in the near future.

@item
Update statements that refer to user variables (that is, variables of the
form @code{@@@var{var_name}}) are badly replicated in 3.23 and 4.0. This is fixed
in 4.1. Note that user variable names are case insensitive starting from
MySQL 5.0.  You should take this into account when setting up replication
between 5.0 and an older version.

@item
The slave can connect to the master using SSL if
both are 4.1.1 or newer.

@item
If a @code{DATA DIRECTORY} or @code{INDEX DIRECTORY} clause is used in a
@code{CREATE TABLE} statement on the master server, the clause is also used
on the slave. This can cause problems if no corresponding directory exists
in the slave host filesystem or exists but is not accessible to the slave
server.  Starting from MySQL 4.0.15, there is a @code{sql_mode} option
called @code{NO_DIR_IN_CREATE}. If the slave server is run with its SQL mode
set to include this option, it will simply ignore the clauses before
replicating the @code{CREATE TABLE} statement.  The result is that the
@code{MyISAM} data and index files are created in the table's database
directory.

@item
Although we have never heard of it actually occurring, it is theoretically
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
non-deterministic; that is, left to the will of the query optimizer. (That
generally is not a good practice anyway, even outside of replication!).
For a detailed explanation of this issue, see
@ref{Open bugs}.

@item
If on master a @code{LOAD DATA INFILE} is interrupted in the middle (integrity
constraint violation, killed connection...), the slave will skip this
@code{LOAD DATA INFILE} entirely. It means that if this command permanently
inserted/updated some table records before being interrupted, these
modifications won't be replicated to the slave. This will be fixed when MySQL
features a record-level binary log format, in development.

@item
Before MySQL 4.1.1, @code{FLUSH}, @code{ANALYZE TABLE}, @code{OPTIMIZE
TABLE}, and @code{REPAIR TABLE} statements are not written to the binary
log and thus are not replicated to the slaves. This is not normally
a problem because these statements do not modify table data. However,
it can cause difficulties under certain circumstances. If you replicate
the privilege tables in the @code{mysql} database and update those tables
directly without using the @code{GRANT} statement, you
must issue a @code{FLUSH PRIVILEGES} statement on your slaves to put
the new privileges into effect. Also if you use
@code{FLUSH TABLES} when renaming a @code{MyISAM} table that is part of a
@code{MERGE} table, you will have to issue @code{FLUSH TABLES}
manually on the slaves.
As of MySQL 4.1.1, these statements are written to the binary log
(unless you specify @code{NO_WRITE_TO_BINLOG}, or its alias @code{LOCAL}).
Exceptions are that @code{FLUSH LOGS}, @code{FLUSH MASTER},
@code{FLUSH SLAVE}, and @code{FLUSH TABLES WITH READ LOCK} are not logged in
any case.  (Any of them may cause problems if replicated to a slave.)
For a syntax example, see @ref{FLUSH, , @code{FLUSH}}.

@item
MySQL only supports one master and many slaves. Later we will
add a voting algorithm to automatically change master if something goes
wrong with the current master. We will also introduce ``agent'' processes
to help do load balancing by sending @code{SELECT} queries to different
slaves.

@item
When a server shuts down and restarts, its @code{MEMORY} (@code{HEAP}) tables become empty.
As of MySQL 4.0.18, the master replicates this effect as follows:
The first time that the master uses each @code{MEMORY} table after startup,
it notifies slaves that the table needs to be emptied by writing a
@code{DELETE FROM} statement for the table to its binary log.
See @ref{MEMORY storage engine,  , @code{MEMORY} storage engine}
for more details.

@item
Temporary tables are replicated with the exception of the case that you
shut down the slave server (not just the slave threads) and you have some
replicated temporary tables that are used in update statements that have
not yet been executed on the slave.  If you shut down the slave server,
the temporary tables needed by those updates no longer are available when
the slave starts again.  To avoid this problem, do not shut down the
slave while it has temporary tables open. Instead, use this procedure:

@enumerate

@item
Issue a @code{STOP SLAVE} statement.

@item
Use @code{SHOW STATUS} to check the value of the @code{Slave_open_temp_tables}
variable.

@item
If the value is 0, issue a @command{mysqladmin shutdown} command to
shut down the slave.

@item
If the value is not 0, restart the slave threads with @code{START SLAVE}.

@item
Repeat the procedure later to see if you have better luck next time.

@end enumerate

We have plans to fix this problem in the near future.

@item
It is safe to connect servers in a circular
master/slave relationship with the @code{--log-slave-updates} option specified.
Note, however, that many statements will not work correctly in this kind of
setup unless your client code is written to take care of the potential
problems that can occur from updates that occur in different sequence
on different servers.

This means that you can create a setup such as this:

@example
A -> B -> C -> A
@end example

Server IDs are encoded in the binary log events, so server A will know when
an event that it reads was originally created by itself and will not
execute the event (unless server A was started with the
@code{--replicate-same-server-id} option, which is meaningful only in rare
setups). Thus, there will be no infinite loop.  But this circular
setup will work only if you perform no conflicting
updates between the tables.  In other words, if you insert data in both
A and C, you should never insert a row in A that may have a key that
conflicts with with a row inserted in C.  You should also not update
the same rows on two servers if the order in which the updates are
applied is significant.

@item
If a statement on the slave produces an error, the slave SQL thread
terminates, and the slave writes a message to its error log. You should
then connect to the slave manually, fix the problem (for
example, a non-existent table), and then run @code{START SLAVE}.

@item
It is safe to shut down a master server and restart it later.
If a slave loses its connection to the master, the slave tries to reconnect
immediately. If that fails, the slave retries periodically. (The default is
to retry every 60 seconds. This may be changed with the
@code{--master-connect-retry} option.)
The slave will also be able to deal with
network connectivity outages. However, the slave will notice the
network outage only after receiving no data from the master for
@code{slave_net_timeout} seconds. If your outages are short, you may want
to decrease @code{slave_net_timeout}.
@xref{Server system variables}.

@item
Shutting down the slave (cleanly) is also safe, as it keeps track of where
it left off.  Unclean shutdowns might produce problems, especially if disk
cache was not flushed to disk before the system went down. Your system fault
tolerance will be greatly increased if you have a good uninterruptible power
supply. Unclean shutdowns of the master may cause inconsistencies between the
content of tables and the binary log in master; this can be avoided by using
@code{InnoDB} tables and the @code{--innodb-safe-binlog} option on the
master. @xref{Binary log}.

@item
Due to the non-transactional nature of @code{MyISAM} tables, it is possible
to have a statement that only partially updates a table and returns an
error code. This can happen, for example, on a multiple-row insert that has
one row violating a key constraint, or if a long update statement is killed
after updating some of the rows. If that happens on the master, the slave
thread will exit and wait for the database administrator
to decide what to do about it unless
the error code is legitimate and the statement execution results in the same
error code. If this error code validation behavior is not desirable, some or
all errors can be masked out (ignored) with the @code{--slave-skip-errors}
option.  This option is available starting with MySQL 3.23.47.

@item
If you update transactional tables from non-transactional tables inside a
@code{BEGIN/COMMIT} segment, updates to the binary log may be out of sync
if some thread changes the non-transactional table before the
transaction commits.  This is because the transaction is written to the
binary log only when it is committed.

@item
Before version 4.0.15, any update to a non-transactional table is written to
the binary log at once when the update is made, whereas transactional
updates are written on @code{COMMIT} or not written at all if you use
@code{ROLLBACK}. You must take this into account when updating both
transactional tables and non-transactional tables within the same
transaction. (This is true not only for replication, but also if you are
using binary logging for backups.) In version 4.0.15, we changed the logging
behavior for transactions that mix updates to transactional and
non-transactional tables, which solves the problems (order of statements is
good in the binary log, and all needed statements are written to the binary log
even in case of @code{ROLLBACK}). The problem that remains is when a second
connection updates the non-transactional table while the first connection's
transaction is not finished yet; wrong order can still occur, because the
second connection's update will be written immediately after it is done.

@item
When a 4.x slave replicates a @code{LOAD DATA INFILE} from a 3.23 master, the
values of the @code{Exec_Master_Log_Pos} and @code{Relay_Log_Space} columns of
@code{SHOW SLAVE STATUS} become incorrect.
The incorrectness of @code{Exec_Master_Log_Pos} will cause a problem when you
stop and restart replication; so it is a good idea to correct the value before
this, by doing @code{FLUSH LOGS} on the master.
These bugs are already fixed in MySQL 5.0.0 slaves.

@end itemize

The following table lists replication problems in MySQL 3.23 that are
fixed in MySQL 4.0:

@itemize @bullet
@item
@code{LOAD DATA INFILE} is handled properly, as long as the data file
still resides on the master server at the time of update
propagation.

@item
@code{LOAD DATA LOCAL INFILE} is no longer skipped on the slave as it
was in 3.23.

@item
In 3.23, @code{RAND()} in updates does not replicate properly.
Use @code{RAND(some_non_rand_expr)} if you are replicating updates with
@code{RAND()}. You can, for example, use @code{UNIX_TIMESTAMP()} as the
argument to @code{RAND()}.
@end itemize


@node Replication Options, Replication FAQ, Replication Features, Replication
@section Replication Startup Options

@c TODO: This section says that it describes slave options, but there
@c are master options that need to be listed as well, like
@c show-slave-auth-info.

@c TODO: There really should be a separate section devoted to the use
@c and structure of master.info, and how it interacts with startup options.

On both the master and the slave, you must use the @code{server-id} option
to establish a unique replication ID for each server. You should pick a unique
positive integer in the range from 1 to 2^32 @minus{} 1 for each master and slave.
Example: @code{server-id=3}

The options that you can use on the master server for controlling binary
logging are described in @ref{Binary log}.

The following table describes the options you can use on slave replication servers.
You can specify them on the command line or in an option file.

Some slave server replication options are handled in a special way, in the
sense that they are ignored if a @file{master.info} file exists when the slave
starts and contains values for the options.
The following options are handled this way:

@itemize
@item @code{--master-host}
@item @code{--master-user}
@item @code{--master-password}
@item @code{--master-port}
@item @code{--master-connect-retry}
@end itemize

As of MySQL 4.1.1, the following options also are handled specially:

@itemize
@item @code{--master-ssl}
@item @code{--master-ssl-ca}
@item @code{--master-ssl-capath}
@item @code{--master-ssl-cert}
@item @code{--master-ssl-cipher}
@item @code{--master-ssl-key}
@end itemize

The @file{master.info} file format in 4.1.1 changed to include values
corresponding to the SSL options. In addition, the 4.1.1 file format includes
as its first line the number of lines in the file. If you upgrade an older
server to 4.1.1, the new server upgrades the @file{master.info} file to the
new format automatically when it starts.  However, if you downgrade a 4.1.1
or newer server to a version older than 4.1.1, you should manually remove
the first line before starting the older server for the first time.  Note
that, in this case, the downgraded server no longer can use an SSL connection
to communicate with the master.

If no @file{master.info} file exists when the slave server starts,
it uses values for those options that are specified in option files
or on the command line.  This will occur when you start the server
as a replication slave for the very first time, or when you have run
@code{RESET SLAVE} and shut down and restarted the slave server.

If the @file{master.info} file exists when the slave server starts, the
server ignores those options. Instead, it uses the values found in the
@file{master.info} file.

If you restart the slave server with different values of the startup options
that correspond to values in the @file{master.info} file, the different
values have no effect, because the server continues to use the
@file{master.info} file. To use different values, you must either restart
after removing the @file{master.info} file or (preferably) use the
@code{CHANGE MASTER TO} statement to reset the values while the slave is
running.

Suppose that you specify this option in your @file{my.cnf} file:

@example
[mysqld]
master-host=some_host
@end example

The first time you start the server as a replication slave, it reads and
uses that option from the @file{my.cnf} file.  The server then records the
value in the @file{master.info} file.  The next time you start the server,
it reads the master host value from the @file{master.info} file only and
ignores the value in the option file.  If you modify the @file{my.cnf} file
to specify a different master host of @code{some_other_host}, the change
still will have no effect.  You should use @code{CHANGE MASTER TO} instead.

Because the server gives an existing @file{master.info} file precedence
over the startup options just described, you might prefer not to use startup
options for these values at all, and instead specify them by using the
@code{CHANGE MASTER TO} statement.
See @ref{CHANGE MASTER TO,  , @code{CHANGE MASTER TO}}.

This example shows a more extensive use of startup options to configure a
slave server:

@example
[mysqld]
server-id=2
master-host=db-master.mycompany.com
master-port=3306
master-user=pertinax
master-password=freitag
master-connect-retry=60
report-host=db-slave.mycompany.com
@end example

The following list describes startup options for controlling replication:
Many of these options can be reset while the server is running by using the
@code{CHANGE MASTER TO} statement. Others, such as the @code{--replicate-*}
options, can be set only when the slave server starts. We plan to fix this.

@table @code

@item --log-slave-updates
Normally, updates received from a master server by a slave are not logged to
its binary log. This option tells the slave to log the updates performed by
its SQL thread to the slave's own binary log.  For this option to have any
effect, the slave must also be started with the @code{--log-bin} option to
enable binary logging.  @code{--log-slave-updates} is used when you want to
chain replication servers.  For example, you might want a setup like this:

@example
A -> B -> C
@end example

That is, A serves as the master for the slave B, and B serves as the master
for the slave C. For this to work, B must be both a master and a slave.
You must start both A and B with @code{--log-bin} to enable binary logging,
and B with the @code{--log-slave-updates} option.

@item --log-warnings
Makes the slave print more messages to the error log about what it is doing.
For example, it will warn you that it succeeded in reconnecting after a
network/connection failure, and warn you about how each slave thread started.
This option is enabled by default as of MySQL 4.0.19 and 4.1.2; to disable it,
use @code{--skip-log-warnings}.
As of MySQL 4.0.21 and 4.1.3, aborted connections are not logged to the error
log unless the value is greater than 1.

This option is not limited to replication use only. It produces warnings
across a spectrum of server activities.

@item --master-connect-retry=@var{seconds}
The number of seconds the slave thread sleeps before retrying to connect to
the master in case the master goes down or the connection is lost.  The
value in the @file{master.info} file takes precedence if it can be read.  If
not set, the default is 60.

@item --master-host=@var{host}
The hostname or IP number of the master replication server.
If this option is not given, the slave
thread will not be started.  The value in @file{master.info}
takes precedence if it can be read.

@item --master-info-file=@var{file_name}
The name to use for the file in which the slave records
information about the master.
The default name is @file{mysql.info} in the data directory.

@item --master-password=@var{password}
The password of the account that the slave thread uses for authentication when
connecting to the master.
The value in the @file{master.info} file takes precedence if it can be read.
If not set, an empty password is assumed.

@item --master-port=@var{port_number}
The TCP/IP port the master is listening on.
The value in the @file{master.info} file takes precedence if it can be read.
If not set, the compiled-in setting is assumed. If you have not tinkered with
@command{configure} options, this should be 3306.

@item --master-ssl
@itemx --master-ssl-ca=@var{file_name}
@itemx --master-ssl-capath=@var{directory_name}
@itemx --master-ssl-cert=@var{file_name}
@itemx --master-ssl-cipher=@var{cipher_list}
@itemx --master-ssl-key=@var{file_name}

These options are used for setting up a secure replication connection to
the master server using SSL.
Their meanings are the same as the corresponding
@code{--ssl},
@code{--ssl-ca},
@code{--ssl-capath},
@code{--ssl-cert},
@code{--ssl-cipher},
@code{--ssl-key}
options described in
@ref{SSL options}.
The values in the @file{master.info} file take precedence if they can be read.

These options are operational as of MySQL 4.1.1.

@item --master-user=@var{username}
The username of the account that the slave thread uses for authentication when
connecting to the master. The account must have the
@code{REPLICATION SLAVE} privilege. (Prior to MySQL 4.0.2, it must have the
@code{FILE} privilege instead.)
The value in the @file{master.info} file takes precedence if it can be read.
If the master user is not set, user @code{test} is assumed.

@item --max-relay-log-size=@var{#}
To rotate the relay log automatically.
@xref{Server system variables}.

This option is available as of MySQL 4.0.14.

@item --read-only
This option causes the slave to allow no updates except from slave threads
or from users with the @code{SUPER} privilege.  This can be useful to ensure
that a slave server accepts no updates from clients.

This option is available as of MySQL 4.0.14.

@item --relay-log=@var{file_name}
The name for the relay log. The default name is
@code{@var{host_name}-relay-bin.@var{nnnnnn}}, where @var{host_name} is the name of
the slave server host and @var{nnnnnn} indicates that relay logs are
created in numbered sequence.
You can specify the option to create hostname-independent relay log names, or
if your relay logs tend to be big (and you don't want to decrease
@code{max_relay_log_size}) and you need to put them in some area
different from the data directory, or if you want to increase speed by
balancing load between disks.

@item --relay-log-index=@var{file_name}
The location and name that should be used for the relay
log index file. The default name is
@code{@var{host_name}-relay-bin.index}, where @var{host_name} is the name of
the slave server.

@item --relay-log-info-file=@var{file_name}
The name to use for the file in which the slave records
information about the relay logs. The default name is
@file{relay-log.info} in the data directory.

@item --relay-log-purge=@{0|1@}
Disables or enables automatic purging of relay logs as soon as they are not
needed any more.  The default value is 1 (enabled).  This is a global
variable that can be changed dynamically with @code{SET GLOBAL
relay_log_purge}.

This option is available as of MySQL 4.1.1.

@item --relay-log-space-limit=@var{#}
Places an upper limit on the total size of all relay logs on the slave (a
value of 0 means ``unlimited''). This is useful for a slave server host that
has limited disk space.  When the limit is reached, the I/O thread stops
reading binary log events from the master server until the SQL thread has
caught up and deleted some now unused relay logs. Note that this limit is
not absolute: There are cases where the SQL thread needs more events
before it can delete relay logs.
In that case, the I/O thread will exceed the limit until it
becomes possible for the SQL thread to delete some relay logs. Not doing so
would cause a deadlock (which is what happens before MySQL 4.0.13).  You
should not set @code{--relay-log-space-limit} to less than twice the value
of @code{--max-relay-log-size} (or @code{--max-binlog-size} if
@code{--max-relay-log-size} is 0). In that case, there is a chance that the
I/O thread will wait for free space because @code{--relay-log-space-limit}
is exceeded, but the SQL thread will have no relay log to purge and be
unable to satisfy the I/O thread. This forces the I/O thread to temporarily
ignore @code{--relay-log-space-limit}.

@item --replicate-do-db=@var{db_name}

Tells the slave to restrict replication to statements where
the default database (that is, the one selected by @code{USE})
is @var{db_name}.
To specify more than one database, use this option multiple
times, once for each database. Note that this will not replicate
cross-database statements such as @code{UPDATE @var{some_db.some_table}
SET foo='bar'} while having selected a different database or no database. If you
need cross-database updates to work, make sure that you have MySQL 3.23.28 or
later, and use @code{--replicate-wild-do-table=@var{db_name}.%}.
Please read the notes that follow this option list.

An example of what does not work as you might expect: If the slave is
started with @code{--replicate-do-db=sales} and you issue the following
statements on the master, the @code{UPDATE} statement will not be
replicated:

@example
USE prices;
UPDATE sales.january SET amount=amount+1000;
@end example

If you need cross-database updates to work, 
use @code{--replicate-wild-do-table=@var{db_name}.%} instead.

The main reason for this ``just-check-the-default-database''
behavior is that it's difficult from the statement
alone to know whether or not it should be replicated (for example, if you
are using multiple-table @code{DELETE} or multiple-table @code{UPDATE}
statements
that go across multiple databases).  It's also very fast to just check
the default database.

@item --replicate-do-table=@var{db_name.tbl_name}

Tells the slave thread to restrict replication to the specified table.
To specify more than one table, use this option multiple times, once
for each table.  This will work for cross-database updates, in
contrast to @code{--replicate-do-db}. 
Please read the notes that follow this option list.

@item --replicate-ignore-db=@var{db_name}

Tells the slave to not replicate any statement where the default
database (that is, the one selected by @code{USE})
is @var{db_name}. To specify more than one database to
ignore, use this option multiple times, once for each database.
You should not use this option if you are using cross-database updates
and you don't want these updates to be replicated.
Please read the notes that follow this option list.

An example of what does not work as you might expect: If the slave is
started with @code{--replicate-ignore-db=sales} and you issue the following
statements on the master, the @code{UPDATE} statement will be replicated:

@example
USE prices;
UPDATE sales.january SET amount=amount+1000;
@end example

If you need cross-database updates to work, 
use @code{--replicate-wild-ignore-table=@var{db_name}.%} instead.

@item --replicate-ignore-table=@var{db_name.tbl_name}
Tells the slave thread to not replicate any statement that updates the
specified table (even if any other tables might be updated by the same
statement). To specify more than one table to ignore, use this option
multiple times, once for each table. This will work for cross-database
updates, in contrast to @code{--replicate-ignore-db}.
Please read the notes that follow this option list.

@item --replicate-wild-do-table=@var{db_name.tbl_name}
Tells the slave thread to restrict replication to statements where any of
the updated tables match the specified database and table name patterns.
Patterns can contain the @samp{%} and @samp{_} wildcard characters, which have
the same meaning as for the @code{LIKE} pattern-matching operator.  To specify
more than one table, use this option multiple times, once for each
table.  This will work for cross-database updates.
Please read the notes that follow this option list.

Example: @code{--replicate-wild-do-table=foo%.bar%} will replicate only
updates that use a table where the database name starts with @code{foo}
and the table name starts with @code{bar}.

If the table name pattern is @code{%}, it matches any table name and the
option also applies to database-level statements (@code{CREATE DATABASE}, @code{DROP DATABASE}, and
@code{ALTER DATABASE}).
For example, if you use @code{--replicate-wild-do-table=foo%.%},
database-level statements statements are replicated
if the database name matches the pattern @code{foo%}.

To include literal wildcard characters in the database or table name
patterns, escape them with a backslash.  For example, to replicate all tables
of a database that is named @code{my_own%db}, but not replicate tables
from the @code{my1ownAABCdb} database, you should escape the @samp{_} and
@samp{%} characters like this: @code{--replicate-wild-do-table=my\_own\%db}.
If you're using the option on the command line, you might need to double
the backslashes or quote the option value, depending on your command
interpreter.  For example, with the @command{bash} shell, you would need to
type @code{--replicate-wild-do-table=my\\_own\\%db}.

@item --replicate-wild-ignore-table=@var{db_name.tbl_name}
Tells the slave thread to not replicate a statement where any table matches the
given wildcard pattern. To specify more than one table to ignore, use
this option multiple times, once for each table. This will work for
cross-database updates.
Please read the notes that follow this option list.

Example: @code{--replicate-wild-ignore-table=foo%.bar%} will not replicate
updates that use a table where the database name starts with @code{foo}
and the table name starts with @code{bar}.

For information about how matching works, see the description of
the @code{--replicate-wild-ignore-table} option.
The rules for including literal wildcard characters in the option value
are the same as for
@code{--replicate-wild-ignore-table} as well.

@item --replicate-rewrite-db=@var{from_name}->@var{to_name}

Tells the slave to translate the default database
(that is, the one selected by @code{USE})
to @var{to_name} if it was @var{from_name} on the master.
Only statements involving tables are affected
(not statements such as @code{CREATE DATABASE}, @code{DROP DATABASE},
and @code{ALTER DATABASE}),
and only if @var{from_name} was the default database on the master.
This will not work for cross-database updates.
Note that the database name translation is done before @code{--replicate-*}
rules are tested.

If you use this option on the command line and the @samp{>} character is
special to your command interpreter, quote the option value. For example:

@example
shell> mysqld --replicate-rewrite-db="@var{olddb}->@var{newdb}"
@end example

@item --replicate-same-server-id

To be used on slave servers.  Usually you can should the default setting of
0, to prevent infinite loops in circular replication.  If set to 1, this
slave will not skip events having its own server id; normally this is useful
only in rare configurations.  Cannot be set to 1 if
@code{--log-slave-updates} is used.
Be careful that starting from MySQL 4.1, by default the slave I/O thread does
not even write binary log events to the relay log if they have the slave's server
id (this optimization helps save disk usage compared to 4.0). So if you want to
use @code{--replicate-same-server-id} in 4.1 versions, be sure to start the
slave with this option before you make the slave read its own events which you
want the slave SQL thread to execute.

@item --report-host=@var{host}
The hostname or IP number of the slave to be reported to the master during
slave registration. This value will appear in the output of @code{SHOW SLAVE
HOSTS} on the master server. Leave the value unset if you do not want the
slave to register itself with the master. Note that it is not sufficient for
the master to simply read the IP number of the slave from the TCP/IP socket
after the slave connects. Due to @code{NAT} and other routing issues, that IP
may not be valid for connecting to the slave from the master or other hosts.

@c For
@c the moment, this option is of no real interest; it is meant for failover
@c replication, which is not implemented yet.

This option is available as of MySQL 4.0.0.

@item --report-port=@var{port_number}
The TCP/IP port for connecting to the slave, to be reported to the
master during slave registration.  Set it only if the slave is listening
on a non-default port or if you have a special tunnel from the master or
other clients to the slave. If you are not sure, leave this option unset.
@c For the moment, this option is of no real interest; it is meant for failover
@c replication, which is not implemented yet.

This option is available as of MySQL 4.0.0.

@item --skip-slave-start
Tells the slave server not to start the slave threads when the server starts.
To start the threads later, use a @code{START SLAVE} statement.

@item --slave_compressed_protocol=@{0|1@}
If this option is set to
1, use compression of the slave/master protocol if both the
slave and the master support it.

@item --slave-load-tmpdir=@var{file_name}
The name of the directory where the slave creates temporary files.
This option is by default equal to the value of the @code{tmpdir} system variable.
When the slave SQL thread replicates a @code{LOAD DATA INFILE} statement, it
extracts the to-be-loaded file from the relay log into temporary files,
then loads these into the table. If the file loaded on the master was
huge, the temporary files on the slave will be huge, too. Therefore, it might
be advisable to use this option to tell the slave to put temporary files in
a directory located in some filesystem that has a lot of available space.
In that case, you may also use the @code{--relay-log} option to place
the relay logs in that filesystem, because the relay logs
will be huge as well.
@code{--slave-load-tmpdir} should point to a disk-based filesystem, not a
memory-based one: The slave needs the
temporary files used to replicate @code{LOAD DATA INFILE} to survive a
machine's restart.
The directory also should not be one that is cleared by the operating system
during the system startup process.

@item --slave-net-timeout=@var{seconds}
The number of seconds to wait for more data from the master before aborting
the read, considering the connection broken, and trying to reconnect. The first
retry occurs immediately after the timeout. The interval between retries is
controlled by the @code{--master-connect-retry} option.

@item --slave-skip-errors= [@var{err_code1},@var{err_code2},... | all]

Normally, replication stops when an error occurs, which gives you the
opportunity to resolve the inconsistency in the data manually.  This option
tells the slave SQL thread to continue replication when a statement returns
any of the errors listed in the option value.

Do not use this option unless you fully understand why you are getting the
errors.  If there are no bugs in your replication setup and client programs,
and no bugs in MySQL itself, an error that stops replication should never
occur.  Indiscriminate use of this option will result in slaves becoming
hopelessly out of sync with the master, and you will have no idea why.

For error codes, you should use the numbers provided by the error message in
your slave error log and in the output of @code{SHOW SLAVE STATUS}.
The server error codes are listed in @ref{Error-handling}.

You can (but should not) also use the very non-recommended value of @code{all}
which will ignore all error messages and keep barging along regardless of what
happens.  Needless to say, if you use it, we make no promises regarding your
data integrity. Please do not complain if your data on the slave is not
anywhere close to what it is on the master in this case. You have been
warned.

Examples:

@example
--slave-skip-errors=1062,1053
--slave-skip-errors=all
@end example

@end table

The @code{--replicate-*} rules are evaluated as follows to determine whether a
statement will be executed by the slave or ignored:

@enumerate
@item
Are there some @code{--replicate-do-db} or @code{--replicate-ignore-db}
rules?

@itemize @bullet
@item Yes:
Test them as for @code{--binlog-do-db} and @code{--binlog-ignore-db}
(@pxref{Binary log}). What is the result of the test?

@itemize @minus
@item Ignore the statement:
Ignore it and exit.
@item Execute the statement:
Don't execute it immediately, defer the decision, go to the next step.
@end itemize

@item No:
Go to the next step.
@end itemize

@item
Are there some @code{--replicate-*-table} rules?

@itemize @bullet
@item No:
Execute the query and exit.
@item Yes:
Go to the next step. Only tables that are to be updated are compared
to the rules (@code{INSERT INTO sales SELECT * FROM prices}: only
@code{sales} will be compared to the rules). If several tables are to be
updated (multiple-table statement),
the first matching table (matching ``do'' or ``ignore'') wins.
That is, the first table is compared to the rules. Then, if no decision could
be mad, the second table is compared to the rules, and so forth.
@end itemize

@item
Are there some @code{--replicate-do-table} rules?

@itemize @bullet
@item Yes:
Does the table match any of them?
@itemize @minus
@item Yes:
Execute the query and exit.
@item No:
Go to the next step.
@end itemize

@item No:
Go to the next step.
@end itemize

@item
Are there some @code{--replicate-ignore-table} rules?

@itemize @bullet
@item Yes:
Does the table match any of them?
@itemize @minus
@item Yes:
Ignore the query and exit.
@item No:
Go to the next step.
@end itemize

@item No:
Go to the next step.
@end itemize

@item
Are there some @code{--replicate-wild-do-table} rules?

@itemize @bullet
@item Yes:
Does the table match any of them?

@itemize @minus
@item Yes:
Execute the query and exit.
@item No:
Go to the next step.
@end itemize

@item No:
Go to the next step.
@end itemize

@item
Are there some @code{--replicate-wild-ignore-table} rules?

@itemize @bullet
@item Yes:
Does the table match any of them?

@itemize @minus
@item Yes:
Ignore the query and exit.
@item No:
Go to the next step.
@end itemize

@item No:
Go to the next step.
@end itemize

@item
No @code{--replicate-*-table} rule was matched.
Is there another table to test against these rules?

@itemize @bullet
@item Yes:
Loop.
@item No:
We have tested all tables to be updated and could not match any rule.
Are there @code{--replicate-do-table} or @code{--replicate-wild-do-table}
rules?

@itemize @minus
@item Yes:
Ignore the query and exit.
@item No:
Execute the query and exit.
@end itemize

@end itemize

@end enumerate


@node Replication FAQ, Replication Problems, Replication Options, Replication
@section Replication FAQ

@strong{Q}: How do I configure a slave if the master is already running
and I do not want to stop it?

@strong{A}: There are several options. If you have taken a backup of the
master at some point and recorded the binary log name and offset (from the
output of @code{SHOW MASTER STATUS} ) corresponding to the snapshot, use
the following procedure:

@enumerate
@item
Make sure that the slave is assigned a unique server ID.
@item
Execute the following statement on the slave, filling in appropriate values for each
option:

@example
mysql> CHANGE MASTER TO
    ->     MASTER_HOST='master_host_name',
    ->     MASTER_USER='master_user_name',
    ->     MASTER_PASSWORD='master_pass',
    ->     MASTER_LOG_FILE='recorded_log_file_name',
    ->     MASTER_LOG_POS=recorded_log_position;
@end example

@item
Execute @code{START SLAVE} on the slave.
@end enumerate

If you do not have a backup of the master server already, here is a quick
procedure for creating one. All steps should be performed on the master host.

@enumerate
@item
Issue this statement:

@example
mysql> FLUSH TABLES WITH READ LOCK;
@end example

@item
With the lock still in place, execute this command (or a variation of it):

@example
shell> tar zcf /tmp/backup.tar.gz /var/lib/mysql
@end example

@item
Issue this statement and
make sure to record the output, which you will need later:

@example
mysql> SHOW MASTER STATUS;
@end example

@item
Release the lock:

@example
mysql> UNLOCK TABLES;
@end example

@end enumerate

An alternative is to make an SQL dump of the master instead of a binary copy
as in the preceding procedure. To do this, you can use @command{mysqldump
--master-data} on your master and later load the SQL dump into your slave.
However, this is slower than making a binary copy.

No matter which of the two methods you use, afterward follow the
instructions for the case when you have a snapshot and have recorded the log
name and offset. You can use the same snapshot to set up several slaves.
Once you have the snapshot of the master, you can wait to set up a slave as
long as the binary logs of the master are left intact.  The two practical
limitations on the length of time you can wait are the amount of disk space
available to retain binary logs on the master and the length of time it
will take the slave to catch up.

You can also use @code{LOAD DATA FROM MASTER}.  This is a convenient
statement that transfers a snapshot to the slave and adjusts the log name
and offset all at once. In the future, @code{LOAD DATA FROM MASTER} will be
the recommended way to set up a slave.  Be warned, however, that it works
only for @code{MyISAM} tables and it may hold a read lock for a long time.
It is not yet implemented as efficiently as we would like. If you have large
tables, the preferred method at this time is still to make a binary snapshot
on the master server after executing @code{FLUSH TABLES WITH READ LOCK}.

@strong{Q}: Does the slave need to be connected to the master all the time?

@strong{A}: No, it does not. The slave can go down or stay
disconnected for hours or even days, then reconnect and catch up on the
updates.
For example, you can set up a master/slave relationship over a dial-up link
where the link is up only sporadically and
for short periods of time. The implication of this is that, at any
given time, the slave is not guaranteed to be in sync with the master
unless you take some special measures. In the future, we will have the
option to block the master until at least one slave is in sync.

@strong{Q}: How do I know how late a slave is compared to the
master? In other words, how do I know the date of the last query
replicated by the slave?

@strong{A}: 
If the slave is 4.1.1 or newer, read the @code{Seconds_Behind_Master} column
in @code{SHOW SLAVE STATUS}. For older versions, the following applies.
This is possible only if @code{SHOW PROCESSLIST} on the slave shows that the
SQL thread is running (or for MySQL 3.23, that the slave thread is running),
and that the thread has executed at least one event from the master.
@xref{Replication Implementation Details}.

When the slave SQL thread executes an event read from the master, it
modifies its own time to the event timestamp (this is why @code{TIMESTAMP}
is well replicated). In the @code{Time} column in the output of
@code{SHOW PROCESSLIST}, the number of seconds displayed for the slave SQL
thread is the number of seconds between the timestamp of the last replicated
event and the real time of the slave machine. You can use this to determine
the date of the last replicated event. Note that if your slave has been
disconnected from the master for one hour, and then reconnects, you may
immediately see @code{Time} values like 3600 for the slave SQL thread in
@code{SHOW PROCESSLIST}. This would be because the slave is executing
statements that are one hour old.

@strong{Q}: How do I force the master to block updates until the slave catches
up?

@strong{A}: Use the following procedure:

@enumerate

@item
On the master, execute these statements:

@example
mysql> FLUSH TABLES WITH READ LOCK;
mysql> SHOW MASTER STATUS;
@end example

Record the log name and the offset from the output of the @code{SHOW}
statement. These are the replication coordinates.

@item
On the slave, issue the following statement, where the arguments to the
@code{MASTER_POS_WAIT()} function are the replication coordinate values
obtained in the previous step:

@example
mysql> SELECT MASTER_POS_WAIT('log_name', log_offset);
@end example

The @code{SELECT} statement will block until the slave reaches the specified
log file and offset. At that point, the slave will be in sync with the master
and the statement will return.

@item
On the master, issue the following statement to allow the master to begin
processing updates again:

@example
mysql> UNLOCK TABLES;
@end example

@end enumerate

@strong{Q}: What issues should I be aware of when setting up two-way
replication?

@strong{A}: MySQL replication currently does not support any
locking protocol between master and slave to guarantee the atomicity of
a distributed (cross-server) update. In other words, it is possible
for client A to make an update to  co-master 1, and in the meantime,
before it propagates to co-master 2, client B could make an update to
co-master 2 that will make the update of client A work differently than
it did on co-master 1. Thus, when the update of client A makes it
to co-master 2, it will produce  tables that are different than
what you have on co-master 1, even after all the updates from co-master
2 have also propagated. This means that you should not co-chain two servers
in a two-way replication relationship unless you are sure that your updates
can safely happen in any order, or unless you take care of mis-ordered
updates somehow in the client code.

You must also realize that two-way replication actually does not improve
performance very much (if at all), as far as updates are concerned. Both
servers need to do the same number of updates each, as you would have
one server do. The only difference is that there will be a little less
lock contention, because the updates originating on another server will
be serialized in one slave thread. Even this benefit might be
offset by network delays.

@cindex performance, improving
@cindex increasing, performance
@strong{Q}: How can I use replication to improve performance of my system?

@strong{A}: You should set up one server as the master and direct all
writes to it. Then configure as many slaves as you have the budget and
rackspace for, and distribute the reads among the master and the slaves.
You can also start the slaves with the @code{--skip-innodb}, @code{--skip-bdb},
@code{--low-priority-updates}, and @code{--delay-key-write=ALL} options
to get speed improvements on the slave end.  In this case, the slave will
use non-transactional @code{MyISAM} tables instead of @code{InnoDB} and
@code{BDB} tables to get more speed.

@strong{Q}: What should I do to prepare client code in my own applications
to use performance-enhancing replication?

@strong{A}:
If the part of your code that is responsible for database access has
been properly abstracted/modularized, converting it to run with a
replicated setup should be very smooth and easy. Just change the
implementation of your database access to send all writes to the master,
and to send reads to either the master or a slave.
If your code does not have this level of abstraction,
setting up a replicated system will give you the opportunity and motivation
to it clean up.
You should start by creating a wrapper library or module with the following
functions:

@itemize @bullet
@item
@code{safe_writer_connect()}
@item
@code{safe_reader_connect()}
@item
@code{safe_reader_statement()}
@item
@code{safe_writer_statement()}
@end itemize

@code{safe_} in each function name means that the function will take care
of handling all the error conditions.
You can use different names for the
functions. The important thing is to have a unified interface for connecting
for reads, connecting for writes, doing a read, and doing a write.

You should then convert your client code to use the wrapper library.
This may be a painful and scary process at first, but it will pay off in
the long run. All applications that use the approach just described will be
able to take advantage of a master/slave configuration, even one involving
multiple slaves.  The
code will be a lot easier to maintain, and adding troubleshooting
options will be trivial. You will just need to modify one or two
functions; for example, to log how long each statement took, or which
statement among your many thousands gave you an error.

If you have
written a lot of code already, you may want to automate the conversion
task by using the @command{replace} utility that comes with standard MySQL
distributions, or just write your own conversion script.  Ideally, your
code already uses consistent programming style conventions. If not, then you
are probably better off rewriting it anyway, or at least going through
and manually regularizing it to use a consistent style.

@strong{Q}: When and how much can MySQL replication improve the performance
of my system?

@strong{A}: MySQL replication is most beneficial for a system
with frequent reads and infrequent writes. In theory, by using a
single-master/multiple-slave setup, you can scale the system by adding more
slaves until you either run out of network bandwidth, or your update
load grows to the point that the master cannot handle it.

In order to determine how many slaves you can get before the added benefits
begin to level out, and how much you can improve performance of your site,
you need to know your query patterns, and to determine empirically by
benchmarking the relationship between the throughput for reads (reads per
second, or @code{max_reads}) and for writes (@code{max_writes}) on a typical
master and a typical slave. The example here shows a rather simplified
calculation of what you can get with replication for a hypothetical system.

Let's say that system load consists of 10% writes and 90% reads, and we
have determined by benchmarking that @code{max_reads} is 1200 @minus{}
2 * @code{max_writes}.  In other words, the system can do 1,200 reads per
second with no writes, the average write is twice as slow as the average
read, and the relationship is linear. Let us suppose that the master
and each slave have the same capacity, and that we have one master and N
slaves. Then we have for each server (master or slave):

@code{reads = 1200 - 2 * writes}

@code{reads = 9 * writes / (N + 1) } (reads are split, but writes go
to all servers)

@code{9 * writes / (N + 1) + 2 * writes = 1200}

@code{writes = 1200 / (2 + 9/(N+1)) }

The last equation indicates that the maximum number of writes for N slaves,
given a maximum possible read rate of 1,200 per minute and a ratio of nine
reads per write.

This analysis yields the following conclusions:

@itemize @bullet

@item
If N = 0 (which means we have no replication), our system can handle about
1200/11 = 109 writes per second.

@item
If N = 1, we get up to 184 writes per second.

@item
If N = 8, we get up to 400 writes per second.

@item
If N = 17, we get up to 480 writes per second.

@item
Eventually, as N approaches infinity (and our budget negative infinity),
we can get very close to 600 writes per second, increasing system
throughput about 5.5 times. However, with only eight servers, we increased
it almost four times already.

@end itemize

Note that these computations assume infinite network bandwidth and
neglect several other factors that could turn out to be significant on
your system. In many cases, you may not be able to perform a computation
similar to the just shown that will accurately predict what will happen
on your system if you add N replication slaves. However, answering the
following questions should help you decide whether and how much
replication will improve the performance of your system:

@itemize @bullet
@item
What is the read/write ratio on your system?
@item
How much more write load can one server handle if you reduce the reads?
@item
For how many slaves do you have bandwidth available on your network?
@end itemize

@strong{Q}: How can I use replication to provide redundancy/high
availability?

@strong{A}: With the currently available features, you would have to
set up a master and a slave (or several slaves), and write a script
that will monitor the
master to see whether it is up. Then instruct your applications and
the slaves to change master in case of failure. Some suggestions:

@itemize @bullet
@item
To tell a slave to change its master, use the @code{CHANGE MASTER TO}
statement.
@item
A good way to keep your applications informed as to the location of the
master is by having a dynamic DNS entry for the master.
With @code{bind} you can use @file{nsupdate} to dynamically update your DNS.
@item
You should run your slaves with the @code{--log-bin} option and without
@code{--log-slave-updates}. This way the slave will be ready to become a
master as soon as you issue @code{STOP SLAVE}; @code{RESET MASTER}, and
@code{CHANGE MASTER TO} on the other slaves.
For example, assume that you have the following setup:

@example
       WC   
        \  
         v
 WC----> M
       / | \  
      /  |  \     
     v   v   v
    S1   S2  S3  
@end example

M means the master, S the slaves, WC the clients that issue database writes
and reads; clients that issue only database reads are not represented,
because they need not switch.  S1, S2, and S3 are slaves running with
@code{--log-bin} and without @code{--log-slave-updates}.
Because updates received by a slave from the master are not logged in the
binary log unless @code{--log-slave-updates} is specified, the binary log on
each slave is empty.  If for some reason M becomes unavailable, you can
pick one slave to become the new master. For example, if you pick S1,
all WC should be redirected to S1, and S2 and S3 should replicate from S1.

Make sure that all slaves have processed any statements in their relay log.
On each slave, issue @code{STOP SLAVE IO_THREAD}, then check the output
of @code{SHOW PROCESSLIST} until you see @code{Has read all relay log}.
When this is true for all slaves, they can be reconfigured to the new setup.
On the slave S1 being promoted to become the master, issue
@code{STOP SLAVE} and  @code{RESET MASTER}.

On the other slaves S2 and S3, use @code{STOP SLAVE} and @code{CHANGE MASTER
TO MASTER_HOST='S1'} (where @code{'S1'} represents the real hostname of
S1). To @code{CHANGE MASTER}, add all information about how to connect to
S1 from S2 or S3 (user, password, port). In @code{CHANGE MASTER}, there is
no need to specify the name of S1's binary log or binary log position to
read from: We know it is the first binary log and position 4, which are
the defaults for @code{CHANGE MASTER}. Finally, use @code{START SLAVE}
on S2 and S3.

Then instruct all WC to direct their statements to S1. From that point on,
all updates statements sent by WC to S1 are written to the binary log of S1,
which will contain exactly every update statement sent to S1 since M died.

The result is this configuration:

@example
       WC   
      /   
      |  
 WC   |  M(unavailable)
  \   | 
   \  | 
    v v
     S1<--S2  S3  
      ^       |
      +-------+
@end example

When M is up again, you just have to issue on it the same @code{CHANGE
MASTER} as the one issued on S2 and S3, so that M becomes a slave of S1 and
picks all the WC writes it has missed while it was down. Now to make M a
master again (because it is the most powerful machine, for example), use
the preceding procedure as if S1 was unavailable and M was to be the new
master. During the procedure, don't forget to run @code{RESET MASTER} on M
before making S1, S2,  and S3 slaves of M. Otherwise, they may pick up old
WC writes from before the point at which M became unavailable.

@end itemize

We are currently working on integrating an automatic master election
system into MySQL, but until it is ready, you will have to
create your own monitoring tools.


@node Replication Problems, Replication Bugs, Replication FAQ, Replication
@section Troubleshooting Replication

If you have followed the instructions, and your replication setup is not
working, first check the following:

@itemize @bullet
@item
@strong{Check the error log for messages}. Many users have lost time
by not doing this early enough.

@item
Is the master logging to the binary log? Check with @code{SHOW MASTER STATUS}.
If it is, @code{Position} will be non-zero. If not, verify that you are
running the master with the @code{log-bin} and @code{server-id} options.

@item
Is the slave running? Use @code{SHOW SLAVE STATUS} to check whether the
@code{Slave_IO_Running} and @code{Slave_SQL_Running} values are both
@code{Yes}.
If not, verify the options that were used when starting the slave server.

@item
If the slave is running, did it establish a connection to the master? Use
@code{SHOW PROCESSLIST}, find the I/O and SQL threads and check their 
@code{State} column to see how they display.
@xref{Replication Implementation Details}.
If the I/O thread state says @code{Connecting to master}, verify the
privileges for the replication user on the master, master hostname, your
DNS setup, whether the master is actually running, and whether it is reachable
from the slave.

@item
If the slave was running before but now has stopped, the reason usually is
that some statement that succeeded on the master failed on the slave. This
should never happen if you have taken a proper snapshot of the master, and
never modify the data on the slave outside of the slave thread. If it does,
it is a bug or you have encountered one of the known replication limitations
described in @ref{Replication Features}.  If it is a bug, see
@ref{Replication Bugs} for instructions on how to report it.

@item
If a statement that succeeded on the master refuses to run on the slave, and
it is not feasible to do a full database resynchronization (that is, to
delete the slave's database and copy a new snapshot from the master), try
the following:

@enumerate
@item
Determine whether
the slave's table is different from the
master's. Try to understand how this happened.
Then make the slave's table
identical to the master's and run @code{START SLAVE}.

@item
If the preceding step does not work or does not apply, try to understand
whether it would
be safe to make the update manually (if needed) and then ignore the next
statement from the master.

@item
If you decide that you can skip the next statement from the master, issue
the following statements:

@example
mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = n;
mysql> START SLAVE;
@end example

The value of @code{n} should be 1 if the next statement from the master
does not use @code{AUTO_INCREMENT} or @code{LAST_INSERT_ID()}. Otherwise,
the value should be 2.  The reason for using a value of 2 for statements
that use @code{AUTO_INCREMENT} or @code{LAST_INSERT_ID()} is that they
take two events in the binary log of the master.

@item
If you are sure that the slave started out perfectly synchronized with the master,
and no one has updated the tables involved outside of slave thread, then
presumably the discrepancy is the result of a bug. If you are running the most
recent version, please report the problem. If you are running an older
version of MySQL, try upgrading.
@end enumerate

@end itemize


@node Replication Bugs,  , Replication Problems, Replication
@section Reporting Replication Bugs

When you have determined that there is no user error involved, and replication
still either does not work at all or is unstable, it is time to send
us a bug report. We need to get as much information as possible from you to be able
to track down the bug. Please do spend some time and effort preparing a good
bug report. 

If you have a repeatable test case that demonstrates the bug, please
enter it into our bugs database
at @uref{http://bugs.mysql.com/}. If you have a phantom problem (one that
you cannot duplicate ``at will''), use the following procedure:

@enumerate
@item
Verify that no user error is involved. For example, if you update the
slave outside of the slave thread, the data will go out of sync, and you can
have unique key violations on updates. In this case, the slave thread will
stop and wait for you to clean up the tables manually to bring them in sync.
This is not a replication problem. It is a problem of outside interference
that causes replication to fail.

@item
Run the slave with the @code{--log-slave-updates} and @code{--log-bin}
options.
They will cause the slave to log the updates that it receives from the master
into its own binary logs.

@item
Save all evidence before resetting the replication state. If we have no
information or only sketchy information, it becomes difficult or impossible
for us to track down the problem. The evidence you should collect is:

@itemize @bullet
@item
All binary logs from the master

@item
All binary logs from the slave

@item
The output of @code{SHOW MASTER STATUS} from the master at the time
you have discovered the problem

@item
The output of @code{SHOW SLAVE STATUS} from the master at the time
you have discovered the problem

@item
Error logs from the master and the slave
@end itemize

@item
Use @command{mysqlbinlog} to examine the binary logs. The following should
be helpful
to find the trouble query, for example:
@example
shell> mysqlbinlog -j pos_from_slave_status \
           /path/to/log_from_slave_status | head
@end example
@end enumerate

Once you have collected the evidence for the phantom problem, try hard to
isolate it into a separate test case first. Then enter the problem into
our bugs database at @uref{http://bugs.mysql.com/} with as much
information as possible.


@node MySQL Optimization, Client-Side Scripts, Replication, Top
@chapter MySQL Optimization

@menu
* Optimize Overview::           Optimization Overview
* Query Speed::                 Optimizing @code{SELECT} Statements and Other Queries
* Locking Issues::              Locking Issues
* Optimizing Database Structure::  Optimizing Database Structure
* Optimizing the Server::       Optimizing the MySQL Server
* Disk issues::                 Disk Issues
@end menu


Optimization is a complex task because ultimately it requires understanding
of the entire system to be optimized. Although it may be possible to
perform some local optimizations with little knowledge of your system or
application, the more optimal you want your system to become, the more
you will have to know about it.

This chapter tries to explain and give some examples of different
ways to optimize MySQL.  Remember, however, that there are
always additional ways to make the system
even faster, although they may require increasing effort to achieve.


@node Optimize Overview, Query Speed, MySQL Optimization, MySQL Optimization
@section Optimization Overview

The most important factor in making a system fast is its basic
design. You also need to know what kinds of things your system will be
doing, and what your bottlenecks are.

The most common system bottlenecks are:

@itemize @bullet
@item Disk seeks.
It takes time for the disk to find a piece of data. With modern disks,
the mean time for this is usually lower than 10ms, so we can in
theory do about 100 seeks a second. This time improves slowly with new
disks and is very hard to optimize for a single table. The way to
optimize seek time is to distribute the data onto more than one disk.

@item Disk reading and writing.
When the disk is at the correct position, we need to read the data. With
modern disks, one disk delivers at least 10-20MB/s throughput. This
is easier to optimize than seeks because you can read in parallel from
multiple disks.

@item CPU cycles.
When we have the data in main memory (or if it was already
there), we need to process it to get our result. Having small
tables compared to the amount of memory is the most common limiting
factor. But with small tables, speed is usually not the problem.

@item Memory bandwidth.
When the CPU needs more data than can fit in the CPU cache, main
memory bandwidth becomes a bottleneck. This is an uncommon bottleneck
for most systems, but one to be aware of.
@end itemize


@menu
* Design Limitations::          MySQL Design Limitations and Tradeoffs
* Portability::                 Designing Applications for Portability
* Internal use::                What We Have Used MySQL For
* MySQL Benchmarks::            The MySQL Benchmark Suite
* Custom Benchmarks::           Using Your Own Benchmarks
@end menu


@node Design Limitations, Portability, Optimize Overview, Optimize Overview
@subsection MySQL Design Limitations and Tradeoffs

@cindex design, limitations
@cindex limitations, design

When using the @code{MyISAM} storage engine, MySQL uses extremely fast table
locking that allows multiple readers or a single writer. The biggest problem
with this storage engine occurs when you have a steady stream of mixed
updates and slow selects on a single table.  If this is a problem for
certain tables, you can use another storage engine for them. @xref{Storage
engines}.

MySQL can work with both transactional and non-transactional tables.
To be able to work smoothly with non-transactional tables (which can't
roll back if something goes wrong), MySQL has the following rules
(when not running in strict mode or if you use the @code{IGNORE}
specifier to @code{INSERT} or @code{UPDATE}).

@cindex default values
@itemize @bullet
@item
All columns have default values.
@item
If you insert an ``incorrect'' value in a column, such as a too-large numeric
value into a numeric column, MySQL sets the column to the ``best possible
value'' instead of giving an error.  For numerical values, this is 0,
the smallest possible value or the largest possible value. For strings,
this is either the empty string or the longest possible string that can
be stored in the column.
@item
All calculated expressions return a value that can be used instead of
signaling an error condition. For example, 1/0 returns @code{NULL}.
(This behavior can be changed by using the
@code{ERROR_FOR_DIVISION_BY_ZERO} SQL mode).
@end itemize

If you are using non-transactional tables, you should not use MySQL to check
column content. In general, the safest (and often fastest) way is to let the
application ensure that it passes only legal values to the database.

For more information about this, see @ref{Constraints} and @ref{INSERT} or
@ref{Server SQL mode}.

@node Portability, Internal use, Design Limitations, Optimize Overview
@subsection Designing Applications for Portability

@cindex portability
@cindex crash-me program
@cindex programs, crash-me

Because all SQL servers implement different parts of standard SQL,
it takes work to write portable SQL applications.  It is very easy to
achieve portability for very simple selects and inserts, but becomes more
difficult the more capabilities you require.  If you want an application
that is fast with many database systems, it becomes even harder!

To make a complex application portable, you need to determine which SQL
servers it must work with, then determine what features those servers
support.

All database systems have some weak points. That is, they have different
design compromises that lead to different behavior.

You can use the MySQL @code{crash-me} program to find functions, types, and
limits that you can use with a selection of database servers.
@code{crash-me} does not check for every possible feature, but it is still
reasonably comprehensive, performing about 450 tests.

An example of the type of information @code{crash-me} can provide is that
you shouldn't have column names longer than 18 characters
if you want to be able to use Informix or DB2.

The @code{crash-me} program and the MySQL benchmarks are all very database
independent.  By taking a look at how they are written, you can get
a feeling for what you have to do to make your own applications database
independent.  The programs can be found in the @file{sql-bench} directory
of MySQL source distributions. They are written in Perl and use the DBI
database interface.  Use of DBI in itself solves part of the portability
problem because it provides database-independent access methods.

For @code{crash-me} results, visit
@uref{http://dev.mysql.com/tech-resources/crash-me.php}.
See @uref{http://dev.mysql.com/tech-resources/benchmarks/} for the results
from the benchmarks.

If you strive for database independence, you need to get a good feeling
for each SQL server's bottlenecks. For example, MySQL is very fast in
retrieving and updating records for @code{MyISAM} tables, but will have
a problem in mixing slow readers and writers on the same table. Oracle,
on the other hand, has a big problem when you try to access rows that
you have recently updated (until they are flushed to disk). Transactional
databases in general are not very good at generating summary tables from
log tables, because in this case row locking is almost useless.

To make your application @emph{really} database independent, you need to define
an easily extendable interface through which you manipulate your data. As
C++ is available on most systems, it makes sense to use a C++ class-based
interface to the databases.

If you use some feature that is specific to a given database system (such
as the @code{REPLACE} statement, which is specific to MySQL), you should
implement the same feature for other SQL servers by coding an alternative
method. Although the alternative may be slower, it will allow the other
servers to perform the same tasks.

With MySQL, you can use the @code{/*!  */} syntax to add MySQL-specific
keywords to a query.  The code inside @code{/**/} will be treated as a
comment (and ignored) by most other SQL servers.

If high performance is more important than exactness, as in some
Web applications, it is possible to create an application layer that
caches all results to give you even higher performance. By letting
old results ``expire'' after a while, you can keep the cache reasonably
fresh.  This provides a method to handle high load spikes, in which case
you can dynamically increase the cache and set the expiration timeout higher
until things get back to normal.

In this case, the table creation information should contain information
of the initial size of the cache and how often the table should normally
be refreshed.

An alternative to implementing an application cache is to use the MySQL query
cache. By enabling the query cache, the server handles the details of
determining whether a query result can be reused. This simplifies your
application.
@xref{Query Cache}.


@node Internal use, MySQL Benchmarks, Portability, Optimize Overview
@subsection What We Have Used MySQL For

@cindex uses, of MySQL
@cindex customers, of MySQL

This section describes an early application for MySQL.

During MySQL initial development, the features of MySQL
were made to fit our largest customer, which handled data warehousing for a
couple of the largest retailers in Sweden.

From all stores, we got weekly summaries of all bonus card transactions,
and were expected to provide useful information for the store owners
to help them find how their advertising campaigns were affecting their
own customers.

The volume of data was quite huge (about seven million summary transactions
per month), and we had data for 4-10 years that we needed to present to
the users.  We got weekly requests from our customers, who wanted to get
``instant'' access to new reports from this data.

We solved this problem by storing all information per month in compressed
``transaction'' tables. We had a set of simple macros that
generated summary tables grouped by different criteria (product group,
customer id, store, and so on) from the tables in which the transactions
were stored.  The reports were Web pages that were dynamically generated
by a small Perl script. This script parsed a Web page, executed the SQL
statements in it, and inserted the results. We would have used PHP or
mod_perl instead, but they were not available at the time.

For graphical data, we wrote a simple tool in C that could process SQL
query results and produce GIF images based on those results.  This tool also
was dynamically executed from the Perl script that parses the Web pages.

In most cases, a new report could be created simply by copying an existing
script and modifying the SQL query in it.  In some cases, we needed to
add more columns to an existing summary table or generate a new one.
This also was quite simple because we kept all transaction-storage tables
on disk.  (This amounted to about 50GB of transaction tables and 200GB
of other customer data.)

We also let our customers access the summary tables directly with ODBC
so that the advanced users could experiment with the data themselves.

This system worked well and we had no problems handling the data with
quite modest Sun Ultra SPARCstation hardware (2x200MHz). Eventually the
system was migrated to Linux.


@node MySQL Benchmarks, Custom Benchmarks, Internal use, Optimize Overview
@subsection The MySQL Benchmark Suite

@cindex benchmark suite
@cindex crash-me program

This section should contain a technical description of the MySQL
benchmark suite (and @code{crash-me}), but that description has not yet
been written. Currently, you can get a good idea of the benchmarks by
looking at the code and results in the @file{sql-bench} directory in any
MySQL source distribution.

This benchmark suite is meant to tell any user what operations a given
SQL implementation performs well or poorly.

Note that this benchmark is single-threaded, so it measures the minimum
time for the operations performed. We plan to add multi-threaded tests to
the benchmark suite in the future.

To use the benchmark suite, the following requirements must be satisfied:

@itemize @bullet
@item
The benchmark suite is provided with MySQL source distributions.
You can either download a released distribution from
@uref{http://dev.mysql.com/downloads/}, or use the current development
source tree (@pxref{Installing source tree}).

@item
The benchmark scripts are written in Perl and use the Perl DBI module to
access database servers, so DBI must be installed.  You will also need
the server-specific DBD drivers for each of the servers you want to test.
For example, to test MySQL, PostgreSQL, and DB2, you must have the
@code{DBD::mysql}, @code{DBD::Pg}, and @code{DBD::DB2} modules installed.
@xref{Perl support}.

@end itemize

After you obtain a MySQL source distribution, you will find the benchmark
suite located in its @file{sql-bench} directory.  To run the benchmark tests,
build MySQL, then
change location into the @file{sql-bench} directory and execute the @code{run-all-tests}
script:

@example
shell> cd sql-bench
shell> perl run-all-tests --server=@var{server_name}
@end example

@var{server_name} is one of the supported servers. To get a list of
all options and supported servers, invoke this command:

@example
shell> perl run-all-tests --help
@end example

@cindex crash-me
The @code{crash-me} script also is located in the @file{sql-bench} directory.
@code{crash-me} tries to determine what features a database supports and
what its capabilities and limitations are by actually running
queries. For example, it determines:

@itemize @bullet
@item
What column types are supported
@item
How many indexes are supported
@item
What functions are supported
@item
How big a query can be
@item
How big a @code{VARCHAR} column can be
@end itemize

You can find the results from @code{crash-me} for many different database
servers at @uref{http://dev.mysql.com/tech-resources/crash-me.php}.
For more information about benchmark results, visit
@uref{http://dev.mysql.com/tech-resources/benchmarks/}.


@node Custom Benchmarks,  , MySQL Benchmarks, Optimize Overview
@subsection Using Your Own Benchmarks

@cindex benchmarks
@cindex performance, benchmarks

You should definitely benchmark your application and database to find
out where the bottlenecks are.  By fixing a bottleneck (or by replacing it
with a ``dummy module''), you can then easily identify the next
bottleneck.  Even if the overall performance for your
application currently is acceptable, you should at least make a plan for each
bottleneck, and decide how to solve it if someday you really need the
extra performance.

For an example of portable benchmark programs, look at the MySQL
benchmark suite. @xref{MySQL Benchmarks, , MySQL Benchmarks}. You
can take any program from this suite and modify it for your needs. By doing
this, you can try different solutions to your problem and test which really is
fastest for you.

Another free benchmark suite is the Open Source Database Benchmark,
available at @uref{http://osdb.sourceforge.net/}.

It is very common for a problem to occur only when the system is very
heavily loaded. We have had many customers who contact us when they
have a (tested) system in production and have encountered load problems. In
most cases, performance problems turn out to be due to issues of basic
database design (for example, table scans are @emph{not good} at high load) or
problems with the operating system or libraries. Most of the time, these
problems would be a @emph{lot} easier to fix if the systems were not
already in production.

To avoid problems like this, you should put some effort into benchmarking
your whole application under the worst possible load!  You can use
Super Smack for this. It is available at
@uref{http://jeremy.zawodny.com/mysql/super-smack/}.
As the name suggests, it can bring a system to its knees if you ask it,
so make sure to use it only on your development systems.


@node Query Speed, Locking Issues, Optimize Overview, MySQL Optimization
@section Optimizing @code{SELECT} Statements and Other Queries

@cindex queries, speed of
@cindex permission checks, effect on speed
@cindex speed, of queries

First, one factor affects all statements: The more complex your permission
setup is, the more overhead you will have.

Using simpler permissions when you issue @code{GRANT} statements enables
MySQL to reduce permission-checking overhead when clients execute
statements.  For example, if you don't grant any table-level or column-level
privileges, the server need not ever check the contents of the
@code{tables_priv} and @code{columns_priv} tables. Similarly, if you place
no resource limits on any accounts, the server does not have to perform
resource counting.  If you have a very high query volume, it may be worth
the time to use a simplified grant structure to reduce permission-checking
overhead.

If your problem is with some specific MySQL expression or function, you can
use the @code{BENCHMARK()} function from the @command{mysql} client program
to perform a timing test. Its syntax is
@code{BENCHMARK(@var{loop_count},@var{expression})}. For example:

@example
mysql> SELECT BENCHMARK(1000000,1+1);
+------------------------+
| BENCHMARK(1000000,1+1) |
+------------------------+
|                      0 |
+------------------------+
1 row in set (0.32 sec)
@end example

This result was obtained on a Pentium II 400MHz system. It shows that
MySQL can execute 1,000,000 simple addition expressions in 0.32 seconds
on that system.

All MySQL functions should be very optimized, but there may be some
exceptions. @code{BENCHMARK()} is a great tool to find out if this is a
problem with your query.

@menu
* EXPLAIN::                     @code{EXPLAIN} Syntax (Get Information About a @code{SELECT})
* Estimating performance::      Estimating Query Performance
* SELECT speed::                Speed of @code{SELECT} Queries
* Where optimizations::         How MySQL Optimizes @code{WHERE} Clauses
* Range optimization::          Range Optimization
* Index Merge optimization::    Index Merge Optimization
* IS NULL optimization::        How MySQL Optimizes @code{IS NULL}
* DISTINCT optimization::       How MySQL Optimizes @code{DISTINCT}
* LEFT JOIN optimization::      How MySQL Optimizes @code{LEFT JOIN} and @code{RIGHT JOIN}
* ORDER BY optimization::       How MySQL Optimizes @code{ORDER BY}
* GROUP BY optimization::       How MySQL Optimizes @code{GROUP BY}
* LIMIT optimization::          How MySQL Optimizes @code{LIMIT}
* How to avoid table scan::     How to Avoid Table Scans
* Insert speed::                Speed of @code{INSERT} Statements
* Update speed::                Speed of @code{UPDATE} Statements
* Delete speed::                Speed of @code{DELETE} Statements
* Tips::                        Other Optimization Tips
@end menu


@node EXPLAIN, Estimating performance, Query Speed, Query Speed
@subsection @code{EXPLAIN} Syntax (Get Information About a @code{SELECT})

@findex EXPLAIN
@findex SELECT, optimizing

@c help_category Data Manipulation

@c example_for_help_topic EXPLAIN
@example
EXPLAIN @var{tbl_name}
@end example

Or:

@example
EXPLAIN SELECT @var{select_options}
@end example

@c description_for_help_topic EXPLAIN  SELECT
The @code{EXPLAIN} statement can be used either as a synonym for
@code{DESCRIBE} or as a way to obtain information about how MySQL will execute
a @code{SELECT} statement:

@itemize @bullet
@item
The @code{EXPLAIN @var{tbl_name}} syntax is synonymous with @code{DESCRIBE @var{tbl_name}}
or
@code{SHOW COLUMNS FROM @var{tbl_name}}.
@item
When you precede a @code{SELECT} statement with the keyword @code{EXPLAIN},
MySQL explains how it would process the @code{SELECT}, providing
information about how tables are joined and in which order.
@end itemize
@c end_description_for_help_topic

This section provides information about the second use of @code{EXPLAIN}.

With the help of @code{EXPLAIN}, you can see when you must add indexes
to tables to get a faster @code{SELECT} that uses indexes to find
records.

If you have a problem with incorrect index usage, you should run
@code{ANALYZE TABLE} to update table statistics such as cardinality of
keys, which can affect the choices the optimizer makes. @xref{ANALYZE
TABLE, , @code{ANALYZE TABLE}}.

You can also see whether the optimizer joins the tables in an optimal order.
To force the optimizer to use a join order corresponding to the order
in which the tables are named in the @code{SELECT} statement, begin the
statement with @code{SELECT STRAIGHT_JOIN} rather than just @code{SELECT}.

@code{EXPLAIN} returns a row of information for each table used in the
@code{SELECT} statement. The tables are listed in the output in the order
that MySQL would read them while processing the query.  MySQL resolves
all joins using a single-sweep
multi-join method. This means that MySQL reads a row from the first
table, then finds a matching row in the second table, then in the third table,
and so on. When all tables are processed, it outputs the selected columns and
backtracks through the table list until a table is found for which there are
more matching rows. The next row is read from this table and the process
continues with the next table.

In MySQL version 4.1, the @code{EXPLAIN} output format was changed to work
better with constructs such as @code{UNION} statements, subqueries, and
derived tables. Most notable is the addition of two new columns: @code{id}
and @code{select_type}. You will not see these columns when using servers
older than MySQL 4.1.

Each output row from @code{EXPLAIN} provides information about one table, and
each row consists of the following columns:

@table @code
@item id
The @code{SELECT} identifier. This is the sequential number of the
@code{SELECT} within the query.

@item select_type
The type of @code{SELECT}, which can be any of the following:

@table @code
@item SIMPLE
Simple @code{SELECT} (not using @code{UNION} or subqueries)

@item PRIMARY
Outermost @code{SELECT}

@item UNION
Second or later @code{SELECT} statement in a @code{UNION}

@item DEPENDENT UNION
Second or later @code{SELECT} statement in a @code{UNION}, dependent on outer
query

@item UNION RESULT
Result of a @code{UNION}.

@item SUBQUERY
First @code{SELECT} in subquery

@item DEPENDENT SUBQUERY
First @code{SELECT} in subquery, dependent on outer query

@item DERIVED
Derived table @code{SELECT} (subquery in @code{FROM} clause)
@end table

@item table
The table to which the row of output refers.

@item type
The join type. The different join types are listed here, ordered from the
best type to the worst:

@table @code
@item system
@cindex system table
@cindex tables, system
The table has only one row (= system table). This is a special case of
the @code{const} join type.

@item const
@cindex constant table
@cindex tables, constant
The table has at most one matching row, which will be read at the start
of the query. Because there is only one row, values from the column in
this row can be regarded as constants by the rest of the
optimizer. @code{const} tables are very fast because they are read only once!

@code{const} is used when you compare all parts of a
@code{PRIMARY KEY} or @code{UNIQUE} index with constant values. In the
following queries, @var{tbl_name} can be used as a @code{const} table:

@example
SELECT * FROM @var{tbl_name} WHERE @var{primary_key}=1;

SELECT * FROM @var{tbl_name}
WHERE @var{primary_key_part1}=1 AND @var{primary_key_part2}=2;
@end example

@item eq_ref
One row will be read from this table for each combination of rows from
the previous tables.  Other than the @code{const} types, this is the best
possible join type.  It is used when all parts of an index are used by
the join and the index is a @code{PRIMARY KEY} or @code{UNIQUE} index.

@code{eq_ref} can be used for indexed columns that are compared using the
@code{=} operator.  The comparison value can be a constant or an expression
that uses columns from tables that are read before this table.

In the following examples, MySQL can use an @code{eq_ref} join to process
@var{ref_table}:

@example
SELECT * FROM @var{ref_table},@var{other_table}
WHERE @var{ref_table}.@var{key_column}=@var{other_table}.@var{column};

SELECT * FROM @var{ref_table},@var{other_table}
WHERE @var{ref_table}.@var{key_column_part1}=@var{other_table}.@var{column}
AND @var{ref_table}.@var{key_column_part2}=1;
@end example

@item ref
All rows with matching index values will be read from this table for
each combination of rows from the previous tables.  @code{ref} is used
if the join uses only a leftmost prefix of the key or if the key is not
a @code{PRIMARY KEY} or @code{UNIQUE} index (in other words, if the join
cannot select a single row based on the key value).  If the key that is
used matches only a few rows, this is a good join type.

@code{ref} can be used for indexed columns that are compared using the @code{=}
operator.

In the following examples, MySQL can use a @code{ref} join to process
@var{ref_table}:

@example
SELECT * FROM @var{ref_table} WHERE @var{key_column}=@var{expr};

SELECT * FROM @var{ref_table},@var{other_table}
WHERE @var{ref_table}.@var{key_column}=@var{other_table}.@var{column};

SELECT * FROM @var{ref_table},@var{other_table}
WHERE @var{ref_table}.@var{key_column_part1}=@var{other_table}.@var{column}
AND @var{ref_table}.@var{key_column_part2}=1;
@end example

@item ref_or_null
This join type is like @code{ref}, but with the addition that MySQL will
do an extra search for rows that contain @code{NULL} values.  This join
type optimization is new for MySQL 4.1.1 and is mostly used when resolving
subqueries.

In the following examples, MySQL can use a @code{ref_or_null} join to process
@var{ref_table}:

@example
SELECT * FROM @var{ref_table}
WHERE @var{key_column}=@var{expr} OR @var{key_column} IS NULL; 
@end example


@xref{IS NULL optimization, , @code{IS NULL} optimization}.

@item index_merge
This join type indicates that the Index Merge optimization is used.
In this case, the @code{key} column contains a list of indexes used, and
@code{key_len} contains a list of the longest key parts for the indexes
used.  For more information, see
@ref{Index Merge optimization}.

@item unique_subquery
This type replaces @code{ref} for some @code{IN} subqueries of the following
form:
@example
@var{value} IN (SELECT @var{primary_key} FROM @var{single_table} WHERE @var{some_expr}) 
@end example
@code{unique_subquery} is just an index lookup function that replaces the
subquery completely for better efficiency.

@item index_subquery
This join type is similar to
@code{unique_subquery}. It replaces @code{IN} subqueries, but
it works for non-unique indexes in subqueries of the following form:

@example
@var{value} IN (SELECT @var{key_column} FROM @var{single_table} WHERE @var{some_expr}) 
@end example

@item range
Only rows that are in a given range will be retrieved, using an index to
select the rows.  The @code{key} column indicates which index is used.
The @code{key_len} contains the longest key part that was used.
The @code{ref} column will be @code{NULL} for this type.

@code{range} can be used for when a key column is compared to a
constant using any of the @code{=}, @code{<>}, @code{>}, @code{>=}, @code{<},
@code{<=}, @code{IS NULL}, @code{<=>}, @code{BETWEEN}, or @code{IN} operators:

@example
SELECT * FROM @var{tbl_name}
WHERE @var{key_column} = 10;

SELECT * FROM @var{tbl_name}
WHERE @var{key_column} BETWEEN 10 and 20;

SELECT * FROM @var{tbl_name}
WHERE @var{key_column} IN (10,20,30);

SELECT * FROM @var{tbl_name}
WHERE @var{key_part1}= 10 AND @var{key_part2} IN (10,20,30);
@end example

@item index
This join type is the same as @code{ALL}, except that only the index tree
is scanned.  This usually is faster than @code{ALL}, because the index
file usually is smaller than the data file.

MySQL can use this join type when the query uses only columns that are
part of a single index.

@item ALL
A full table scan will be done for each combination of rows from the
previous tables.  This is normally not good if the table is the first
table not marked @code{const}, and usually @emph{very} bad in all other
cases. Normally, you can avoid @code{ALL} by adding indexes that allow row
retrieval from the table based on constant values or column values from
earlier tables.
@end table

@item possible_keys
The @code{possible_keys} column indicates which indexes MySQL could use to
find the rows in this table. Note that this column is totally independent of
the order of the tables as displayed in the output from @code{EXPLAIN}. That
means that some of the keys in @code{possible_keys} might not be usable in
practice with the generated table order.

If this column is @code{NULL}, there are no relevant indexes. In this case,
you may be able to improve the performance of your query by examining
the @code{WHERE} clause to see whether it refers to some column or columns
that would be suitable for indexing.  If so, create an appropriate index
and check the query with @code{EXPLAIN} again.
@xref{ALTER TABLE,  , @code{ALTER TABLE}}.

To see what indexes a table has, use @code{SHOW INDEX FROM @var{tbl_name}}.

@item key
The @code{key} column indicates the key (index) that MySQL actually decided
to use. The key is @code{NULL} if no index was chosen. To force MySQL
to use or ignore an index listed in the @code{possible_keys} column, use
@code{FORCE INDEX}, @code{USE INDEX}, or @code{IGNORE INDEX} in your query.
@xref{SELECT,  , @code{SELECT}}.

For @code{MyISAM} and @code{BDB} tables, running @code{ANALYZE TABLE}
will help the optimizer choose better indexes.  For @code{MyISAM} tables,
@command{myisamchk --analyze} will do the same.  See @ref{ANALYZE TABLE, ,
@code{ANALYZE TABLE}} and @ref{Table maintenance}.

@item key_len
The @code{key_len} column indicates the length of the key that MySQL
decided to use.  The length is @code{NULL} if the @code{key} column says
@code{NULL}. Note that the value of @code{key_len} allows you to determine
how many parts of a multiple-part key MySQL will actually use.

@item ref
The @code{ref} column shows which columns or constants are used with the
@code{key} to select rows from the table.

@c TODO: we don't seem to explain what ref values of "const", NULL, or
@c @var{tbl_name.col_name} mean.

@item rows
The @code{rows} column indicates the number of rows MySQL
believes it must examine to execute the query.

@item Extra
This column contains additional information about how MySQL will
resolve the query. Here is an explanation of the different text
strings that can appear in this column:

@table @code
@item Distinct
MySQL will stop searching for more rows for the current row
combination after it has found the first matching row.

@item Not exists
MySQL was able to do a @code{LEFT JOIN} optimization on the
query and will not examine more rows in this table for the previous row
combination after it finds one row that matches the @code{LEFT JOIN} criteria.

Here is an example of the type of query that can be optimized this way:

@example
SELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.id
WHERE t2.id IS NULL;
@end example

Assume that @code{t2.id} is defined as @code{NOT NULL}.  In this case,
MySQL will scan @code{t1} and look up the rows in @code{t2} using the values
of @code{t1.id}. If MySQL finds a matching row in @code{t2}, it knows that
@code{t2.id} can never be @code{NULL}, and will not scan through the rest
of the rows in @code{t2} that have the same @code{id} value.  In other
words, for each row in @code{t1}, MySQL needs to do only a single lookup
in @code{t2}, regardless of how many rows actually match in @code{t2}.

@item @code{range checked for each record (index map: #)}
MySQL found no good index to use, but found that some of indexes might
be used once column values from preceding tables are known.  For each
row combination in the preceding tables, MySQL will check whether it is
possible to use a @code{range} or @code{index_merge} access method to
retrieve rows. The applicability criteria are as described in @ref{Range
optimization}
and @ref{Index Merge optimization}, with the exception that all column values for the
preceding table are known and considered to be constants.

This is not very fast, but is faster than performing a join with no index
at all.

@item Using filesort
MySQL will need to do an extra pass to find out how to retrieve
the rows in sorted order.  The sort is done by going through all rows
according to the join type and storing the sort key and pointer to
the row for all rows that match the @code{WHERE} clause. The keys then are
sorted and the rows are retrieved in sorted order.
@xref{ORDER BY optimization,  , @code{ORDER BY} optimization}.

@item Using index
The column information is retrieved from the table using only
information in the index tree without having to do an additional seek to
read the actual row.  This strategy can be used when the query uses only
columns that are part of a single index.

@item Using temporary
To resolve the query, MySQL will need to create a temporary table to hold
the result.  This typically happens if the query contains @code{GROUP BY}
and @code{ORDER BY} clauses that list columns differently.

@item Using where
A @code{WHERE} clause will be used to restrict which rows to match
against the next table or send to the client. Unless you specifically intend
to fetch or examine all rows from the table, you may have something wrong
in your query if the @code{Extra} value is not @code{Using where}
and the table join type is @code{ALL} or @code{index}.

If you want to make your queries as fast as possible, you should look out for
@code{Extra} values of @code{Using filesort} and @code{Using temporary}.

@item Using sort_union(...)
@itemx Using union(...)
@itemx Using intersect(...)

These indicate how index scans are merged for the @code{index_merge}
join type.  See @ref{Index Merge optimization} for more information.

@item Using index for group-by

Similar to the @code{Using index} way of accessing a table, @code{Using
index for group-by} indicates that MySQL found an index that can be used
to retrieve all columns of a @code{GROUP BY} or @code{DISTINCT} query
without any extra disk access to the actual table. Additionally, the index
will be used in the most efficient way so that for each group, only a few
index entries will be read. For details, see
@ref{GROUP BY optimization,  , @code{GROUP BY} optimization}.
@end table

@end table

You can get a good indication of how good a join is by taking the
product of the values in the @code{rows} column of the @code{EXPLAIN}
output. This should tell you roughly how many rows MySQL must examine to
execute the query.  If you restrict queries with the @code{max_join_size}
system variable, this product also is used to determine which multiple-table
@code{SELECT} statements to execute.
@xref{Server parameters}.

The following example shows how a multiple-table join can be optimized
progressively based on the information provided by @code{EXPLAIN}.

Suppose that you have the @code{SELECT} statement shown here and you plan to
examine it using @code{EXPLAIN}:

@example
EXPLAIN SELECT tt.TicketNumber, tt.TimeIn,
            tt.ProjectReference, tt.EstimatedShipDate,
            tt.ActualShipDate, tt.ClientID,
            tt.ServiceCodes, tt.RepetitiveID,
            tt.CurrentProcess, tt.CurrentDPPerson,
            tt.RecordVolume, tt.DPPrinted, et.COUNTRY,
            et_1.COUNTRY, do.CUSTNAME
        FROM tt, et, et AS et_1, do
        WHERE tt.SubmitTime IS NULL
            AND tt.ActualPC = et.EMPLOYID
            AND tt.AssignedPC = et_1.EMPLOYID
            AND tt.ClientID = do.CUSTNMBR;
@end example

For this example, make the following assumptions:

@itemize @bullet
@item
The columns being compared have been declared as follows:

@multitable @columnfractions .10 .25 .25
@item @strong{Table} @tab @strong{Column} @tab @strong{Column Type}
@item @code{tt}      @tab @code{ActualPC}      @tab @code{CHAR(10)}
@item @code{tt}      @tab @code{AssignedPC}    @tab @code{CHAR(10)}
@item @code{tt}      @tab @code{ClientID}      @tab @code{CHAR(10)}
@item @code{et}      @tab @code{EMPLOYID}      @tab @code{CHAR(15)}
@item @code{do}      @tab @code{CUSTNMBR}      @tab @code{CHAR(15)}
@end multitable

@item
The tables have the following indexes:

@multitable @columnfractions .10 .40
@item @strong{Table} @tab @strong{Index}
@item @code{tt}      @tab @code{ActualPC}
@item @code{tt}      @tab @code{AssignedPC}
@item @code{tt}      @tab @code{ClientID}
@item @code{et}      @tab @code{EMPLOYID} (primary key)
@item @code{do}      @tab @code{CUSTNMBR} (primary key)
@end multitable

@item
The @code{tt.ActualPC} values are not evenly distributed.
@end itemize

Initially, before any optimizations have been performed, the @code{EXPLAIN}
statement produces the following information:

@example
table type possible_keys key  key_len ref  rows  Extra
et    ALL  PRIMARY       NULL NULL    NULL 74
do    ALL  PRIMARY       NULL NULL    NULL 2135
et_1  ALL  PRIMARY       NULL NULL    NULL 74
tt    ALL  AssignedPC,   NULL NULL    NULL 3872
           ClientID,
           ActualPC
      range checked for each record (key map: 35)
@end example

Because @code{type} is @code{ALL} for each table, this output indicates
that MySQL is generating a Cartesian product of all the tables; that is,
every combination of rows.  This will take quite a long time, because the
product of the number of rows in each table must be examined.  For the case
at hand, this product is @code{74 * 2135 * 74 * 3872 = 45,268,558,720} rows.
If the tables were bigger, you can only imagine how long it would take.

One problem here is that MySQL can use indexes on columns more efficiently
if they are declared the same. (For @code{ISAM} tables, indexes may not be
used at all unless the columns are declared the same.)  In this context,
@code{VARCHAR} and @code{CHAR} are the same unless they are declared as
different lengths. Because @code{tt.ActualPC} is declared as @code{CHAR(10)}
and @code{et.EMPLOYID} is declared as @code{CHAR(15)}, there is a length
mismatch.

To fix this disparity between column lengths, use @code{ALTER TABLE} to
lengthen @code{ActualPC} from 10 characters to 15 characters:

@example
mysql> ALTER TABLE tt MODIFY ActualPC VARCHAR(15);
@end example

Now @code{tt.ActualPC} and @code{et.EMPLOYID} are both @code{VARCHAR(15)}.
Executing the @code{EXPLAIN} statement again produces this result:

@example
table type   possible_keys key     key_len ref         rows    Extra
tt    ALL    AssignedPC,   NULL    NULL    NULL        3872    Using
             ClientID,                                         where
             ActualPC
do    ALL    PRIMARY       NULL    NULL    NULL        2135
      range checked for each record (key map: 1)
et_1  ALL    PRIMARY       NULL    NULL    NULL        74
      range checked for each record (key map: 1)
et    eq_ref PRIMARY       PRIMARY 15      tt.ActualPC 1
@end example

This is not perfect, but is much better: The product of the @code{rows}
values is now less by a factor of 74. This version is executed in a couple
of seconds.

A second alteration can be made to eliminate the column length mismatches
for the @code{tt.AssignedPC = et_1.EMPLOYID} and @code{tt.ClientID =
do.CUSTNMBR} comparisons:

@example
mysql> ALTER TABLE tt MODIFY AssignedPC VARCHAR(15),
    ->                MODIFY ClientID   VARCHAR(15);
@end example

Now @code{EXPLAIN} produces the output shown here:

@example
table type   possible_keys key      key_len ref           rows Extra
et    ALL    PRIMARY       NULL     NULL    NULL          74
tt    ref    AssignedPC,   ActualPC 15      et.EMPLOYID   52   Using
             ClientID,                                         where
             ActualPC
et_1  eq_ref PRIMARY       PRIMARY  15      tt.AssignedPC 1
do    eq_ref PRIMARY       PRIMARY  15      tt.ClientID   1
@end example

This is almost as good as it can get.

The remaining problem is that, by default, MySQL assumes that values
in the @code{tt.ActualPC} column are evenly distributed, and that is not the
case for the @code{tt} table.  Fortunately, it is easy to tell MySQL
to analyze the key distribution:

@example
mysql> ANALYZE TABLE tt;
@end example

@c @example
@c shell> myisamchk --analyze PATH_TO_MYSQL_DATABASE/tt
@c shell> mysqladmin refresh
@c @end example

Now the join is perfect, and @code{EXPLAIN} produces this result:

@example
table type   possible_keys key     key_len ref           rows Extra
tt    ALL    AssignedPC    NULL    NULL    NULL          3872 Using
             ClientID,                                        where
             ActualPC
et    eq_ref PRIMARY       PRIMARY 15      tt.ActualPC   1
et_1  eq_ref PRIMARY       PRIMARY 15      tt.AssignedPC 1
do    eq_ref PRIMARY       PRIMARY 15      tt.ClientID   1
@end example

Note that the @code{rows} column in the output from @code{EXPLAIN} is an
educated guess from the MySQL join optimizer.  You should check whether the
numbers are even close to the truth.  If not, you may get better performance
by using @code{STRAIGHT_JOIN} in your @code{SELECT} statement and trying
to list the tables in a different order in the @code{FROM} clause.


@node Estimating performance, SELECT speed, EXPLAIN, Query Speed
@subsection Estimating Query Performance

@cindex estimating, query performance
@cindex queries, estimating performance
@cindex performance, estimating

In most cases, you can estimate the performance by counting disk seeks.
For small tables, you can usually find a row in one disk seek (because the
index is probably cached).  For bigger tables, you can estimate that,
using B-tree indexes, you will need this many seeks to find a row:
@code{log(@var{row_count}) / log(@var{index_block_length} / 3 * 2 /
(@var{index_length} + @var{data_pointer_length})) +
1}.

In MySQL, an index block is usually 1024 bytes and the data
pointer is usually 4 bytes. For a 500,000-row table with an
index length of 3 bytes (medium integer), the formula indicates
@code{log(500,000)/log(1024/3*2/(3+4)) + 1} = @code{4} seeks.

This index would require storage of about 500,000 * 7 * 3/2 = 5.2MB
(assuming a typical index buffer fill ratio of 2/3), so
you will probably have much of the index in memory and you will probably
need only one or two calls to read data to find the row.

For writes, however, you will need four seek requests (as above) to find
where to place the new index and normally two seeks to update the index
and write the row.

Note that the preceding discussion doesn't mean that your application
performance will slowly degenerate by log N!  As long as everything
is cached by the OS or SQL server, things will become only marginally
slower as the table gets bigger. After the data gets too big to be cached,
things will start to go much slower until your applications is only bound
by disk-seeks (which increase by log @var{N}). To avoid this, increase the key
cache size as the data grows.  For @code{MyISAM} tables, the key cache
size is controlled by the @code{key_buffer_size} system variable.
@xref{Server parameters}.


@node SELECT speed, Where optimizations, Estimating performance, Query Speed
@subsection Speed of @code{SELECT} Queries

@findex SELECT speed

@cindex speed, of queries

In general, when you want to make a slow @code{SELECT ... WHERE} query
faster, the first thing to check is whether you can add an index.
All references between different tables should usually be done with
indexes. You can use the @code{EXPLAIN} statement to determine which
indexes are used for a @code{SELECT}.
See @ref{MySQL indexes, , MySQL indexes} and
@ref{EXPLAIN, , @code{EXPLAIN}}.

Some general tips for speeding up queries on @code{MyISAM} tables:

@itemize @bullet
@item
To help MySQL optimize queries better, use @code{ANALYZE TABLE} or
run @command{myisamchk --analyze} on a table after it has been loaded with
data. This updates a value for each index part that indicates the average
number of rows that have the same value.  (For unique indexes, this is
always 1.)  MySQL will use this to decide which index to choose when you
join two tables based on a non-constant expression.  You can check the
result from the table analysis by using @code{SHOW INDEX FROM @var{tbl_name}}
and examining the @code{Cardinality} value.  @command{myisamchk --description
--verbose} shows index distribution information.

@item
To sort an index and data according to an index, use @command{myisamchk
--sort-index --sort-records=1} (if you want to sort on index 1). This is
a good way to make queries faster if you have a unique index from which
you want to read all records in order according to the index.  Note that
the first time you sort a large table this way, it may take a long time.
@end itemize


@node Where optimizations, Range optimization, SELECT speed, Query Speed
@subsection How MySQL Optimizes @code{WHERE} Clauses

@findex WHERE

@cindex optimizations

This section discusses optimizations that can be made for processing
@code{WHERE} clauses. The examples use @code{SELECT} statements, but
the same optimizations apply for @code{WHERE} clauses in @code{DELETE}
and @code{UPDATE} statements.

Note that work on the MySQL optimizer is ongoing, so this section is
incomplete. MySQL does many optimizations, not all of which are documented
here.

Some of the optimizations performed by MySQL are listed here:

@itemize @bullet
@item
Removal of unnecessary parentheses:
@example
   ((a AND b) AND c OR (((a AND b) AND (c AND d))))
-> (a AND b AND c) OR (a AND b AND c AND d)
@end example
@item
Constant folding:
@example
   (a<b AND b=c) AND a=5
-> b>5 AND b=c AND a=5
@end example
@item
Constant condition removal (needed because of constant folding):
@example
   (B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6)
-> B=5 OR B=6
@end example
@item
Constant expressions used by indexes are evaluated only once.
@item
@code{COUNT(*)} on a single table without a @code{WHERE} is retrieved
directly from the table information for @code{MyISAM} and @code{HEAP} tables.
This is also done for any @code{NOT NULL} expression when used with only one
table.
@item
Early detection of invalid constant expressions. MySQL quickly
detects that some @code{SELECT} statements are impossible and returns no rows.
@item
@code{HAVING} is merged with @code{WHERE} if you don't use @code{GROUP BY}
or group functions (@code{COUNT()}, @code{MIN()}, and so on).
@item
For each table in a join, a simpler @code{WHERE} is constructed to get a fast
@code{WHERE} evaluation for the table and also to skip records as
soon as possible.
@cindex constant table
@cindex tables, constant
@item
All constant tables are read first before any other tables in the query.
A constant table is any of the following:
@itemize @minus
@item
An empty table or a table with one row.
@item
A table that is used with a @code{WHERE} clause on a @code{PRIMARY KEY}
or a @code{UNIQUE} index, where all index parts are compared to constant
expressions and are defined as @code{NOT NULL}.
@end itemize
All of the following tables are used as constant tables:

@example
SELECT * FROM t WHERE @var{primary_key}=1;
SELECT * FROM t1,t2
    WHERE t1.@var{primary_key}=1 AND t2.@var{primary_key}=t1.id;
@end example

@item
The best join combination for joining the tables is found by trying all
possibilities. If all columns in @code{ORDER BY} and @code{GROUP
BY} clauses come from the same table, that table is preferred first when
joining.
@item
If there is an @code{ORDER BY} clause and a different @code{GROUP BY}
clause, or if the @code{ORDER BY} or @code{GROUP BY} contains columns
from tables other than the first table in the join queue, a temporary
table is created.
@item
If you use @code{SQL_SMALL_RESULT}, MySQL uses an in-memory
temporary table.
@item
Each table index is queried, and the best index is used unless the optimizer
believes that it will be more efficient to use a table scan. At one time, a
scan was used based on whether the best index spanned more than 30% of the
table.  Now the optimizer is more complex and bases its estimate on
additional factors such as table size, number of rows, and I/O block size,
so a fixed percentage no longer determines the choice between using an index
or a scan.
@item
In some cases, MySQL can read rows from the index without even
consulting the data file.  If all columns used from the index are numeric,
only the index tree is used to resolve the query.
@item
Before each record is output, those that do not match the @code{HAVING} clause
are skipped.
@end itemize

Some examples of queries that are very fast:

@example
SELECT COUNT(*) FROM @var{tbl_name};

SELECT MIN(@var{key_part1}),MAX(@var{key_part1}) FROM @var{tbl_name};

SELECT MAX(@var{key_part2}) FROM @var{tbl_name}
    WHERE @var{key_part1}=@var{constant};

SELECT ... FROM @var{tbl_name}
    ORDER BY @var{key_part1},@var{key_part2},... LIMIT 10;

SELECT ... FROM @var{tbl_name}
    ORDER BY @var{key_part1} DESC, @var{key_part2} DESC, ... LIMIT 10;
@end example

The following queries are resolved using only the index tree, assuming
that the indexed columns are numeric:

@example
SELECT @var{key_part1},@var{key_part2} FROM @var{tbl_name} WHERE @var{key_part1}=@var{val};

SELECT COUNT(*) FROM @var{tbl_name}
    WHERE @var{key_part1}=@var{val1} AND @var{key_part2}=@var{val2};

SELECT @var{key_part2} FROM @var{tbl_name} GROUP BY @var{key_part1};
@end example

The following queries use indexing to retrieve the rows in sorted
order without a separate sorting pass:

@example
SELECT ... FROM @var{tbl_name}
    ORDER BY @var{key_part1},@var{key_part2},... ;

SELECT ... FROM @var{tbl_name}
    ORDER BY @var{key_part1} DESC, @var{key_part2} DESC, ... ;
@end example


@node Range optimization, Index Merge optimization, Where optimizations, Query Speed
@subsection Range Optimization

The @code{range} access method uses a single index to retrieve a subset
of table records that are contained within one or several index value
intervals. It can be used for a single-part or multiple-part index.
A detailed description of how intervals are extracted from the
@code{WHERE} clause is given in the following sections.

@menu
* Range access single-part::    Range Access Method for Single-Part Indexes
* Range access multi-part::     Range Access Method for Multiple-Part Indexes
@end menu

@node Range access single-part, Range access multi-part, Range optimization, Range optimization
@subsubsection Range Access Method for Single-Part Indexes

For a single-part index, index value intervals can be conveniently
represented by corresponding conditions in the @code{WHERE} clause, so
we'll talk about ``range conditions'' instead of intervals.

The definition of a range condition for a single-part index is as follows:

@itemize @bullet

@item
For both @code{BTREE} and @code{HASH} indexes, comparison of a key part with
a constant value is a range condition when using the @code{=}, @code{<=>},
@code{IN}, @code{IS NULL}, or @code{IS NOT NULL} operators.

@item
For @code{BTREE} indexes, comparison of a key part with a constant
value is a range condition when using the @code{>}, @code{<}, @code{>=},
@code{<=}, @code{BETWEEN}, @code{!=}, or @code{<>} operators, or @code{LIKE
'@var{pattern}'} (where @code{'@var{pattern}'} doesn't start with a
wildcard).

@item
For all types of indexes, multiple range conditions combined with @code{OR}
or @code{AND} form a range condition.

@end itemize

``Constant value'' in the preceding descriptions  means one of the following:

@itemize @bullet
@item
A constant from the query string
@item
A column of a @code{const} or @code{system} table from the the same join
@item
The result of an uncorrelated subquery
@item
Any expression composed entirely from subexpressions of the preceding types
@end itemize

Here are some examples of queries with range conditions in the
@code{WHERE} clause:

@example
SELECT * FROM t1 WHERE @var{key_col} > 1 AND @var{key_col} < 10;

SELECT * FROM t1 WHERE @var{key_col} = 1 OR @var{key_col} IN (15,18,20);

SELECT * FROM t1 WHERE @var{key_col} LIKE 'ab%' OR @var{key_col} BETWEEN 
'bar' AND 'foo';
@end example

Note that some non-constant values may be converted to constants during
the constant propagation phase.

MySQL tries to extract range conditions from the @code{WHERE} clause for
each of the possible indexes. During the extraction process, conditions
that can't be used for constructing the range condition are dropped,
conditions that produce overlapping ranges are combined, and conditions that
produce empty ranges are removed.

For example, consider the following statement, where @code{key1} is an
indexed column and @code{nonkey} is not indexed:

@example
SELECT * FROM t1 WHERE
   (key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR
   (key1 < 'bar' AND nonkey = 4) OR
   (key1 < 'uux' AND key1 > 'z');
@end example

The extraction process for key @code{key1} is as follows:

@enumerate
@item
Start with original @code{WHERE} clause:

@example
(key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR
(key1 < 'bar' AND nonkey = 4) OR
(key1 < 'uux' AND key1 > 'z')
@end example

@item
Remove @code{nonkey = 4} and @code{key1 LIKE '%b'} because they cannot be
used for a range scan. The right way to remove them is to replace them
with @code{TRUE}, so that we don't miss any matching records when doing
the range scan. Having replaced them with @code{TRUE}, we get:

@example
(key1 < 'abc' AND (key1 LIKE 'abcde%' OR TRUE)) OR
(key1 < 'bar' AND TRUE) OR
(key1 < 'uux' AND key1 > 'z')
@end example

@item
Collapse conditions that are always true or false:

@itemize @bullet
@item
@code{(key1 LIKE 'abcde%' OR TRUE)}  is always true
@item
@code{(key1 < 'uux' AND key1 > 'z')} is always false
@end itemize

Replacing these conditions with constants, we get:

@example
(key1 < 'abc' AND TRUE) OR (key1 < 'bar' AND TRUE) OR (FALSE)
@end example

Removing unnecessary @code{TRUE} and @code{FALSE} constants, we obtain

@example
(key1 < 'abc') OR (key1 < 'bar')
@end example

@item
Combining overlapping intervals into one yields the final condition to be used
for the range scan:

@example
(key1 < 'bar')
@end example

@end enumerate

In general (and as demonstrated in the example), the condition used for
a range scan is less restrictive than the @code{WHERE} clause. MySQL will
perform an additional check to filter out rows that satisfy the range
condition but not the full @code{WHERE} clause.

The range condition extraction algorithm can handle nested
@code{AND}/@code{OR} constructs of arbitrary depth, and its output doesn't
depend on the order in which conditions appear in @code{WHERE} clause.


@node Range access multi-part,  , Range access single-part, Range optimization
@subsubsection Range Access Method for Multiple-Part Indexes

Range conditions on a multiple-part index are an extension of range conditions
for a single-part index.  A range condition on a multiple-part index restricts
index records to lie within one or several key tuple intervals. Key
tuple intervals are defined over a set of key tuples, using ordering from
the index.

For example, consider a multiple-part index defined as
@code{key1(@var{key_part1}, @var{key_part2}, @var{key_part3})}, and the
following set of key tuples listed in key order:

@example
@var{key_part1}  @var{key_part2}  @var{key_part3}
  NULL       1          'abc'
  NULL       1          'xyz'
  NULL       2          'foo'
   1         1          'abc'
   1         1          'xyz'
   1         2          'abc'
   2         1          'aaa'
@end example

The condition @code{@var{key_part1} = 1} defines this interval:

@example
(1, -inf, -inf) <= (@var{key_part1}, @var{key_part2}, @var{key_part3}) < (1, +inf, +inf)
@end example

The interval covers the 4th, 5th, and 6th tuples in the preceding data
set and can be used by the range access method.

By contrast, the condition @code{@var{key_part3} = 'abc'} does not define a single
interval and cannot be used by the range access method.

The following descriptions indicate how range conditions work for
multiple-part indexes in greater detail.

@itemize @bullet

@item
For @code{HASH} indexes, each interval containing identical values
can be used.  This means that the interval can be produced only for
conditions in the following form:

@example
    @var{key_part1} @var{cmp} @var{const1}
AND @var{key_part2} @var{cmp} @var{const2}
AND ...
AND @var{key_partN} @var{cmp} @var{constN};
@end example

Here, @var{const1}, @var{const2}, ... are constants, @var{cmp} is one of
the @code{=}, @code{<=>}, or @code{IS NULL} comparison operators, and the
conditions cover all index parts. (That is, there are @var{N} conditions,
one for each part of an @var{N}-part index.)

See @ref{Range access single-part} for the definition of
what is considered to be a constant.

For example, the following is a range condition for a three-part
@code{HASH} index:

@example
@var{key_part1} = 1 AND @var{key_part2} IS NULL AND @var{key_part3} = 'foo'
@end example

@item
For a @code{BTREE} index, an interval might be usable for conditions
combined with @code{AND}, where each condition compares a key part with
a constant value using @code{=}, @code{<=>}, @code{IS NULL}, @code{>},
@code{<}, @code{>=}, @code{<=}, @code{!=}, @code{<>}, @code{BETWEEN}, or
@code{LIKE '@var{pattern}'} (where @code{'@var{pattern}'} doesn't start
with a wildcard).  An interval can be used as long as it is possible to
determine a single key tuple containing all records that match the condition
(or two intervals if @code{<>} or @code{!=} is used).  For example, for
this condition:

@example
@var{key_part1} = 'foo' AND @var{key_part2} >= 10 AND @var{key_part3} > 10
@end example

The single interval will be:

@example
('foo', 10, 10)
   < (@var{key_part1}, @var{key_part2}, @var{key_part3})
      < ('foo', +inf, +inf)
@end example

It is possible that
the created interval will contain more records than the initial condition.
For example, the preceding interval includes the value @code{('foo', 11, 0)},
which does not satisfy the original condition.

@item
If conditions that cover sets of records contained within intervals are
combined with @code{OR}, they form a condition that covers a set of records
contained within the union of their intervals. If the conditions are combined
with @code{AND}, they form a condition that covers a set of records
contained within the intersection of their intervals.  For example, for
this condition on a two-part index:

@example
(@var{key_part1} = 1 AND @var{key_part2} < 2)
OR (@var{key_part1} > 5)
@end example

The intervals will be:

@example
(1, -inf) < (@var{key_part1}, @var{key_part2}) < (1, 2)
(5, -inf) < (@var{key_part1}, @var{key_part2})
@end example

In this example, the interval on the first line uses one key part for the
left bound and two key parts for the right bound. The interval on the second
line uses only one key part. The @code{key_len} column in the @code{EXPLAIN}
output indicates the maximum length of the key prefix used.

In some cases, @code{key_len} may indicate that a key part was used, but
that might be not what you would expect.  Suppose that @var{key_part1}
and @var{key_part2} can be @code{NULL}.  Then the @code{key_len} column
will display two key part lengths for the following condition:

@example
@var{key_part1} >= 1 AND @var{key_part2} < 2
@end example

But in fact, the condition will be converted to this:

@example
@var{key_part1} >= 1 AND @var{key_part2} IS NOT NULL
@end example

@c The criteria of when this happens is too complicated to be specified
@c here. So maybe it's worth adding a phrase
@c "so if you need to figure out #key parts used, better use logic described
@c then simply rely in key_len value."

@end itemize

@ref{Range access single-part} describes how optimizations are performed
to combine or eliminate intervals for range conditions on single-part index.
Analogous steps are performed for range conditions on multiple-part keys.

@c Note: The result of the conversions is not visible to user. To see it
@c you must run the server with --debug, and look for enters/exits of
@c 'print_param' function.

@c TODO: resolve this
@c Note: the text above conflicts with section #7.4.5 How MySQL Uses Indexes.


@node Index Merge optimization, IS NULL optimization, Range optimization, Query Speed
@subsection Index Merge Optimization

@findex OR
@cindex OR Index Merge optimization
@cindex optimizations

@c TODO: replace following para with this one if ref/ref_or_null don't apply.
@c The Index Merge method is used to retrieve rows with several @code{range}
@c scans and merge their results into one.

The Index Merge (@code{index_merge}) method is used to retrieve rows with
several @code{ref}, @code{ref_or_null}, or @code{range} scans and merge
the results into one.  This method is employed when the table condition
is a disjunction of conditions for which @code{ref}, @code{ref_or_null},
or @code{range} could be used with different keys.

This ``join'' type optimization is new in MySQL 5.0.0, and represents
a significant change in behavior with regard to indexes, because the
@emph{old} rule was that the server is only ever able to use at most
one index for each referenced table.

In @code{EXPLAIN} output, this method appears as @code{index_merge} in the
@code{type} column. In this case, the @code{key} column contains a list of
indexes used, and @code{key_len} contains a list of the longest key parts
for those indexes.

Examples:

@example
SELECT * FROM @var{tbl_name} WHERE @var{key_part1} = 10 OR @var{key_part2} = 20;

SELECT * FROM @var{tbl_name}
    WHERE (@var{key_part1} = 10 OR @var{key_part2} = 20) AND @var{non_key_part}=30;

SELECT * FROM t1, t2
    WHERE (t1.@var{key1} IN (1,2) OR t1.@var{key2} LIKE '@var{value}%')
    AND t2.@var{key1}=t1.@var{some_col};

SELECT * FROM t1, t2
    WHERE t1.@var{key1}=1
    AND (t2.@var{key1}=t1.@var{some_col} OR t2.@var{key2}=t1.@var{some_col2});
@end example

The Index Merge method has several access algorithms (seen in the
@code{Extra} field of @code{EXPLAIN} output):

@itemize @bullet
@item intersection
@item union
@item sort-union
@end itemize

The following sections describe these methods in greater detail.

@strong{Note}:
The Index Merge optimization algorithm has the following known deficiencies:

@itemize @bullet
@item
If a range scan is possible on some key, Index Merge will not
be considered.  For example, consider this query:

@example
SELECT * FROM t1 WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30;
@end example

For this query, two plans are possible:

@enumerate
@item
An Index Merge scan using the @code{(goodkey1 < 10 OR goodkey2 < 20)}
condition.
@item
A range scan using the @code{badkey < 30} condition.
@end enumerate

However, the optimizer will only consider the second plan. If that not what
you want, you can make the optimizer consider @code{index_merge} by using
@code{IGNORE INDEX} or @code{FORCE INDEX}. The following queries will be
executed using Index Merge:

@example
SELECT * FROM t1 FORCE INDEX(goodkey1,goodkey2)
WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30;

SELECT * FROM t1 IGNORE INDEX(badkey)
WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30;
@end example

@item
If your query has a complex @code{WHERE} clause with deep
@code{AND}/@code{OR} nesting and MySQL doesn't choose the optimal plan,
try distributing terms using the following identity laws:

@example
(@var{x} AND @var{y}) OR @var{z} = (@var{x} OR @var{z}) AND (@var{y} OR @var{z})
(@var{x} OR @var{y}) AND @var{z} = (@var{x} AND @var{z}) OR (@var{y} AND @var{z})
@end example

@end itemize

The choice between different possible variants of the @code{index_merge}
access method and other access methods is based on cost estimates of
various available options.

@menu
* Index merge intersection::    Index Merge Intersection Access Algorithm
* Index merge union::           Index Merge Union Access Algorithm
* Index merge sort-union::      Index Merge Sort-Union Access Algorithm
@end menu


@node Index merge intersection, Index merge union, Index Merge optimization, Index Merge optimization
@subsubsection Index Merge Intersection Access Algorithm

This access algorithm can be employed when a @code{WHERE} clause was
converted to several range conditions on different keys combined with
@code{AND}, and each condition is one of the following:

@itemize @bullet

@item
In this form, where the index has exactly @var{N} parts (that is, all
index parts are covered):

@example
@var{key_part1}=@var{const1} AND @var{key_part2}=@var{const2} ... AND @var{key_partN}=@var{constN}
@end example

@item
Any range condition over a primary key of an @code{InnoDB}
or @code{BDB}
table.

@end itemize

Here are some examples:

@example
SELECT * FROM @var{innodb_table} WHERE @var{primary_key} < 10 AND @var{key_col1}=20;

SELECT * FROM @var{tbl_name}
WHERE (@var{key1_part1}=1 AND @var{key1_part2}=2) AND @var{key2}=2;
@end example

The Index Merge intersection algorithm performs simultaneous scans on
all used indexes and produces the intersection of row sequences that it
receives from the merged index scans.

If all columns used in the query are covered by the used indexes, full
table records will not be retrieved (@code{EXPLAIN} output will contain
@code{Using index} in @code{Extra} field in this case).  Here is an example
of such query:

@example
SELECT COUNT(*) FROM t1 WHERE key1=1 AND key2=1;
@end example

If the used indexes don't cover all columns used in the query, full records
will be retrieved only when the range conditions for all used keys are
satisfied.

If one of the merged conditions is a condition over a primary key of an
@code{InnoDB} or @code{BDB} table, it is not used for record retrieval,
but is used to filter out records retrieved using other conditions.


@node Index merge union, Index merge sort-union, Index merge intersection, Index Merge optimization
@subsubsection Index Merge Union Access Algorithm

The applicability criteria for this algorithm are similar to those of the
Index Merge method intersection algorithm.  The algorithm can be
employed when the table @code{WHERE} clause was converted to several range
conditions on different keys combined with @code{OR}, and each condition
is one of the following:

@itemize @bullet
@item
In this form, where the index has exactly @var{N} parts (that is, all
index parts are covered):

@example
@var{key_part1}=@var{const1} AND @var{key_part2}=@var{const2} ... AND @var{key_partN}=@var{constN}
@end example

@item
Any range condition over a primary key of an @code{InnoDB} or @code{BDB} table.

@item
A condition for which the Index Merge method intersection algorithm
is applicable.

@end itemize

Here are some examples:

@example
SELECT * FROM t1 WHERE @var{key1}=1 OR @var{key2}=2 OR @var{key3}=3;

SELECT * FROM @var{innodb_table} WHERE (@var{key1}=1 AND @var{key2}=2) OR
  (@var{key3}='foo' AND @var{key4}='bar') AND @var{key5}=5;
@end example


@node Index merge sort-union,  , Index merge union, Index Merge optimization
@subsubsection Index Merge Sort-Union Access Algorithm

This access algorithm is employed when the @code{WHERE} clause was converted
to several range conditions combined by @code{OR}, but for which the
Index Merge method union algorithm is not applicable.

Here are some examples:

@example
SELECT * FROM @var{tbl_name} WHERE @var{key_col1} < 10 OR @var{key_col2} < 20;

SELECT * FROM @var{tbl_name}
     WHERE (@var{key_col1} > 10 OR @var{key_col2} = 20) AND @var{nonkey_col}=30;
@end example

The difference between the sort-union algorithm and the union algorithm
is that the sort-union algorithm must first fetch row IDs for all records
and sort them before returning any records.


@node IS NULL optimization, DISTINCT optimization, Index Merge optimization, Query Speed
@subsection How MySQL Optimizes @code{IS NULL}

@findex IS NULL
@findex ref_or_null

MySQL can do the same optimization on @var{col_name} @code{IS NULL} that it can do
with @var{col_name} @code{=} @var{constant_value}.  For example, MySQL can use
indexes and ranges to search for @code{NULL} with @code{IS NULL}.

@example
SELECT * FROM @var{tbl_name} WHERE @var{key_col} IS NULL;

SELECT * FROM @var{tbl_name} WHERE @var{key_col} <=> NULL;

SELECT * FROM @var{tbl_name}
    WHERE @var{key_col}=@var{const1} OR @var{key_col}=@var{const2} OR @var{key_col} IS NULL;
@end example

If a @code{WHERE} clause includes a @var{col_name} @code{IS NULL} condition for a
column that is declared as @code{NOT NULL}, that expression will be
optimized away.  This optimization does not occur in cases when the column
might produce @code{NULL} anyway; for example, if it comes from a table on
the right side of a @code{LEFT JOIN}.

MySQL 4.1.1 and up can additionally optimize the combination
@code{@var{col_name} = @var{expr} AND @var{col_name} IS NULL},
a form that is common in resolved subqueries.
@code{EXPLAIN} will show @code{ref_or_null} when this
optimization is used.

This optimization can handle one @code{IS NULL} for any key part.

Some examples of queries that are optimized, assuming that there is an index
on columns @code{a} and @code{b} of table @code{t2}:

@example
SELECT * FROM t1 WHERE t1.a=@var{expr} OR t1.a IS NULL;

SELECT * FROM t1, t2 WHERE t1.a=t2.a OR t2.a IS NULL;

SELECT * FROM t1, t2
    WHERE (t1.a=t2.a OR t2.a IS NULL) AND t2.b=t1.b;

SELECT * FROM t1, t2
    WHERE t1.a=t2.a AND (t2.b=t1.b OR t2.b IS NULL);

SELECT * FROM t1, t2
    WHERE (t1.a=t2.a AND t2.a IS NULL AND ...)
    OR (t1.a=t2.a AND t2.a IS NULL AND ...);
@end example

@code{ref_or_null} works by first doing a read on the reference key,
and then a separate search for rows with a @code{NULL} key value.

Note that the optimization can handle only one @code{IS NULL} level.
In the following query, MySQL will use key lookups only on the expression
@code{(t1.a=t2.a AND t2.a IS NULL)} and not be able to use the key part on
@code{b}:

@example
SELECT * FROM t1, t2
     WHERE (t1.a=t2.a AND t2.a IS NULL)
     OR (t1.b=t2.b AND t2.b IS NULL);
@end example


@node DISTINCT optimization, LEFT JOIN optimization, IS NULL optimization, Query Speed
@subsection How MySQL Optimizes @code{DISTINCT}

@findex DISTINCT

@cindex optimizing, DISTINCT

@code{DISTINCT} combined with @code{ORDER BY} will
need a temporary table in many cases.

Note that because @code{DISTINCT} may use @code{GROUP BY}, you should be
aware of how MySQL works with columns in @code{ORDER BY} or @code{HAVING}
clauses that are not part of the selected columns.
@xref{GROUP-BY-hidden-fields}.

In most cases, a @code{DISTINCT} clause can be considered as a special case
of @code{GROUP BY}. For example, the following two queries are equivalent:

@example
SELECT DISTINCT(c1, c2, c3) FROM t1 WHERE c1 > @var{const};

SELECT c1, c2, c3 FROM t1 WHERE c1 > @var{const} GROUP BY c1, c2, c3;
@end example

Due to this equivalence, the optimizations applicable to @code{GROUP BY}
queries can be also applied to queries with a @code{DISTINCT} clause. Thus,
for more details on the optimization possibilities for @code{DISTINCT}
queries, see @ref{GROUP BY optimization,  , @code{GROUP BY} optimization}.

When combining @code{LIMIT @var{row_count}} with @code{DISTINCT}, MySQL stops
as soon as it finds @var{row_count} unique rows.

If you don't use columns from all tables named in a query, MySQL stops
scanning the not-used tables as soon as it finds the first match.
In the following case, assuming that @code{t1} is used before @code{t2}
(which you can check with @code{EXPLAIN}), MySQL stops reading from @code{t2}
(for any particular row in @code{t1}) when the first row in @code{t2}
is found:

@example
SELECT DISTINCT t1.a FROM t1, t2 where t1.a=t2.a;
@end example


@node LEFT JOIN optimization, ORDER BY optimization, DISTINCT optimization, Query Speed
@subsection How MySQL Optimizes @code{LEFT JOIN} and @code{RIGHT JOIN}

@findex LEFT JOIN

@cindex optimizing, LEFT JOIN

@code{A LEFT JOIN B join_condition} is implemented in MySQL as follows:

@itemize @bullet
@item
Table @code{B} is set to depend on table @code{A} and all tables
on which @code{A} depends.

@item
Table @code{A} is set to depend on all tables (except @code{B})
that are used in the @code{LEFT JOIN} condition.

@item
The @code{LEFT JOIN} condition is used to decide how to retrieve rows
from table B. (In other words, any condition in the @code{WHERE} clause
is not used.)

@item
All standard join optimizations are done, with the exception that a table is
always read after all tables on which it depends.  If there is a circular
dependence, MySQL issues an error.

@item
All standard @code{WHERE} optimizations are done.

@item
If there is a row in @code{A} that matches the @code{WHERE} clause, but there
is no row in @code{B} that matches the @code{ON} condition,
an extra @code{B} row is generated with all columns set to @code{NULL}.

@item
If you use @code{LEFT JOIN} to find rows that don't exist in some
table and you have the following test: @code{@var{col_name} IS NULL} in the
@code{WHERE} part, where @var{col_name} is a column that is declared as
@code{NOT NULL}, MySQL stops searching for more rows
(for a particular key combination) after it has found one row that
matches the @code{LEFT JOIN} condition.
@end itemize

@code{RIGHT JOIN} is implemented analogously to @code{LEFT JOIN}, with the
roles of the tables reversed.

The join optimizer calculates the order in which tables should be joined.
The table read order forced by @code{LEFT JOIN} and @code{STRAIGHT_JOIN}
helps the join optimizer do its work much more quickly, because there are
fewer table permutations to check.
Note that this means that if you do a query of the following type,
MySQL will do a full scan on @code{b} because the @code{LEFT JOIN} forces
it to be read before @code{d}:

@example
SELECT *
    FROM a,b LEFT JOIN c ON (c.key=a.key) LEFT JOIN d ON (d.key=a.key)
    WHERE b.key=d.key;
@end example

The fix in this case is to rewrite the query as follows:

@example
SELECT *
    FROM b,a LEFT JOIN c ON (c.key=a.key) LEFT JOIN d ON (d.key=a.key)
    WHERE b.key=d.key;
@end example

Starting from 4.0.14, MySQL does the following @code{LEFT JOIN} optimization:
If the @code{WHERE} condition is always false for the generated
@code{NULL} row, the @code{LEFT JOIN} is changed to a normal join.

For example, the @code{WHERE} clause would be
false in the following query
if @code{t2.column1} would be @code{NULL}:

@example
SELECT * FROM t1 LEFT JOIN t2 ON (column1) WHERE t2.column2=5;
@end example

Therefore, it's safe to convert the query to a normal join:

@example
SELECT * FROM t1, t2 WHERE t2.column2=5 AND t1.column1=t2.column1;
@end example

This can be made faster because MySQL can now use table @code{t2} before
table @code{t1} if this would result in a better query plan.  To force a
specific table order, use @code{STRAIGHT_JOIN}.

@node ORDER BY optimization, GROUP BY optimization, LEFT JOIN optimization, Query Speed
@subsection How MySQL Optimizes @code{ORDER BY}

In some cases, MySQL can use an index to satisfy an @code{ORDER BY}
clause without doing any extra sorting.

The index can also be used even if the @code{ORDER BY} doesn't match the
index exactly, as long as all the unused index parts and all the extra
are @code{ORDER BY} columns are constants in the @code{WHERE}
clause. The following queries will use the index to resolve the
@code{ORDER BY} part:

@example
SELECT * FROM t1 ORDER BY @var{key_part1},@var{key_part2},... ;
SELECT * FROM t1 WHERE @var{key_part1}=@var{constant} ORDER BY @var{key_part2};
SELECT * FROM t1 ORDER BY @var{key_part1} DESC, @var{key_part2} DESC;
SELECT * FROM t1
    WHERE @var{key_part1}=1 ORDER BY @var{key_part1} DESC, @var{key_part2} DESC;
@end example

In some cases, MySQL @emph{cannot} use indexes to resolve the @code{ORDER
BY}, although it still will use indexes to find the rows that
match the @code{WHERE} clause. These cases include the following:

@itemize @bullet
@item
You use @code{ORDER BY} on different keys:

@example
SELECT * FROM t1 ORDER BY @var{key1}, @var{key2};
@end example

@item
You use @code{ORDER BY} on non-consecutive key parts:

@example
SELECT * FROM t1 WHERE @var{key2}=@var{constant} ORDER BY @var{key_part2};
@end example

@item
You mix @code{ASC} and @code{DESC}:

@example
SELECT * FROM t1 ORDER BY @var{key_part1} DESC, @var{key_part2} ASC;
@end example

@item
The key used to fetch the rows is not the same as the one used in
the @code{ORDER BY}:

@example
SELECT * FROM t1 WHERE @var{key2}=@var{constant} ORDER BY @var{key1};
@end example

@item
You are joining many tables, and the columns in the @code{ORDER
BY} are not all from the first non-constant table that is used to
retrieve rows. (This is the first table in the @code{EXPLAIN} output that
doesn't have a @code{const} join type.)

@item
You have different @code{ORDER BY} and @code{GROUP BY} expressions.

@item
The type of table index used doesn't store rows in order.  For example, this
is true for a @code{HASH} index in a @code{HEAP} table.

@end itemize

With @code{EXPLAIN SELECT ... ORDER BY}, you can check whether MySQL can use
indexes to resolve the query.  It cannot if you see @code{Using filesort} in
the @code{Extra} column.
@xref{EXPLAIN,  , @code{EXPLAIN}}.

@c NOTE: This description is also present in internals.texi

@cindex filesort optimization
@cindex optimizing, filesort

In those cases where MySQL must sort the result, it uses the following
@code{filesort} algorithm before MySQL 4.1:

@enumerate

@item
Read all rows according to key or by table scanning.
Rows that don't match the @code{WHERE} clause are skipped.

@item
For each row, store a pair of values in a buffer (the sort key and the row
pointer).  The size of the buffer is the value of the @code{sort_buffer_size}
system variable.

@item
When the buffer gets full, run a qsort (quicksort) on it and store the
result in a temporary file.  Save a pointer to the sorted block.  (If all
pairs fit into the sort buffer, no temporary file is created.)

@item
Repeat the preceding steps until all rows have been read.

@item
Do a multi-merge of up to @code{MERGEBUFF} (7) regions to one block in
another temporary file.  Repeat until all blocks from the first file
are in the second file.

@item
Repeat the following until there are fewer than @code{MERGEBUFF2} (15)
blocks left.

@item
On the last multi-merge, only the pointer to the row (the last part of
the sort key) is written to a result file.

@item
Read the rows in sorted order by using the row pointers in the result file.
To optimize this, we read in a big block of row pointers, sort them, and use
them to read the rows in sorted order into a row buffer. The size of the
buffer is the value of the @code{read_rnd_buffer_size} system variable.
The code for this step is in the @file{sql/records.cc} source file.

@end enumerate


One problem with this approach is that it reads rows twice: One time when
evaluating the @code{WHERE} clause, and again after sorting the pair values.
And even if the rows were accessed successively the first time (for example,
if a table scan is done), the second time they are accessed randomly. (The
sort keys are ordered, but the row positions are not.)

In MySQL 4.1 and up, a @code{filesort} optimization is used that records not
only the sort key value and row position, but also the columns required for
the query.  This avoids reading the rows twice. The modified @code{filesort}
algorithm works like this:

@enumerate

@item
Read the rows that match the @code{WHERE} clause, as before.

@item
For each row, record a tuple of values consisting of the sort key value and
row position, and also the columns required for the query.

@item
Sort the tuples by sort key value

@item
Retrieve the rows in sorted order, but read the required columns directly from
the sorted tuples rather than by accessing the table a second time.

@end enumerate

Using the modified @code{filesort} algorithm, the tuples are longer than the
pairs used in the original method, and fewer of them fit in the sort buffer
(the size of which is given by @code{sort_buffer_size}). As a result, it is
possible for the extra I/O to make the modified approach slower, not faster.
To avoid a slowdown, the optimization is used only if the total size of the
extra columns in the sort tuple does not exceed the value of the
@code{max_length_for_sort_data} system variable. (A symptom of setting the
value of this variable too high is that you will see high disk activity and
low CPU activity.)

If you want to increase @code{ORDER BY} speed, first see whether you can get
MySQL to use indexes rather than an extra sorting phase. If this is not
possible, you can try the following strategies:

@itemize @bullet
@item
Increase the size of the @code{sort_buffer_size} variable.
@item
Increase the size of the @code{read_rnd_buffer_size} variable.
@item
Change @code{tmpdir} to point to a dedicated filesystem with lots of empty
space.  If you use MySQL 4.1 or later, this option accepts several paths
that are used in round-robin fashion. Paths should be separated by colon
characters (@samp{:}) on Unix and semicolon characters (@samp{;}) on
Windows, NetWare, and OS/2.  You can use this feature to spread the load
across several directories.  @emph{Note:} The paths should be for
directories in filesystems that are located on different @emph{physical}
disks, not different partitions of the same disk.

@end itemize

By default, MySQL sorts all @code{GROUP BY @var{col1}, @var{col2}, ...} queries as if
you specified @code{ORDER BY @var{col1}, @var{col2}, ...} in the query as well. If you
include an @code{ORDER BY} clause explicitly that contains the same column
list,  MySQL optimizes it away without any speed penalty, although the sorting
still occurs.  If a query includes @code{GROUP BY} but you want to avoid the
overhead of sorting the result, you can suppress sorting by specifying
@code{ORDER BY NULL}. For example:

@example
INSERT INTO foo
SELECT a, COUNT(*) FROM bar GROUP BY a ORDER BY NULL;
@end example


@node GROUP BY optimization, LIMIT optimization, ORDER BY optimization, Query Speed
@subsection How MySQL Optimizes @code{GROUP BY}

@findex GROUP BY
@cindex optimizing, GROUP BY

The most general way to satisfy a @code{GROUP BY} clause is to scan the whole
table and create a new temporary table where all rows from each group are
consecutive, and then use this temporary table to discover groups and apply
aggregate functions (if any). In some cases, MySQL is able to do much better
than that and to avoid creation of temporary tables by using index access.

The most important preconditions for using indexes for @code{GROUP BY} are
that all @code{GROUP BY} columns reference attributes from the same index,
and the index stores its keys in order (for example, this is a B-Tree index,
and not a HASH index). Whether usage of temporary tables can be replaced by
index access also depends on which parts of an index are used in a query, the
conditions specified for these parts, and the selected aggregate functions.

There are two ways to execute a @code{GROUP BY} query via index access,
as detailed in the following sections. In the first method, the grouping
operation is applied together with all range predicates (if any). The second
method first performs a range scan, and then groups the resulting tuples.

@menu
* Loose index scan::            Loose index scan
* Tight index scan::            Tight index scan
@end menu


@node Loose index scan, Tight index scan, GROUP BY optimization, GROUP BY optimization
@subsubsection Loose index scan

The most efficient way is when the index is used to directly retrieve
the group fields. With this access method, MySQL uses the property of
some index types (for example, B-Trees) that the keys are ordered. This
property allows use of lookup groups in an index without having to consider
all keys in the index that satisfy all @code{WHERE} conditions. Since
this access method considers only a fraction of the keys in an index,
it is called ``loose index scan.'' When there is no @code{WHERE} clause,
a loose index scan will read as many keys as the number of groups, which
may be a much smaller number than all keys. If the @code{WHERE} clause
contains range predicates (described in @ref{EXPLAIN,  , @code{EXPLAIN}},
under the @code{range} join type), a loose index scan looks up the first key of
each group that satisfies the range conditions, and again reads the least
possible number of keys. This is possible under the following conditions:

@itemize @bullet

@item
The query is over a single table.

@item
The @code{GROUP BY} includes the first consecutive parts of the index
(if instead of @code{GROUP BY}, the query has a @code{DISTINCT} clause,
then all distinct attributes refer to the beginning of the index).

@item
The only aggregate functions used (if any) are @code{MIN()} and @code{MAX()},
and all of them refer to the same column.

@item
Any other index parts than the ones from @code{GROUP BY} referenced in the
query must be constants (that is, they must be referenced in equalities
with constants), except for the argument of @code{MIN()} or @code{MAX()}
functions.

@end itemize

The @code{EXPLAIN} output for such queries shows @code{Using index for
group-by} in the @code{Extra} column.

The following queries provide several examples that fall into this
category, assuming there is an index @code{idx(c1, c2, c3)} on table
@code{t1(c1,c2,c3,c4)}:

@example
SELECT c1, c2 FROM t1 GROUP BY c1, c2;
SELECT DISTINCT(c1, c2) FROM t1;
SELECT c1, MIN(c2) FROM t1 GROUP BY c1;
SELECT c1, c2 FROM t1 WHERE c1 < @var{const} GROUP BY c1, c2;
SELECT MAX(c3), MIN(c3), c1, c2 FROM t1 WHERE c2 > @var{const} GROUP BY c1, c2;
SELECT c2 FROM t1 WHERE c1 < @var{const} GROUP BY c1, c2;
SELECT c1, c2 FROM t1 WHERE c3 = @var{const} GROUP BY c1, c2;
@end example

The following queries cannot be executed with this quick select method,
for the reasons given:

@itemize @bullet

@item
There are other aggregate function than @code{MIN()} or @code{MAX()}:

@example
SELECT c1, SUM(c2) FROM t1 GROUP BY c1;
@end example

@item
The fields in @code{GROUP BY} do not refer to the beginning of the index:

@example
SELECT c1,c2 FROM t1 GROUP BY c2, c3;
@end example

@item
The query refers to a key part that is after the @code{GROUP BY} parts,
and for which there is no equality with a constant:

@example
SELECT c1,c3 FROM t1 GROUP BY c1, c2;
@end example

@end itemize


@node Tight index scan,  , Loose index scan, GROUP BY optimization
@subsubsection Tight index scan

A tight index scan may be either a full index scan or a range index scan,
depending on the query conditions.

When the conditions for a loose index scan are not met, it is still
possible to avoid creation of temporary tables for @code{GROUP BY}
queries. If there are range conditions in the @code{WHERE} clause, this
method will read only the keys that satisfy these conditions. Otherwise,
it performs an index scan. Since this method reads all keys in each range
defined by the @code{WHERE} clause, or scans the whole index if there are
no range conditions, we term it a ``tight index scan.'' Notice that with a
tight index scan, the grouping operation is performed after all keys that
satisfy the range conditions have been found.

For this method to work, it is sufficient that for all columns in a query
referring to key parts before or in between the @code{GROUP BY} key parts,
there is a constant equality condition. The constants from the equality
conditions fill in the ``gaps'' in the search keys so that it is possible
to form complete prefixes of the index. Then these index prefixes can
be used for index lookups. If we require sorting of the @code{GROUP BY}
result, and it is possible to form search keys that are prefixes of the
index, MySQL also will avoid sorting because searching with prefixes in
an ordered index already retrieves all keys in order.

The following queries will not work with the first method above, but will
still work with the second index access method (assuming we have the
aforementioned index @code{idx} on table @code{t1}):

@itemize @bullet

@item
There is a ``gap'' in @code{GROUP BY}, but it is covered by the condition (c2 = 'a').

@example
SELECT c1, c2, c3 FROM t1 WHERE c2 = 'a' GROUP BY c1, c3;
@end example

@item
@code{GROUP BY} does not begin from the first key part, but there is a
condition that provides a constant for that key part:

@example
SELECT c1, c2, c3 FROM t1 WHERE c1 = 'a' GROUP BY c2, c3;
@end example

@end itemize


@node LIMIT optimization, How to avoid table scan, GROUP BY optimization, Query Speed
@subsection How MySQL Optimizes @code{LIMIT}

@findex LIMIT

@cindex optimizing, LIMIT

In some cases, MySQL will handle a query differently when you are
using @code{LIMIT @var{row_count}} and not using @code{HAVING}:

@itemize @bullet
@item
If you are selecting only a few rows with @code{LIMIT}, MySQL
uses indexes in some cases when normally it would prefer to do a
full table scan.
@item
If you use @code{LIMIT @var{row_count}} with @code{ORDER BY}, MySQL ends the
sorting as soon as it has found the first @var{row_count} lines rather
than sorting the whole table.
@item
When combining @code{LIMIT @var{row_count}} with @code{DISTINCT}, MySQL stops
as soon as it finds @var{row_count} unique rows.
@item
In some cases, a @code{GROUP BY} can be resolved by reading the key in order
(or doing a sort on the key) and then calculating summaries until the
key value changes.  In this case, @code{LIMIT @var{row_count}} will not calculate any
unnecessary @code{GROUP BY} values.
@item
As soon as MySQL has sent the required number of rows to the client, it
aborts the query unless you are using @code{SQL_CALC_FOUND_ROWS}.
@item
@code{LIMIT 0} always quickly returns an empty set.  This is useful
to check the query or to get the column types of the result columns.
@item
When the server uses temporary tables to resolve the query, the
@code{LIMIT @var{row_count}} is used to calculate how much space is required.
@end itemize


@node How to avoid table scan, Insert speed, LIMIT optimization, Query Speed
@subsection How to Avoid Table Scans

@cindex Table scans, avoiding

The output from @code{EXPLAIN} will show @code{ALL} in the @code{type}
column when MySQL uses a table scan to resolve a query. This usually happens
under the following conditions:

@itemize @bullet
@item
The table is so small that it's faster to do a table scan than a key lookup.
This is a common case for tables with fewer than 10 rows and a short row length.
@item
There are no usable restrictions in the @code{ON} or @code{WHERE} clause
for indexed columns.
@item
You are comparing indexed columns with constant values and MySQL has
calculated (based on the index tree) that the constants cover too large a
part of the table and that a table scan would be faster.
@xref{Where optimizations}.
@item
You are using a key with low cardinality (many rows match the key value)
through another column.  In this case, MySQL assumes that by using the
key it will probably do a lot of key lookups and that a table scan
would be faster.
@end itemize

For small tables, a table scan often is appropriate. For large tables, try
the following techniques to avoid having the optimizer incorrectly choose
a table scan:

@itemize @bullet
@item
Use @code{ANALYZE TABLE @var{tbl_name}} to update the key distributions for the
scanned table.  @xref{ANALYZE TABLE,  , @code{ANALYZE TABLE}}.

@item
Use @code{FORCE INDEX} for the scanned table to tell MySQL that table
scans are very expensive compared to using the given index.
@xref{SELECT,  , @code{SELECT}}.

@example
SELECT * FROM t1, t2 FORCE INDEX (@var{index_for_column})
WHERE t1.@var{col_name}=t2.@var{col_name};
@end example

@item
Start @command{mysqld} with the @code{--max-seeks-for-key=1000} option or use
@code{SET max_seeks_for_key=1000} to tell the optimizer to assume that no
key scan will cause more than 1,000 key seeks.
@xref{Server system variables}.
@end itemize


@node Insert speed, Update speed, How to avoid table scan, Query Speed
@subsection Speed of @code{INSERT} Statements

@findex INSERT

@cindex speed, inserting
@cindex inserting, speed of

The time to insert a record is determined by the following factors,
where the numbers indicate approximate proportions:

@itemize @bullet
@item
Connecting:              (3)
@item
Sending query to server: (2)
@item
Parsing query:           (2)
@item
Inserting record:        (1 x size of record)
@item
Inserting indexes:       (1 x number of indexes)
@item
Closing:                 (1)
@end itemize

This does not take into consideration the initial overhead to open tables,
which is done once for each concurrently running query.

The size of the table slows down the insertion of indexes by log N,
assuming B-tree indexes.

You can use the following methods to speed up inserts:

@itemize @bullet

@item
If you are inserting many rows from the same client at the same time, use
@code{INSERT} statements with multiple @code{VALUES} lists to insert several
rows at a time.  This is much faster (many times faster in some cases) than
using separate single-row @code{INSERT} statements.  If you are adding data
to a non-empty table, you may tune the @code{bulk_insert_buffer_size}
variable to make it even faster.
@xref{Server system variables}.

@item
If you are inserting a lot of rows from different clients, you can get
higher speed by using the @code{INSERT DELAYED} statement. @xref{INSERT,
, @code{INSERT}}.

@item
With @code{MyISAM} tables you can insert rows at the same time that
@code{SELECT} statements are running if there are no deleted rows in the
tables.

@item
When loading a table from a text file, use @code{LOAD DATA INFILE}. This
is usually 20 times faster than using a lot of @code{INSERT} statements.
@xref{LOAD DATA, , @code{LOAD DATA}}.

@item
With some extra work, it is possible to make @code{LOAD DATA INFILE} run even
faster when the table has many indexes. Use the following procedure:

@enumerate

@item
Optionally create the table with @code{CREATE TABLE}.

@item
Execute a @code{FLUSH TABLES} statement or a @command{mysqladmin flush-tables}
command.

@item
Use @command{myisamchk --keys-used=0 -rq @var{/path/to/db/tbl_name}.} This will
remove all use of all indexes for the table.

@item
Insert data into the table with @code{LOAD DATA INFILE}. This will not
update any indexes and will therefore be very fast.

@item
If you are going to only read the table in the future, use @command{myisampack}
to make it smaller. @xref{Compressed format}.

@item
Re-create the indexes with @command{myisamchk -r -q
@var{/path/to/db/tbl_name}}. This will create the index tree in memory before
writing it to disk, which is much faster because it avoids lots of disk
seeks. The resulting index tree is also perfectly balanced.

@item
Execute a @code{FLUSH TABLES} statement or a @command{mysqladmin flush-tables}
command.

@end enumerate

Note that @code{LOAD DATA INFILE} also performs the preceding optimization
if you insert into an empty @code{MyISAM} table; the main difference is that you can let
@command{myisamchk} allocate much more temporary memory for the index creation
than you might want the server to allocate for index re-creation when it
executes the @code{LOAD DATA INFILE} statement.

As of MySQL 4.0, you can also use
@code{ALTER TABLE @var{tbl_name} DISABLE KEYS} instead of
@command{myisamchk --keys-used=0 -rq @var{/path/to/db/tbl_name}} and
@code{ALTER TABLE @var{tbl_name} ENABLE KEYS} instead of
@command{myisamchk -r -q @var{/path/to/db/tbl_name}}. This way you can also skip the
@code{FLUSH TABLES} steps.

@item
You can speed up @code{INSERT} operations that are done
with multiple statements by locking your tables:

@example
LOCK TABLES a WRITE;
INSERT INTO a VALUES (1,23),(2,34),(4,33);
INSERT INTO a VALUES (8,26),(6,29);
UNLOCK TABLES;
@end example

A performance benefit occurs because the index buffer is flushed to disk only
onc, after all @code{INSERT} statements have completed. Normally there would
be as many index buffer flushes as there are different @code{INSERT}
statements. Explicit locking statements are not needed if you can insert
all rows with a single statement.

For transactional tables, you should use @code{BEGIN/COMMIT} instead of
@code{LOCK TABLES} to get a speedup.

Locking also lowers the total time of multiple-connection tests, although the
maximum wait time for individual connections might go up because they wait for
locks.  For example:

@example
Connection 1 does 1000 inserts
Connections 2, 3, and 4 do 1 insert
Connection 5 does 1000 inserts
@end example

If you don't use locking, connections 2, 3, and 4 will finish before 1 and
5. If you use locking, connections 2, 3, and 4 probably will not finish
before 1 or 5, but the total time should be about 40% faster.

@code{INSERT}, @code{UPDATE}, and @code{DELETE} operations are very
fast in MySQL, but you will obtain better overall performance by
adding locks around everything that does more than about five inserts or
updates in a row.  If you do very many inserts in a row, you could do a
@code{LOCK TABLES} followed by an @code{UNLOCK TABLES} once in a while
(about each 1,000 rows) to allow other threads access to the table. This
would still result in a nice performance gain.

@code{INSERT} is still much slower for loading data than @code{LOAD DATA
INFILE}, even when using the strategies just outlined.

@item
To get some more speed for @code{MyISAM} tables, for both @code{LOAD DATA
INFILE} and @code{INSERT}, enlarge the key cache by increasing the
@code{key_buffer_size} system variable.
@xref{Server parameters}.

@end itemize


@node Update speed, Delete speed, Insert speed, Query Speed
@subsection Speed of @code{UPDATE} Statements

Update statements are optimized as a @code{SELECT} query with the additional
overhead of a write. The speed of the write depends on the amount of
data being updated and the number of indexes that are updated.  Indexes that
are not changed will not be updated.

Also, another way to get fast updates is to delay updates and then do
many updates in a row later. Doing many updates in a row is much quicker
than doing one at a time if you lock the table.

Note that for a @code{MyISAM} table that uses dynamic record format,
updating a record to a longer total length may split the record.  If you do
this often, it is very important to use @code{OPTIMIZE TABLE} occasionally.
@xref{OPTIMIZE TABLE, , @code{OPTIMIZE TABLE}}.


@node Delete speed, Tips, Update speed, Query Speed
@subsection Speed of @code{DELETE} Statements

The time to delete individual records is exactly proportional to the number
of indexes. To delete records more quickly, you can increase the size of the
key cache.
@xref{Server parameters}.

If you want to delete all rows in the table, use @code{TRUNCATE TABLE
tbl_name} rather than @code{DELETE FROM @var{tbl_name}}.
@xref{TRUNCATE,  , @code{TRUNCATE}}.


@node Tips,  , Delete speed, Query Speed
@subsection Other Optimization Tips

@cindex optimization, tips
@cindex tips, optimization

This section lists a number of miscellaneous tips for improving query
processing speed:

@itemize @bullet

@item
Use persistent connections to the database to avoid connection
overhead. If you can't use persistent connections and you are initiating many
new connections to the database, you may want to change the value
of the @code{thread_cache_size} variable. @xref{Server parameters}.

@item
Always check whether all your queries really use the indexes you have created
in the tables. In MySQL, you can do this with the @code{EXPLAIN}
statement. @xref{EXPLAIN,  , @code{EXPLAIN}}.

@item
Try to avoid complex @code{SELECT} queries on @code{MyISAM} tables that are
updated frequently, to avoid problems with table locking that occur
due to contention between readers and writers.

@item
With @code{MyISAM} tables that have no deleted rows, you can insert rows at
the end at the same time that another query is reading from the table.  If this
is important for you, you should consider using the table in ways that avoid
deleting rows. Another possibility is to run @code{OPTIMIZE TABLE} after you
have deleted a lot of rows.

@item
Use @code{ALTER TABLE ... ORDER BY @var{expr1}, @var{expr2}, ...} if you mostly
retrieve rows in @code{@var{expr1}, @var{expr2}, ...} order.  By using this option after
extensive changes to the table, you may be able to get higher performance.

@item
In some cases, it may make sense to introduce a column that is ``hashed''
based on information from other columns. If this column is short and
reasonably unique, it may be much faster than a big index on many
columns. In MySQL, it's very easy to use this extra column:

@example
SELECT * FROM @var{tbl_name}
    WHERE @var{hash_col}=MD5(CONCAT(@var{col1},@var{col2}))
    AND @var{col1}='@var{constant}' AND @var{col2}='@var{constant}';
@end example

@item
For @code{MyISAM} tables that change a lot, you should try to avoid all
variable-length columns (@code{VARCHAR}, @code{BLOB}, and @code{TEXT}). The
table will use dynamic record format if it includes even a single
variable-length column.
@xref{Storage engines}.

@item
It's normally not useful to split a table into different tables just
because the rows get ``big.'' To access a row, the biggest performance
hit is the disk seek to find the first byte of the row. After finding
the data, most modern disks can read the whole row fast enough for most
applications. The only cases where it really matters to split up a table is if
it's a @code{MyISAM} table with dynamic record format (see above) that you can
change to a fixed record size,
or if you very often need to scan the table but do not need
most of the columns. @xref{Storage engines}.

@item
If you very often need to calculate results such as counts based on
information from a lot of rows, it's probably much
better to introduce a new table and update the counter in real time. An
update of the following form is very fast:

@example
UPDATE @var{tbl_name} SET @var{count_col}=@var{count_col}+1 WHERE @var{key_col}=@var{constant};
@end example

This is really important when you use MySQL storage engines such as
@code{MyISAM} and @code{ISAM} that have only table-level locking (multiple
readers / single writers). This will also give better performance with most
databases, because the row locking manager in this case will have less to do.

@item
If you need to collect statistics from large log tables, use summary tables
instead of scanning the entire log table. Maintaining the summaries should be
much faster than trying to calculate statistics ``live.'' It's much faster to
regenerate new summary tables from the logs when things change
(depending on business decisions) than to have to change the running
application!

@item
If possible, you should classify reports as ``live'' or ``statistical,''
where data needed for statistical reports is created only from summary
tables that are generated periodically from the live data.

@item
Take advantage of the fact that columns have default values. Insert
values explicitly only when the value to be inserted differs from the
default. This reduces the parsing that MySQL needs to do and
improves the insert speed.

@item
In some cases, it's convenient to pack and store data into a @code{BLOB}
column. In this case, you must add some extra code in your application to
pack and unpack information in the @code{BLOB} values, but this may save a
lot of accesses at some stage.  This is practical when you have data that
doesn't conform to a rows-and-columns table structure.

@item
Normally, you should try to keep all data non-redundant (what
is called "third normal form" in database theory). However, do not be
afraid to duplicate information or create summary tables if necessary
to gain more speed.

@item
Stored procedures or UDFs (user-defined functions) may be a good way to get
more performance for some tasks. However, if you use a database system that
does not support these capabilities, you should always have another way to
perform the same tasks, even if the alternative method is slower.

@item
You can always gain something by caching queries or answers in your
application and then performing many inserts or updates together.  If
your database supports table locks (like MySQL and Oracle),
this should help to ensure that the index cache is only flushed once
after all updates.

@item
Use @code{INSERT DELAYED} when you do not need to know when your
data is written. This speeds things up because many records can be written
with a single disk write.

@item
Use @code{INSERT LOW_PRIORITY} when you want to give @code{SELECT}
statements higher priority than your inserts.

@item
Use @code{SELECT HIGH_PRIORITY} to get retrievals that jump the
queue. That is, the @code{SELECT} is done even if there is another client
waiting to do a write.

@item
Use multiple-row @code{INSERT} statements to store many rows with one
SQL statement (many SQL servers support this).

@item
Use @code{LOAD DATA INFILE} to load large amounts of data. This is
faster than using @code{INSERT} statements.

@item
Use @code{AUTO_INCREMENT} columns to generate unique values.

@item
Use @code{OPTIMIZE TABLE} once in a while to avoid fragmentation
with @code{MyISAM} tables
when
using a dynamic table format.
@xref{MyISAM table formats, , @code{MyISAM} table formats}.

@item
Use @code{HEAP} tables when possible to get more speed.
@xref{Storage engines}.

@item
When using a normal Web server setup, images should be stored as
files. That is, store only a file reference in the database.  The main
reason for this is that a normal Web server is much better at caching
files than database contents, so it's much easier to get a fast
system if you are using files.

@item
Use in-memory tables for non-critical data that is accessed often, such as
information about the last displayed banner for users who don't have
cookies enabled in their Web browser.

@item
Columns with identical information in different tables should be
declared to have identical data types. Before MySQL 3.23, you
get slow joins otherwise.

Try to keep column names simple. For example, in a table named @code{customer},
use a column name of @code{name} instead of @code{customer_name}. To make
your names portable to other SQL servers, you should keep them shorter than
18 characters.

@item
If you need really high speed, you should take a look at the low-level
interfaces for data storage that the different SQL servers support!  For
example, by accessing the MySQL @code{MyISAM} storage engine directly, you could
get a speed increase of two to five times compared to using the SQL interface.
To be able to do this, the data must be on the same server as
the application, and usually it should only be accessed by one process
(because external file locking is really slow).  One could eliminate these
problems by introducing low-level @code{MyISAM} commands in the
MySQL server (this could be one easy way to get more
performance if needed).  By carefully designing the database interface,
it should be quite easy to support this types of optimization.

@item
If you are using numerical data, it's faster in many cases to access
information from a database (using a live connection) than to access a text
file. Information in the database is likely to be stored in a more compact
format than in the text file, so accessing it will involve fewer disk
accesses.  You will also save code in your application because you don't
have to parse your text files to find line and column boundaries.

@item
Replication can provide a performance benefit for some operations. You can
distribute client retrievals among replication servers to split up the load.
To avoid slowing down the master while making backups, you can make backups
using a slave server.
@xref{Replication}.

@item
Declaring a @code{MyISAM} table with the @code{DELAY_KEY_WRITE=1} table
option makes index updates faster because they are not flushed to disk
until the table is closed.  The downside is that if something kills the
server while such a table is open, you should ensure that they are okay by
running the server with the @code{--myisam-recover} option, or by
running @command{myisamchk} before restarting the server.  (However, even in
this case, you should not lose anything by using @code{DELAY_KEY_WRITE},
because the key information can always be generated from the data rows.)

@end itemize


@node Locking Issues, Optimizing Database Structure, Query Speed, MySQL Optimization
@section Locking Issues


@menu
* Internal locking::            Locking Methods
* Table locking::               Table Locking Issues
@end menu


@node Internal locking, Table locking, Locking Issues, Locking Issues
@subsection Locking Methods

@cindex internal locking
@cindex locking methods
@cindex methods, locking
@cindex row-level locking
@cindex page-level locking
@cindex table-level locking
@cindex locking, row-level
@cindex locking, page-level
@cindex locking, table-level

Currently, MySQL supports table-level locking for @code{ISAM},
@code{MyISAM}, and @code{MEMORY} (@code{HEAP}) tables, page-level locking
for @code{BDB} tables, and row-level locking for @code{InnoDB} tables.

In many cases, you can make an educated guess about which locking type is best
for an application, but generally it's very hard to say that a given
lock type is better than another. Everything depends on the application
and different parts of an application may require different lock types.

To decide whether you want to use a storage engine with row-level locking,
you will want to look at what your application does and what mix of select
and update statements it uses.  For example, most Web applications do lots
of selects, very few deletes, updates based mainly on key values, and
inserts into some specific tables.  The base MySQL @code{MyISAM} setup is
very well tuned for this.

Table locking in MySQL is deadlock-free for storage engines that use
table-level locking.  Deadlock avoidance is managed by always requesting all
needed locks at once at the beginning of a query and always locking the
tables in the same order.

The table-locking method MySQL uses for @code{WRITE} locks works as follows:

@itemize @bullet

@item
If there are no locks on the table, put a write lock on it.

@item
Otherwise, put the lock request in the write lock queue.

@end itemize

The table-locking method MySQL uses for @code{READ} locks works as follows:

@itemize @bullet

@item
If there are no write locks on the table, put a read lock on it.

@item
Otherwise, put the lock request in the read lock queue.

@end itemize

When a lock is released, the lock is made available to the threads
in the write lock queue, then to the threads in the read lock queue.

This means that if you have many updates for a table, @code{SELECT}
statements will wait until there are no more updates.

Starting in MySQL 3.23.33, you can analyze the table lock contention
on your system by checking the @code{Table_locks_waited} and
@code{Table_locks_immediate} status variables:

@example
mysql> SHOW STATUS LIKE 'Table%';
+-----------------------+---------+
| Variable_name         | Value   |
+-----------------------+---------+
| Table_locks_immediate | 1151552 |
| Table_locks_waited    | 15324   |
+-----------------------+---------+
@end example

@cindex concurrent inserts

As of MySQL 3.23.7 (3.23.25 for Windows), you can freely mix concurrent
@code{INSERT} and @code{SELECT} statements for a @code{MyISAM} table without
locks if the @code{INSERT} statements are non-conflicting.  That is, you can
insert rows into a @code{MyISAM} table at the same time other clients are
reading from it.  No conflict occurs if the data file contains no free
blocks in the middle, because in that case, records always are inserted at
the end of the data file.  (Holes can result from rows having been deleted
from or updated in the middle of the table.) If there are holes, concurrent
inserts are re-enabled automatically when all holes have been filled with
new data.

If you want to do many @code{INSERT} and @code{SELECT} operations on a table
when concurrent inserts are not possible, you can insert rows in a temporary
table and update the real table with the records from the temporary table
once in a while.  This can be done with the following code:

@example
mysql> LOCK TABLES real_table WRITE, insert_table WRITE;
mysql> INSERT INTO real_table SELECT * FROM insert_table;
mysql> TRUNCATE TABLE insert_table;
mysql> UNLOCK TABLES;
@end example

@code{InnoDB} uses row locks and @code{BDB} uses page locks. For the
@code{InnoDB} and @code{BDB} storage engines, deadlock is possible. This is
because @code{InnoDB} automatically acquires row locks and @code{BDB}
acquires page locks during the processing of SQL statements, not at the
start of the transaction.

Advantages of row-level locking:

@itemize @bullet
@item
Fewer lock conflicts when accessing different rows in many threads.
@item
Fewer changes for rollbacks.
@item
Makes it possible to lock a single row a long time.
@end itemize

Disadvantages of row-level locking:

@itemize @bullet
@item
Takes more memory than page-level or table-level locks.
@item
Is slower than page-level or table-level locks when used on a large part of
the table because you must acquire many more locks.
@item
Is definitely much worse than other locks if you often do @code{GROUP
BY} operations on a large part of the data or if you often must scan the
entire table.
@item
With higher-level locks, you can also more easily support locks of
different types to tune the application, because the lock overhead is less
than for row-level locks.
@end itemize

Table locks are superior to page-level or row-level locks in the
following cases:

@itemize @bullet
@item
Most statements for the table are reads.
@item
Read and updates on strict keys, where you update or delete
a row that can be fetched with a single key read:

@example
UPDATE @var{tbl_name} SET @var{column}=@var{value} WHERE @var{unique_key_col}=@var{key_value};
DELETE FROM @var{tbl_name} WHERE @var{unique_key_col}=@var{key_value};
@end example

@item
@code{SELECT} combined with concurrent @code{INSERT} statements, and very
few @code{UPDATE} and @code{DELETE} statements.
@item
Many scans or @code{GROUP BY} operations on the entire table without any writers.
@end itemize

Options other than row-level or page-level locking:

Versioning (such as we use in MySQL for concurrent inserts) where
you can have one writer at the same time as many readers.  This means
that the database/table supports different views for the data depending
on when you started to access it. Other names for this are time travel,
copy on write, or copy on demand.

Copy on demand is in many cases much better than page-level or row-level
locking. However, the worst case does use much more memory than
when using normal locks.

Instead of using row-level locks, you can use application-level locks,
such as @code{GET_LOCK()} and @code{RELEASE_LOCK()} in MySQL. These are
advisory locks, so they work only in well-behaved applications.


@node Table locking,  , Internal locking, Locking Issues
@subsection Table Locking Issues

@cindex problems, table locking

To achieve a very high lock speed, MySQL uses table locking (instead of
page, row, or column locking) for all storage engines except @code{InnoDB}
and @code{BDB}.

For @code{InnoDB} and @code{BDB} tables, MySQL only uses table locking if
you explicitly lock the table with @code{LOCK TABLES}.  For these table
types, we recommend you to not use @code{LOCK TABLES} at all, because
@code{InnoDB} uses automatic row-level locking and @code{BDB} uses
page-level locking to ensure transaction isolation.

For large tables, table locking is much better than row locking for most
applications, but there are some pitfalls.

Table locking enables many threads to read from a table at the same
time, but if a thread wants to write to a table, it must first get
exclusive access.  During the update, all other threads that want to
access this particular table must wait until the update is done.

Table updates normally are considered to be more important than table
retrievals, so they are given higher priority.  This should ensure that
updates to a table are not ``starved'' even if there is heavy @code{SELECT}
activity for the table.

Table locking causes problems in cases such as when
a thread is waiting because the disk is full and free space needs to become
available before the thread can proceed. In this case, all
threads that want to access the problem table will also be put in a waiting
state until more disk space is made available.

Table locking is also disadvantageous under the following scenario:

@itemize @bullet

@item
A client issues a @code{SELECT} that takes a long time to run.

@item
Another client then issues an @code{UPDATE} on the same table. This client
will wait until the @code{SELECT} is finished.

@item
Another client issues another @code{SELECT} statement on the same table.
Because
@code{UPDATE} has higher priority than @code{SELECT}, this @code{SELECT}
will wait for the @code{UPDATE} to finish.  It will also wait for the first
@code{SELECT} to finish!
@end itemize

The following list describes some ways to avoid or reduce contention caused by
table locking:

@itemize @bullet
@item
Try to get the @code{SELECT} statements to run faster. You might have to
create some summary tables to do this.

@item
Start @command{mysqld} with @code{--low-priority-updates}.  This gives
all statements that update (modify) a table lower priority than @code{SELECT}
statements. In this case, the second @code{SELECT} statement in the preceding
scenario would execute before the @code{INSERT} statement, and would not need
to wait for the first @code{SELECT} to finish.

@item
You can specify that all updates issued in a specific connection should be done
with low priority by using the @code{SET LOW_PRIORITY_UPDATES=1} statement.
@xref{SET OPTION, , @code{SET}}.

@item
You can give a specific @code{INSERT}, @code{UPDATE}, or @code{DELETE}
statement lower priority with the @code{LOW_PRIORITY} attribute.

@item
You can give a specific @code{SELECT} statement higher priority with the
@code{HIGH_PRIORITY} attribute. @xref{SELECT, , @code{SELECT}}.

@item
Starting from MySQL 3.23.7, you can start @command{mysqld} with a low value for
the @code{max_write_lock_count} system variable to force MySQL to
temporarily elevate the priority of all @code{SELECT} statements that are
waiting for a table after a specific number of inserts to the table occur.
This allows @code{READ} locks after a certain number of @code{WRITE} locks.

@item
If you have problems with @code{INSERT} combined with @code{SELECT}, switch
to using @code{MyISAM} tables, which support concurrent @code{SELECT} and
@code{INSERT} statements.

@item
If you mix inserts and deletes on the same table, @code{INSERT DELAYED}
may be of great help.
@xref{INSERT DELAYED, , @code{INSERT DELAYED}}.

@item
If you have problems with mixed @code{SELECT} and @code{DELETE} statements,
the @code{LIMIT} option to @code{DELETE} may help.
@xref{DELETE, , @code{DELETE}}.

@item
Using @code{SQL_BUFFER_RESULT} with @code{SELECT} statements can help to
make the duration of table locks shorter.
@xref{SELECT,  , @code{SELECT}}.

@item
You could change the locking code in @file{mysys/thr_lock.c} to use a
single queue.  In this case, write locks and read locks would have the same
priority, which might help some applications.

@end itemize

Here are some tips about table locking in MySQL:

@itemize @bullet

@item
Concurrent users are not a problem if you don't mix updates with selects
that need to examine many rows in the same table.

@item
You can use @code{LOCK TABLES} to speed up things (many updates within
a single lock is much faster than updates without locks).  Splitting
table contents into separate tables may also help.

@item
If you encounter speed problems with table locks in MySQL, you may be able
to improve performance by converting some of your tables to @code{InnoDB} or
@code{BDB} tables.
@xref{InnoDB,  , @code{InnoDB}}.
@xref{BDB storage engine,  , @code{BDB} storage engine}.
@end itemize


@node Optimizing Database Structure, Optimizing the Server, Locking Issues, MySQL Optimization
@section Optimizing Database Structure


@menu
* Design::                      Design Choices
* Data size::                   Make Your Data as Small as Possible
* Indexes::                     Column Indexes
* Multiple-column indexes::     Multiple-Column Indexes
* MySQL indexes::               How MySQL Uses Indexes
* MyISAM key cache::            The @code{MyISAM} Key Cache
* Open tables::                 How MySQL Counts Open Tables
* Table cache::                 How MySQL Opens and Closes Tables
* Creating many tables::        Drawbacks to Creating Many Tables in the Same Database
@end menu


@node Design, Data size, Optimizing Database Structure, Optimizing Database Structure
@subsection Design Choices

@cindex design, choices
@cindex database design
@cindex storage of data

MySQL keeps row data and index data in separate files. Many (almost all)
other databases mix row and index data in the same file. We believe that the
MySQL choice is better for a very wide range of modern systems.

Another way to store the row data is to keep the information for each
column in a separate area (examples are SDBM and Focus). This will cause a
performance hit for every query that accesses more than one column. Because
this degenerates so quickly when more than one column is accessed,
we believe that this model is not good for general-purpose databases.

The more common case is that the index and data are stored together
(as in Oracle/Sybase, et al). In this case, you will find the row
information at the leaf page of the index. The good thing with this
layout is that it, in many cases, depending on how well the index is
cached, saves a disk read.  The bad things with this layout are:

@itemize @bullet
@item
Table scanning is much slower because you have to read through the indexes
to get at the data.
@item
You can't use only the index table to retrieve data for a query.
@item
You use more space because you must duplicate indexes from the nodes
(you can't store the row in the nodes).
@item
Deletes will degenerate the table over time (because indexes in nodes are
usually not updated on delete).
@item
It's harder to cache only the index data.
@end itemize


@node Data size, Indexes, Design, Optimizing Database Structure
@subsection Make Your Data as Small as Possible

@cindex data, size
@cindex reducing, data size
@cindex storage space, minimising
@cindex tables, improving performance
@cindex performance, improving

One of the most basic optimizations is to design your tables to take as
little space on the disk as possible. This can give huge improvements
because disk reads are faster, and smaller tables normally require less main
memory while their contents are being actively processed during query
execution.  Indexing also is a lesser resource burden if done on smaller
columns.

MySQL supports a lot of different table types and row formats.  For each
table, you can decide which storage/index method to use.  Choosing the
right table format for your application may give you a big performance gain.
@xref{Storage engines}.

You can get better performance on a table and minimize storage space
using the techniques listed here:

@itemize @bullet
@item
Use the most efficient (smallest) data types possible. MySQL has
many specialized types that save disk space and memory.

@item
Use the smaller integer types if possible to get smaller tables. For
example, @code{MEDIUMINT} is often better than @code{INT}.

@item
Declare columns to be @code{NOT NULL} if possible. It makes everything
faster and you save one bit per column. If you really need
@code{NULL} in your application, you should definitely use it. Just avoid
having it on all columns by default.

@item
For @code{MyISAM} tables, if you don't have any variable-length columns
(@code{VARCHAR}, @code{TEXT}, or @code{BLOB} columns), a fixed-size record
format is used. This is faster but unfortunately may waste some space.
@xref{MyISAM table formats, , @code{MyISAM} table formats}.

@item
The primary index of a table should be as short as possible. This makes
identification of each row easy and efficient.

@item
Create only the indexes that you really need. Indexes are good for
retrieval but bad when you need to store things fast. If you mostly
access a table by searching on a combination of columns, make an index
on them. The first index part should be the most used column. If you are
@emph{always} using many columns, you should use the column with more
duplicates first to get better compression of the index.

@item
If it's very likely that a column has a unique prefix on the first number of
characters, it's better to index only this prefix. MySQL supports an index
on the leftmost part of a character column. Shorter indexes are faster not
only because they take less disk space, but also because they will give you
more hits in the index cache and thus fewer disk seeks.
@xref{Server parameters}.

@item
In some circumstances, it can be beneficial to split into two a table that is
scanned very often. This is especially true if it is a dynamic
format table and it is possible to use a smaller static format table that
can be used to find the relevant rows when scanning the table.
@end itemize


@node Indexes, Multiple-column indexes, Data size, Optimizing Database Structure
@subsection Column Indexes

@cindex indexes, columns
@cindex columns, indexes
@cindex keys

All MySQL column types can be indexed.  Use of indexes on the
relevant columns is the best way to improve the performance of @code{SELECT}
operations.

The maximum number of indexes per table and the maximum index length is
defined per storage engine. @xref{Storage engines}. All storage engines support at
least 16 indexes per table and a total index length of at least 256 bytes.
Most storage engines have higher limits.

With @code{@var{col_name}(@var{length})} syntax in an index specification,
you can create an index that uses only the first @var{length} characters of
a @code{CHAR} or @code{VARCHAR} column. Indexing only a prefix of column
values like this can make the index file much smaller.
@xref{Indexes}.

@cindex @code{BLOB} columns, indexing
@cindex indexes, and @code{BLOB} columns
@cindex @code{TEXT} columns, indexing
@cindex indexes, and @code{TEXT} columns
The @code{MyISAM} and (as of MySQL 4.0.14) @code{InnoDB} storage engines also
support indexing on @code{BLOB} and @code{TEXT} columns.  When indexing
a @code{BLOB} or @code{TEXT} column, you @emph{must} specify a prefix
length for the index. For example:

@example
CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
@end example

Prefixes can be up to 255 bytes long (or 1000 bytes for @code{MyISAM}
and @code{InnoDB} tables as of MySQL 4.1.2).  Note that prefix limits
are measured in bytes, whereas the prefix length in @code{CREATE TABLE}
statements is interpreted as number of characters.  Take this into account
when specifying a prefix length for a column that uses a multi-byte
character set.

As of MySQL 3.23.23, you can also create @code{FULLTEXT} indexes.
They are used for full-text searches. Only the @code{MyISAM} table type
supports @code{FULLTEXT} indexes and only for @code{CHAR}, @code{VARCHAR},
and @code{TEXT} columns.  Indexing always happens over the entire column and
partial (prefix) indexing is not supported. See @ref{Fulltext Search} for
details.

As of MySQL 4.1.0, you can create indexes on spatial column types.
Currently, spatial types are supported only by the @code{MyISAM} storage
engine. Spatial indexes use R-trees.

The @code{MEMORY} (@code{HEAP}) storage engine supports hash indexes.
As of MySQL 4.1.0, the engine also supports B-tree indexes.


@node Multiple-column indexes, MySQL indexes, Indexes, Optimizing Database Structure
@subsection Multiple-Column Indexes

@cindex multi-column indexes
@cindex indexes, multi-column
@cindex keys, multi-column

MySQL can create indexes on multiple columns.  An index may consist of up to
15 columns. For certain column types, you can index a prefix of the column
(@pxref{Indexes}).

A multiple-column index can be considered a sorted array containing values
that are created by concatenating the values of the indexed columns.

MySQL uses multiple-column indexes in such a way that queries are
fast when you specify a known quantity for the first column of the index in a
@code{WHERE} clause, even if you don't specify values for the other columns.

Suppose that a table has the following specification:

@example
CREATE TABLE test (
    id INT NOT NULL,
    last_name CHAR(30) NOT NULL,
    first_name CHAR(30) NOT NULL,
    PRIMARY KEY (id),
    INDEX name (last_name,first_name));
@end example

The @code{name} index is an index over @code{last_name} and
@code{first_name}.  The index can be used for queries that specify
values in a known range for @code{last_name}, or for both @code{last_name}
and @code{first_name}.
Therefore, the @code{name} index will be used in the following queries:

@example
SELECT * FROM test WHERE last_name='Widenius';

SELECT * FROM test
    WHERE last_name='Widenius' AND first_name='Michael';

SELECT * FROM test
    WHERE last_name='Widenius'
    AND (first_name='Michael' OR first_name='Monty');

SELECT * FROM test
    WHERE last_name='Widenius'
    AND first_name >='M' AND first_name < 'N';
@end example

However, the @code{name} index will @emph{not} be used in the following
queries:

@example
SELECT * FROM test WHERE first_name='Michael';

SELECT * FROM test
    WHERE last_name='Widenius' OR first_name='Michael';
@end example

The manner in which MySQL uses indexes to improve query performance is
discussed further in the next section.


@node MySQL indexes, MyISAM key cache, Multiple-column indexes, Optimizing Database Structure
@subsection How MySQL Uses Indexes

@cindex indexes, use of

Indexes are used to find rows with specific column values
fast. Without an index, MySQL has to start with the first record
and then read through the whole table to find the relevant
rows. The larger the table, the more this costs. If the table has an index
for the columns in question, MySQL can quickly determine the position to
seek to in the middle of the data file without having to look at all the
data. If a table has 1,000 rows, this is at least 100 times faster than
reading sequentially. Note that if you need to access almost all 1,000
rows, it is faster to read sequentially, because that minimizes disk seeks.

Most MySQL indexes (@code{PRIMARY KEY}, @code{UNIQUE}, @code{INDEX}, and
@code{FULLTEXT}) are stored in B-trees. Exceptions are that indexes on
spatial column types use R-trees, and @code{MEMORY} (@code{HEAP}) tables
support hash indexes.

Strings are automatically prefix- and end-space compressed.
@xref{CREATE INDEX, , @code{CREATE INDEX}}.

In general, indexes are used as described in the following discussion.
Characteristics specific to hash indexes (as used in @code{MEMORY} tables)
are described at the end of this section.

@itemize @bullet

@item
To quickly find the rows that match a @code{WHERE} clause.

@item
To eliminate rows from consideration.  If there is a choice between multiple
indexes, MySQL normally uses the index that finds the smallest number of
rows.

@item
To retrieve rows from other tables when performing joins.

@item
To find the @code{MIN()} or @code{MAX()} value for a specific indexed column
@var{key_col}. This is optimized by a preprocessor that checks whether you are
using @code{WHERE @var{key_part_#} = @var{constant}} on all key parts that occur before
@var{key_col} in the index.  In this case, MySQL will do a single key
lookup for each @code{MIN()} or @code{MAX()} expression and replace it
with a constant.  If all expressions are replaced with constants, the
query will return at once. For example:

@example
SELECT MIN(@var{key_part2}),MAX(@var{key_part2})
FROM @var{tbl_name} WHERE @var{key_part1}=10;
@end example

@item
To sort or group a table if the sorting or grouping is done on a leftmost
prefix of a usable key (for example, @code{ORDER BY @var{key_part1},
@var{key_part2}}).  If all key parts are followed by @code{DESC}, the key
is read in reverse order.
@xref{ORDER BY optimization,  , @code{ORDER BY} optimization}.

@item
In some cases, a query can be optimized to retrieve values without
consulting the data rows. If a query uses only columns from a table that are
numeric and that form a leftmost prefix for some key, the selected values
may be retrieved from the index tree for greater speed:

@example
SELECT @var{key_part3} FROM @var{tbl_name} WHERE @var{key_part1}=1
@end example

@end itemize

Suppose that you issue the following @code{SELECT} statement:

@example
mysql> SELECT * FROM @var{tbl_name} WHERE col1=val1 AND col2=val2;
@end example

If a multiple-column index exists on @code{col1} and @code{col2}, the
appropriate rows can be fetched directly. If separate single-column
indexes exist on @code{col1} and @code{col2}, the optimizer tries to
find the most restrictive index by deciding which index will find fewer
rows and using that index to fetch the rows.

@cindex indexes, leftmost prefix of
@cindex leftmost prefix of indexes
If the table has a multiple-column index, any leftmost prefix of the
index can be used by the optimizer to find rows. For example, if you
have a three-column index on @code{(col1, col2, col3)}, you have indexed
search capabilities on @code{(col1)}, @code{(col1, col2)}, and
@code{(col1, col2, col3)}.

MySQL can't use a partial index if the columns don't form a
leftmost prefix of the index.  Suppose that you have the @code{SELECT}
statements shown here:

@example
SELECT * FROM @var{tbl_name} WHERE col1=val1;
SELECT * FROM @var{tbl_name} WHERE col2=val2;
SELECT * FROM @var{tbl_name} WHERE col2=val2 AND col3=val3;
@end example

If an index exists on @code{(col1, col2, col3)}, only the first of the preceding
queries uses the index. The second and third queries do involve
indexed columns, but @code{(col2)} and @code{(col2, col3)} are not
leftmost prefixes of @code{(col1, col2, col3)}.

An index is used for columns that you compare with the @code{=}, @code{>},
@code{>=}, @code{<}, @code{<=}, or @code{BETWEEN} operators.

@findex LIKE, and indexes
@findex LIKE, and wildcards
@cindex indexes, and @code{LIKE}
@cindex wildcards, and @code{LIKE}
MySQL also uses indexes for @code{LIKE} comparisons if the argument
to @code{LIKE} is a constant string that doesn't start with a wildcard
character.  For example, the following @code{SELECT} statements use indexes:

@example
SELECT * FROM @var{tbl_name} WHERE @var{key_col} LIKE 'Patrick%';
SELECT * FROM @var{tbl_name} WHERE @var{key_col} LIKE 'Pat%_ck%';
@end example

In the first statement, only rows with @code{'Patrick' <= @var{key_col} <
'Patricl'} are considered.  In the second statement, only rows with
@code{'Pat' <= @var{key_col} < 'Pau'} are considered.

The following @code{SELECT} statements will not use indexes:
@example
SELECT * FROM @var{tbl_name} WHERE @var{key_col} LIKE '%Patrick%';
SELECT * FROM @var{tbl_name} WHERE @var{key_col} LIKE @var{other_col};
@end example

In the first statement, the @code{LIKE} value begins with a wildcard
character.  In the second statement, the @code{LIKE} value is not a
constant.

MySQL 4.0 and up performs an additional @code{LIKE} optimization.  If you use
@code{... LIKE '%@var{string}%'} and @var{string} is longer than three characters,
MySQL will use the @code{Turbo Boyer-Moore} algorithm to initialize the
pattern for the string and then use this pattern to perform the search
quicker.

@findex IS NULL, and indexes
@cindex indexes, and @code{IS NULL}
Searching using @code{@var{col_name} IS NULL} will use indexes if @var{col_name}
is indexed.

Any index that doesn't span all @code{AND} levels in the @code{WHERE} clause
is not used to optimize the query. In other words, to be able to use an
index, a prefix of the index must be used in every @code{AND} group.

The following @code{WHERE} clauses use indexes:
@example
... WHERE @var{index_part1}=1 AND @var{index_part2}=2 AND @var{other_column}=3
    /* @var{index} = 1 OR @var{index} = 2 */
... WHERE @var{index}=1 OR A=10 AND @var{index}=2
    /* optimized like "@var{index_part1}='hello'" */
... WHERE @var{index_part1}='hello' AND @var{index_part3}=5
    /* Can use index on @var{index1} but not on @var{index2} or @var{index3} */
... WHERE @var{index1}=1 AND @var{index2}=2 OR @var{index1}=3 AND @var{index3}=3;
@end example

These @code{WHERE} clauses do @emph{not} use indexes:

@c NOTE: the comments for the 2nd query below does not seem to make sense.
@c The comment for the 3rd query does not seem correct.

@example
    /* @var{index_part1} is not used */
... WHERE @var{index_part2}=1 AND @var{index_part3}=2 
    /* Index is not used in both AND parts */
... WHERE @var{index}=1 OR A=10                 
    /* No index spans all rows  */
... WHERE @var{index_part1}=1 OR @var{index_part2}=10
@end example

Sometimes MySQL will not use an index, even if one is available.  One way
this occurs is when the optimizer estimates that using the index would
require MySQL to access a large percentage of the rows in the table.
(In this case, a table scan is probably much faster, because it will
require many fewer seeks.) However, if such a query uses @code{LIMIT} to
only retrieve part of the rows, MySQL will use an index anyway, because
it can much more quickly find the few rows to return in the result.

Hash indexes have somewhat different characteristics than those just
discussed:

@itemize @bullet

@item
They are used only for @code{=} or @code{<=>} comparisons (but are
@emph{very} fast).

@item
The optimizer cannot use a hash index to speed up @code{ORDER BY}
operations. (This type of index cannot be used to search for the next entry
in order.)

@item
MySQL cannot determine approximately how many rows there
are between two values (this is used by the range optimizer to decide which
index to use).  This may affect some queries if you change a @code{MyISAM}
table to a hash-indexed @code{MEMORY} table.

@item
Only whole keys can be used to search for a row. (With a B-tree index,
any leftmost prefix of the key can be used to find rows.)

@end itemize



@node MyISAM key cache, Open tables, MySQL indexes, Optimizing Database Structure
@subsection The @code{MyISAM} Key Cache

@cindex MyISAM key cache
@cindex Key cache, MyISAM

@menu
* Shared key cache::            Shared Key Cache Access
* Multiple key caches::         Multiple Key Caches
* Midpoint insertion::          Midpoint Insertion Strategy
* Index preloading::            Index Preloading
* Key cache block size::        Key Cache Block Size
* Key cache restructuring::     Restructuring a Key Cache
@end menu

To minimize disk I/O, the @code{MyISAM} storage engine employs a strategy that
is used by many database management systems. It exploits a cache
mechanism to keep the most frequently accessed table blocks in memory:

@itemize @bullet
@item
For index blocks, a special structure called the key cache (key buffer)
is maintained. The structure contains a number of block buffers where the
most-used index blocks are placed.

@item
For data blocks, MySQL uses no special cache. Instead it relies on the
native operating system filesystem cache.

@end itemize

This section first describes the basic operation of the @code{MyISAM} key
cache. Then it discusses changes made in MySQL 4.1 that improve key cache
performance and that enable you to better control cache operation:

@itemize @bullet
@item
Access to the key cache no longer is serialized among threads. Multiple
threads can access the cache concurrently.

@item
You can set up multiple key caches and assign table indexes to specific
caches.

@end itemize

The key cache mechanism also is used for @code{ISAM} tables.  However, the
significance of this fact is on the wane.  @code{ISAM} table use has been
decreasing since MySQL 3.23 when @code{MyISAM} was introduced. MySQL 4.1
carries this trend further; the @code{ISAM} storage engine is disabled by
default.

You can control the size of the key cache by means of the
@code{key_buffer_size} system variable.  If this variable is set equal
to zero, no key cache is used.  The key cache also is not used if the
@code{key_buffer_size} value is too small to allocate the minimal number
of block buffers (8).

When the key cache is not operational, index files are accessed using only
the native filesystem buffering provided by the operating system.  (In other
words, table index blocks are accessed using the same strategy as that
employed for table data blocks.)

An index block is a contiguous unit of access to the @code{MyISAM} index files.
Usually the size of an index block is equal to the size of nodes of the
index B-tree. (Indexes are represented on disk using a B-tree data structure.
Nodes at the bottom of the tree are leaf nodes. Nodes above the leaf nodes
are non-leaf nodes.)

All block buffers in a key cache structure are the same size. This size can
be equal to, greater than, or less than the size of a table index block.
Usually one these two values is a multiple of the other.

When data from any table index block must be accessed, the server first
checks whether it is available in some block buffer of the key cache. If
it is, the server accesses data in the key cache rather than on disk.
That is, it reads from the cache or writes into it rather than reading
from or writing to disk. Otherwise, the server chooses a cache block
buffer containing a different table index block (or blocks) and replaces
the data there by a copy of required table index block.  As soon as the
new index block is in the cache, the index data can be accessed.

If it happens that a block selected for replacement has been modified,
the block is considered ``dirty.'' In this case, before being replaced, its
contents are flushed to the table index from which it came.

Usually the server follows an LRU (Least Recently Used) strategy: When
choosing a block for replacement, it selects the least recently used index
block. To be able to make such a choice easy, the key cache module maintains
a special queue (LRU chain) of all used blocks.  When a block is accessed,
it is placed at the end of the queue.  When blocks need to be replaced,
blocks at the beginning of the queue are the least recently used and become
the first candidates for eviction.


@node Shared key cache, Multiple key caches, MyISAM key cache, MyISAM key cache
@subsubsection Shared Key Cache Access

Prior to MySQL 4.1, access to the key cache is serialized:
No two threads can access key cache buffers simultaneously.
The server processes a request for an index block only after it has
finished processing the previous request. As a result, a request for an
index block not present in any key cache buffer blocks access by other
threads while a buffer is being updated to contain the requested index block.

Starting from version 4.1.0, the server supports shared access to the key
cache:

@itemize @bullet
@item
A buffer that is not being updated can be accessed by multiple threads.

@item
A buffer that is being updated causes threads that need to use it to wait
until the update is complete.

@item
Multiple threads can initiate requests that result in cache block
replacements, as long as they do not interfere with each other (that is,
as long as they need different index blocks, and thus cause different
cache blocks to be replaced).

@end itemize

Shared access to the key cache allows the server to improve throughput
significantly.


@node Multiple key caches, Midpoint insertion, Shared key cache, MyISAM key cache
@subsubsection Multiple Key Caches

Shared access to the key cache improves performance but does not eliminate
contention among threads entirely. They still compete for control structures
that manage access to the key cache buffers. To reduce key cache access
contention further, MySQL 4.1.1 offers the feature of multiple key caches.
This allows you to assign different table indexes to different key caches.

When there can be multiple key caches, the server must know which cache to
use when processing queries for a given @code{MyISAM} table. By default, all
@code{MyISAM} table indexes are cached in the default key cache. To assign
table indexes to a specific key cache, use the @code{CACHE INDEX} statement.

For example, the following statement assigns indexes from the tables
@code{t1}, @code{t2}, and @code{t3} to the key cache named @code{hot_cache}:

@example
mysql> CACHE INDEX t1, t2, t3 IN hot_cache;
+---------+--------------------+----------+----------+
| Table   | Op                 | Msg_type | Msg_text |
+---------+--------------------+----------+----------+
| test.t1 | assign_to_keycache | status   | OK       |
| test.t2 | assign_to_keycache | status   | OK       |
| test.t3 | assign_to_keycache | status   | OK       |
+---------+--------------------+----------+----------+
@end example

@strong{Note}: If the server has been built with the @code{ISAM} storage
engine enabled, @code{ISAM} tables use the key cache mechanism. However,
@code{ISAM} indexes use only the default key cache and cannot be reassigned to
a different cache.

The key cache referred to in a @code{CACHE INDEX} statement can be created
by setting its size with a @code{SET GLOBAL} parameter setting statement or by
using server startup options.  For example:

@example
mysql> SET GLOBAL keycache1.key_buffer_size=128*1024;
@end example

To destroy a key cache, set its size to zero:

@example
mysql> SET GLOBAL keycache1.key_buffer_size=0;
@end example

Key cache variables are structured system variables that have a name and
components. For @code{keycache1.key_buffer_size}, @code{keycache1} is the
cache variable name and @code{key_buffer_size} is the cache component.
See @ref{Structured System Variables} for a description of the syntax used
for referring to structured key cache system variables.

By default, table indexes are assigned to the main (default) key cache
created at the server startup. When a key cache is destroyed, all indexes
assigned to it are reassigned to the default key cache.

For a busy server, we recommend a strategy that uses three key caches:

@itemize @bullet

@item
A hot key cache that takes up 20% of the space allocated for all key
caches. This is used for tables that are heavily used for searches but that
are not updated.

@item
A cold key cache that takes up 20% of the space allocated for all key
caches.  This is used for medium-sized intensively modified tables,
such as temporary tables.

@item
A warm key cache that takes up 60% of the key cache space.  This is the
default key cache, to be used by default for all other tables.

@end itemize

One reason the use of three key caches is beneficial is that access to one
key cache structure does not block access to the others.  Queries that
access tables assigned to one cache do not compete with queries that
access tables assigned to another cache.  Performance gains occur for
other reasons as well:

@itemize @bullet

@item
The hot cache is used only for retrieval queries, so its contents are
never modified.  Consequently, whenever an index block needs to be pulled
in from disk, the contents of the cache block chosen for replacement need
not be flushed first.

@item
For an index assigned to the hot cache, if there are no queries
requiring an index scan, there is a high probability that the index
blocks corresponding to non-leaf nodes of the index B-tree will remain
in the cache.

@item
An update operation most frequently executed for temporary tables is
performed much faster when the updated node already is in the cache and need
not be read in from disk first. If the size of the indexes of the temporary
tables are comparable with the size of cold key cache, the probability is
very high that the updated node already will be in the cache.

@end itemize


@node Midpoint insertion, Index preloading, Multiple key caches, MyISAM key cache
@subsubsection Midpoint Insertion Strategy


By default, the key cache management system of MySQL 4.1 uses the LRU
strategy for choosing key cache blocks to be evicted, but it also supports a
more sophisticated method called the "midpoint insertion strategy."

When using the midpoint insertion strategy, the LRU chain is divided into
two parts: a hot sub-chain and a warm sub-chain. The division point between
two parts is not fixed, but the key cache management system takes care that
the warm part is not ``too short,'' always containing at least
@code{key_cache_division_limit} percent of the key cache blocks.
@code{key_cache_division_limit} is a component of structured key cache
variables, so its value is a parameter that can be set per cache.

When an index block is read from a table into the key cache, it is placed
at the end of the warm sub-chain. After a certain number of hits (accesses
of the block), it is promoted to the hot sub-chain.  At present, the number
of hits required to promote a block (3) is the same for all index blocks.
In the future, we will allow the hit count to depend on the B-tree level
of the node corresponding to an index block: Fewer hits will be required
for promotion of an index block if it contains a non-leaf node from the
upper levels of the index B-tree than if it contains a leaf node.

A block promoted into the hot sub-chain is placed at the end of the chain.
The block then circulates within this sub-chain. If the block stays at the
beginning of the sub-chain for a long enough time, it is demoted to the warm
chain. This time is determined by the value of the
@code{key_cache_age_threshold} component of the key cache.

The threshold value prescribes that, for a key cache containing @var{N}
blocks, the block at the beginning of the hot sub-chain not accessed within
the last @code{@var{N}*key_cache_age_threshold/100} hits is to be moved to the
beginning of the warm sub-chain. It then becomes the first candidate for
eviction, because blocks for replacement always are taken from the beginning
of the warm sub-chain.

The midpoint insertion strategy allows you to keep more-valued blocks
always in the cache. If you prefer to use the plain LRU strategy, leave the
@code{key_cache_division_limit} value set to its default of 100.

The midpoint insertion strategy helps to improve performance when execution
of a query that requires an index scan effectively pushes out of the cache
all the index blocks corresponding to valuable high-level B-tree nodes. To
avoid this, you must use a midpoint insertion strategy with the
@code{key_cache_division_limit} set to much less than 100.  Then valuable
frequently hit nodes will be preserved in the hot sub-chain during an index
scan operation as well.


@node Index preloading, Key cache block size, Midpoint insertion, MyISAM key cache
@subsubsection Index Preloading

If there are enough blocks in a key cache to hold blocks of an entire
index, or at least the blocks corresponding to its non-leaf nodes, then
it makes sense to preload the key cache with index blocks before starting
to use it. Preloading allows you to put the table index blocks into a key
cache buffer in the most efficient way: by reading the index blocks from
disk sequentially.

Without preloading, the blocks still will be placed into the key cache as
needed by queries. Although the blocks will stay
in the cache, because there are enough buffers for all of them, they will be
fetched from disk in a random order, not sequentially.

To preload an index into a cache, use the @code{LOAD INDEX INTO CACHE}
statement. For example,
the following statement preloads nodes (index blocks) of indexes of the
tables @code{t1} and @code{t2}:

@example
mysql> LOAD INDEX INTO CACHE t1, t2 IGNORE LEAVES;
+---------+--------------+----------+----------+
| Table   | Op           | Msg_type | Msg_text |
+---------+--------------+----------+----------+
| test.t1 | preload_keys | status   | OK       |
| test.t2 | preload_keys | status   | OK       |
+---------+--------------+----------+----------+
@end example

The @code{IGNORE LEAVES} modifier causes only blocks for the non-leaf
nodes of the index to be preloaded. Thus,
the statement shown preloads all index blocks from @code{t1}, but only
blocks for the non-leaf nodes from @code{t2}.

If an index has been assigned to a key cache using a
@code{CACHE INDEX} statement, preloading places index blocks into that cache.
Otherwise, the index is loaded into the default key cache.


@node Key cache block size, Key cache restructuring, Index preloading, MyISAM key cache
@subsubsection Key Cache Block Size

MySQL 4.1 introduces a new @code{key_cache_block_size} variable on
a per-key cache basis. This variable specifies the size of the block
buffers for a key cache.  It is intended to allow tuning of the performance
of I/O operations for index files.

The best performance for I/O operations is achieved when the size of
read buffers is equal to the size of the native operating system I/O
buffers. But setting the size of key nodes equal to the size of the I/O buffer
does not always ensure the best overall performance. When reading the
big leaf nodes, the server pulls in a lot of unnecessary data, effectively
preventing reading other leaf nodes.

Currently, you cannot control the size of the index blocks in a table.  This
size is set by the server when the @file{.MYI} index file is created,
depending on the size of the keys in the indexes present in the table
definition.  In most cases, it is set equal to the I/O buffer size. In the
future, this will be changed and then @code{key_cache_block_size} variable
will be fully employed.


@node Key cache restructuring,  , Key cache block size, MyISAM key cache
@subsubsection Restructuring a Key Cache

A key cache can be restructured at any time by updating its parameter
values.  For example:

@example
mysql> SET GLOBAL cold_cache.key_buffer_size=4*1024*1024;
@end example

If you assign to either the @code{key_buffer_size} or
@code{key_cache_block_size} key cache component a value that differs from
the component's current value, the server destroys the cache's old
structure and creates a new one based on the new values.  If the cache
contains any dirty blocks, the server saves them to disk before destroying
and re-creating the cache. Restructuring does not occur if you set other key
cache parameters.

When restructuring a key cache, the server first flushes the contents of any
dirty buffers to disk. After that, the cache contents become unavailable.
However, restructuring does not block queries that need to use indexes
assigned to the cache.  Instead, the server directly accesses the table
indexes using native filesystem caching.  Filesystem caching is not as
efficient as using a key cache, so although queries will execute, a slowdown
can be anticipated.  Once the cache has been restructured, it becomes
available again for caching indexes assigned to it, and the use of filesystem
caching for the indexes ceases.


@node Open tables, Table cache, MyISAM key cache, Optimizing Database Structure
@subsection How MySQL Counts Open Tables

@cindex tables, open
@cindex open tables

When you execute a @command{mysqladmin status} command, you'll see something
like this:

@example
Uptime: 426 Running threads: 1 Questions: 11082
Reloads: 1 Open tables: 12
@end example

The @code{Open tables} value of 12 can be somewhat puzzling if you have
only six tables.

MySQL is multi-threaded, so there may be many clients issuing queries for a
given table simultaneously. To minimize the problem with multiple client threads
having different states on the same table, the table is opened independently
by each concurrent thread. This takes some memory but normally increases
performance.  With @code{MyISAM} tables, one extra file descriptor is
required for the data file for each client that has the table open. (By
contrast, the index file descriptor is shared between all threads.) The
@code{ISAM} storage engine shares this behavior.

You can read more about this topic in the next section. @xref{Table cache}.

@node Table cache, Creating many tables, Open tables, Optimizing Database Structure
@subsection How MySQL Opens and Closes Tables

@findex table_cache

@cindex tables, opening
@cindex tables, closing
@cindex opening, tables
@cindex closing, tables
@cindex table cache

The @code{table_cache}, @code{max_connections}, and @code{max_tmp_tables}
system variables affect the maximum number of files the server keeps open.
If you increase one or more of these values, you may run up against a limit
imposed by your operating system on the per-process number of open file
descriptors.  Many operating systems allow you to increase the open-files
limit, although the method varies widely from system to system.  Consult your
operating system documentation to determine whether it is possible to
increase the limit and how to do so.

@code{table_cache} is related to @code{max_connections}.  For example,
for 200 concurrent running connections, you should have a table cache size of
at least @code{200 * @var{N}}, where @var{N} is the maximum number of tables
in a join.  You also need to reserve some extra file descriptors for
temporary tables and files.

Make sure that your operating system can handle the number of open file
descriptors implied by the @code{table_cache} setting.  If
@code{table_cache} is set too high, MySQL may run out of file
descriptors and refuse connections, fail to perform queries, and be very
unreliable.  You also have to take into account that the @code{MyISAM} storage
engine needs two file descriptors for each unique open table. You can
increase the number of file descriptors available for MySQL with
the @code{--open-files-limit} startup option to @command{mysqld_safe}.
@xref{Not enough file handles}.

The cache of open tables will be kept at a level of @code{table_cache}
entries. The default value is 64; this can be changed with the
@code{--table_cache} option to @command{mysqld}.  Note that MySQL may
temporarily open even more tables to be able to execute queries.

An unused table is closed and removed from the table cache under the
following circumstances:

@itemize @bullet
@item
When the cache is full and a thread tries to open a table that is not in
the cache.
@item
When the cache contains more than @code{table_cache} entries and
a thread is no longer using a table.
@item
When a table flushing operation occurs. This happens when someone issues a
@code{FLUSH TABLES} statement or executes a @command{mysqladmin flush-tables}
or @command{mysqladmin refresh} command.
@end itemize

When the table cache fills up, the server uses the following procedure
to locate a cache entry to use:

@itemize @bullet
@item
Tables that are not currently in use are released, in least recently used
order.

@item
If a new table needs to be opened, but the cache is full and no tables
can be released, the cache is temporarily extended as necessary.
@end itemize

When the cache is in a temporarily extended state and a table goes from a used
to unused state, the table is closed and released from the cache.

@c TODO: does following paragraph apply to MyISAM/ISAM only? - PD

A table is opened for each concurrent access. This means the table needs
to be opened twice if two threads access the same table or if a thread
accesses the table twice in the same query (for example, by joining the
table to itself).  Each concurrent open requires an entry in the table
cache. The first open of any table takes two file descriptors: one for the
data file and one for the index file.  Each additional use of the table
takes only one file descriptor, for the data file.  The index file
descriptor is shared among all threads.

If you are opening a table with the @code{HANDLER @var{tbl_name} OPEN}
statement, a dedicated table object is allocated for the thread.
This table object is not shared by other threads and is not closed
until the thread calls @code{HANDLER @var{tbl_name} CLOSE} or the thread
terminates.  When this happens, the table is put back in the table cache
(if the cache isn't full).
@xref{HANDLER, , @code{HANDLER}}.

You can determine whether your table cache is too small by checking the
@command{mysqld} status variable @code{Opened_tables}:

@example
mysql> SHOW STATUS LIKE 'Opened_tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Opened_tables | 2741  |
+---------------+-------+
@end example

If the value is quite big, even when you haven't issued a lot of @code{FLUSH
TABLES} statements, you should increase your table cache size.
See @ref{Server system variables} and @ref{Server status variables}.


@node Creating many tables,  , Table cache, Optimizing Database Structure
@subsection Drawbacks to Creating Many Tables in the Same Database

@cindex tables, too many

If you have many @code{MyISAM} or @code{ISAM} tables in a database
directory, open, close, and create operations will be slow.  If you execute
@code{SELECT} statements on many different tables, there will be a little
overhead when the table cache is full, because for every table that has to
be opened, another must be closed. You can reduce this overhead by making
the table cache larger.


@node Optimizing the Server, Disk issues, Optimizing Database Structure, MySQL Optimization
@section Optimizing the MySQL Server


@menu
* System::                      System Factors and Startup Parameter Tuning
* Server parameters::           Tuning Server Parameters
* Controlling optimizer::       Controlling Query Optimizer Performance
* Compile and link options::    How Compiling and Linking Affects the Speed of MySQL
* Memory use::                  How MySQL Uses Memory
* DNS::                         How MySQL Uses DNS
@end menu


@node System, Server parameters, Optimizing the Server, Optimizing the Server
@subsection System Factors and Startup Parameter Tuning

@cindex compiling, optimizing
@cindex system optimization
@cindex startup parameters, tuning

We start with system-level factors, because some of these decisions must be
made very early to achieve large performance gains. In other cases, a quick
look at this section may suffice. However, it is always nice to have a sense
of how much can be gained by changing things at this level.

The default operating system to use is very important!  To get the best
use of multiple-CPU machines, you should use Solaris (because its threads
implementation works really well) or Linux (because the 2.4 kernel has
really good SMP support).  Note that older Linux kernels have a 2GB filesize
limit by default. If you have such a kernel and a desperate need for files
larger than 2GB, you should get the Large File Support (LFS) patch for the
ext2 filesystem.  Other filesystems such as ReiserFS and XFS do not have
this 2GB limitation.

Before using MySQL in production, we advise you to test it on your intended
platform.

@cindex locking
Other tips:
@itemize @bullet

@item
If you have enough RAM, you could remove all swap devices. Some
operating systems will use a swap device in some contexts even if you
have free memory.

@item
Use the @code{--skip-external-locking} MySQL option to avoid external
locking.  This option is on by default as of MySQL 4.0.
Before that, it is on by default when compiling with
MIT-pthreads, because @code{flock()} isn't fully supported by
MIT-pthreads on all platforms.  It's also on by default for Linux
because Linux file locking is not yet safe.

Note that the @code{--skip-external-locking} option will not affect MySQL's
functionality as long as you run only one server. Just remember to take
down the server (or lock and flush the relevant tables) before you run
@command{myisamchk}. On some systems this option is mandatory, because the
external locking does not work in any case.

The only case when you can't use @code{--skip-external-locking} is if you run
multiple MySQL @emph{servers} (not clients) on the same data,
or if you run @command{myisamchk} to check (not repair) a table without telling
the server to flush and lock the tables first.

You can still use @code{LOCK TABLES} and @code{UNLOCK TABLES} even if you
are using @code{--skip-external-locking}.
@end itemize


@node Server parameters, Controlling optimizer, System, Optimizing the Server
@subsection Tuning Server Parameters

@cindex parameters, server
@cindex @command{mysqld} server, buffer sizes
@cindex buffer sizes, @command{mysqld} server
@cindex startup parameters

You can determine the default buffer sizes used by the @command{mysqld} server
with this command (prior to MySQL 4.1, omit @code{--verbose}):

@example
shell> mysqld --verbose --help
@end example

@cindex @command{mysqld} options
@cindex variables, @command{mysqld}
This command produces a list of all @command{mysqld} options and configurable
system variables. The output includes the default variable values and
looks something like this:

@example
back_log                 current value: 5
bdb_cache_size           current value: 1048540
binlog_cache_size        current value: 32768
connect_timeout          current value: 5
delayed_insert_limit     current value: 100
delayed_insert_timeout   current value: 300
delayed_queue_size       current value: 1000
flush_time               current value: 0
interactive_timeout      current value: 28800
join_buffer_size         current value: 131072
key_buffer_size          current value: 1048540
long_query_time          current value: 10
lower_case_table_names   current value: 0
max_allowed_packet       current value: 1048576
max_binlog_cache_size    current value: 4294967295
max_connect_errors       current value: 10
max_connections          current value: 100
max_delayed_threads      current value: 20
max_heap_table_size      current value: 16777216
max_join_size            current value: 4294967295
max_sort_length          current value: 1024
max_tmp_tables           current value: 32
max_write_lock_count     current value: 4294967295
myisam_sort_buffer_size  current value: 8388608
net_buffer_length        current value: 16384
net_read_timeout         current value: 30
net_retry_count          current value: 10
net_write_timeout        current value: 60
read_buffer_size         current value: 131072
read_rnd_buffer_size     current value: 262144
slow_launch_time         current value: 2
sort_buffer              current value: 2097116
table_cache              current value: 64
thread_concurrency       current value: 10
thread_stack             current value: 131072
tmp_table_size           current value: 1048576
wait_timeout             current value: 28800
@end example

If there is a @command{mysqld} server currently running, you can see what
values it actually is using for the system variables by connecting to it and
issuing this statement:

@example
mysql> SHOW VARIABLES;
@end example

You can also see some statistical and status indicators for a running server
by issuing this statement:

@example
mysql> SHOW STATUS;
@end example

System variable and status information also can be obtained using
@command{mysqladmin}:

@example
shell> mysqladmin variables
shell> mysqladmin extended-status
@end example

You can find a full description for all system and status variables in
@ref{Server system variables} and @ref{Server status variables}.

MySQL uses algorithms that are very scalable, so you can usually run with
very little memory. However, normally you will get better performance by
giving MySQL more memory.

When tuning a MySQL server, the two most important variables to configure
are @code{key_buffer_size} and @code{table_cache}.  You should first feel
confident that you have these set appropriately before trying to change
any other variables.

The following examples indicate some typical variable values for different
runtime configurations. The examples use the @command{mysqld_safe} script and
use @code{--@var{var_name}=@var{value}} syntax to set the variable @var{var_name} to the value
@var{value}.  This syntax is available as of MySQL 4.0.  For older versions
of MySQL, take the following differences into account:

@itemize @bullet
@item
Use @command{safe_mysqld} rather than @command{mysqld_safe}.

@item
Set variables using @code{--set-variable=@var{var_name}=@var{value}} or @code{-O
@var{var_name}=@var{value}} syntax.

@item
For variable names that end in @code{_size}, you may need to specify them
without @code{_size}. For example, the old name for @code{sort_buffer_size} is
@code{sort_buffer}. The old name for @code{read_buffer_size} is
@code{record_buffer}. To see which variables your version of the server
recognizes, use @command{mysqld --help}.

@end itemize


If you have at least 256MB of memory and many tables and want maximum
performance with a moderate number of clients, you should use something
like this:

@example
shell> mysqld_safe --key_buffer_size=64M --table_cache=256 \
           --sort_buffer_size=4M --read_buffer_size=1M &
@end example

If you have only 128MB of memory and only a few tables, but you still do a
lot of sorting, you can use something like this:

@example
shell> mysqld_safe --key_buffer_size=16M --sort_buffer_size=1M
@end example

If there are very many simultaneous connections, swapping problems
may occur unless @command{mysqld} has been configured to use very
little memory for each connection. @command{mysqld} performs better
if you have enough memory for all connections.

With little memory and lots of connections, use something like this:

@example
shell> mysqld_safe --key_buffer_size=512K --sort_buffer_size=100K \
           --read_buffer_size=100K &
@end example

Or even this:

@example
shell> mysqld_safe --key_buffer_size=512K --sort_buffer_size=16K \
           --table_cache=32 --read_buffer_size=8K \
           --net_buffer_length=1K &
@end example

If you are doing @code{GROUP BY} or @code{ORDER BY} operations on tables
that are much larger than your available memory, you should increase the
value of @code{read_rnd_buffer_size} to speed up the reading of rows after
sorting operations.

When you have installed MySQL, the @file{support-files} directory will
contain some different @file{my.cnf} sample files: @file{my-huge.cnf},
@file{my-large.cnf}, @file{my-medium.cnf}, and @file{my-small.cnf}. You can
use these as a basis for optimizing your system.

Note that if you specify an option on the command line for @command{mysqld} or
@command{mysqld_safe}, it remains in effect only for that invocation of the server.
To use the option every time the server runs, put it in an option file.

To see the effects of a parameter change, do something like this (prior to
MySQL 4.1, omit @code{--verbose}):

@example
shell> mysqld --key_buffer_size=32M --verbose --help
@end example

The variable values are listed near the end of the output.
Make sure that the @code{--verbose} and @code{--help} options are
last. Otherwise, the effect of any options listed after them on the command
line will not be reflected in the output.

For information on tuning the @code{InnoDB} storage engine, see
@ref{InnoDB tuning,  , @code{InnoDB} tuning}.


@node Controlling optimizer, Compile and link options, Server parameters, Optimizing the Server
@subsection Controlling Query Optimizer Performance

@cindex optimizer, controlling

The task of the query optimizer is to find an optimal plan for executing
an SQL query. Because the difference in performance between ``good'' and
``bad'' plans can be orders of magnitude (that is, seconds versus hours
or even days), most query optimizers, including that of MySQL, perform
more or less exhaustive search for an optimal plan among all possible
query evaluation plans. For join queries, the number of possible plans
investigated by the MySQL optimizer grows exponentially with the number
of tables referenced in a query. For small numbers of tables (typically
less than 7-10) this is not a problem. However, when bigger queries are
submitted, the time spent in query optimization may easily become the
major bottleneck in the server performance.

MySQL 5.0.1 introduces a new more flexible method for query optimization
that allows the user to control how exhaustive the optimizer is in its
search for an optimal query evaluation plan. The general idea is that the
fewer plans that are investigated by the optimizer, the less time it will
spend in compiling a query. On the other hand, because the optimizer will
skip some plans, it may miss finding an optimal plan.

The behavior of the optimizer with respect to the number of plans it
evaluates can be controlled via two system variables:

@itemize @bullet
@item
The @code{optimizer_prune_level} variable tells the optimizer to skip
certain plans based on estimates of the number of rows accessed for each
table. Our experience shows that this kind of ``educated guess'' rarely
misses optimal plans, while it may dramatically reduce query compilation
times. That is why this option is on (@code{optimizer_prune_level}=1)
by default. However, if you believe that the optimizer missed better query
plans, then this option can be switched off (@code{optimizer_prune_level}=0)
with the risk that query compilation may take much longer. Notice that
even with the use of this heuristic, the optimizer will still explore a
roughly exponential number of plans.

@item
The @code{optimizer_search_depth} variable tells how far in the
``future'' of each incomplete plan the optimizer should look in order
to evaluate whether it should be expanded further.  Smaller values of
@code{optimizer_search_depth} may result in orders of magnitude smaller query
compilation times. For example, queries with 12-13 or more tables may easily
require hours and even days to compile if @code{optimizer_search_depth}
is close to the number of tables in the query. At the same time, if
compiled with @code{optimizer_search_depth} equal to 3 or 4, the compiler
may compile in less than a minute for the same query. If you are unsure of
what a reasonable value is for @code{optimizer_search_depth}, this variable
can be set to 0 to tell the optimizer to determine the value automatically.

@end itemize


@node Compile and link options, Memory use, Controlling optimizer, Optimizing the Server
@subsection How Compiling and Linking Affects the Speed of MySQL

@cindex linking, speed
@cindex compiling, speed
@cindex speed, compiling
@cindex speed, linking

Most of the following tests were performed on Linux with the
MySQL benchmarks, but they should give some indication for
other operating systems and workloads.

You get the fastest executables when you link with @code{-static}.

On Linux, you will get the fastest code when compiling with @code{pgcc}
and @code{-O3}.  You need about 200MB memory to compile @file{sql_yacc.cc}
with these options, because @command{gcc/pgcc} needs a lot of memory to
make all functions inline. You should also set @code{CXX=gcc} when
configuring MySQL to avoid inclusion of the @code{libstdc++}
library, which is not needed. Note that with some versions of @code{pgcc},
the resulting code will run only on true Pentium processors, even if you
use the compiler option indicating that you want the resulting code to work on
all x586-type processors (such as AMD).

By just using a better compiler and better compiler options, you can
get a 10-30% speed increase in your application.  This is particularly
important if you compile the MySQL server yourself.

We have tested both the Cygnus CodeFusion and Fujitsu compilers, but
when we tested them, neither was sufficiently bug-free to allow
MySQL to be compiled with optimizations enabled.

The standard MySQL binary distributions are compiled with support for all
character sets.  When you compile MySQL yourself, you should include support
only for the character sets that you are going to use. This is controlled by
the @code{--with-charset} option to @command{configure}.

Here is a list of some measurements that we have made:

@itemize @bullet

@item
If you use @code{pgcc} and compile everything with @code{-O6}, the
@command{mysqld} server is 1% faster than with @command{gcc} 2.95.2.

@item
If you link dynamically (without @code{-static}), the result is 13%
slower on Linux.  Note that you still can use a dynamically linked
MySQL library for your client applications. It is the server that is most
critical for performance.

@item
If you strip your @command{mysqld} binary with @code{strip mysqld},
the resulting binary can be up to 4% faster.

@item
For a connection from a client to a server running on the same host,
if you connect using TCP/IP rather than a Unix socket file, performance is 7.5%
slower. (On Unix, if you connect to the hostname @code{localhost},
MySQL uses a socket file by default.)

@item
For TCP/IP connections from a client to a server, connecting to a remote
server on another host will be 8-11% slower than connecting to the local
server on the same host, even for connections over 100Mb/s Ethernet.

@item
When running our benchmark tests using secure connections (all data
encrypted with internal SSL support) performance was 55% slower than for
unencrypted connections.

@item
If you compile with @code{--with-debug=full}, most queries will be 20% slower.
Some queries may take substantially longer; for example,
the MySQL benchmarks ran 35% slower.  If you use @code{--with-debug} (without
@code{=full}),
the slowdown will be only 15%.  For a version of @command{mysqld} that has
been compiled with @code{--with-debug=full}, you can disable memory
checking at runtime by starting it with the @code{--skip-safemalloc}
option. The execution speed should then be close to that obtained when
configuring with @code{--with-debug}.

@item
On a Sun UltraSPARC-IIe, a server compiled with Forte 5.0 is 4% faster than
one compiled with @command{gcc} 3.2.

@item
On a Sun UltraSPARC-IIe, a server compiled with Forte 5.0 is 4% faster in
32-bit mode than in 64-bit mode.

@item
Compiling with @command{gcc} 2.95.2 for UltraSPARC with the
@code{-mcpu=v8 -Wa,-xarch=v8plusa} options gives 4% more performance.

@item
On Solaris 2.5.1, MIT-pthreads is 8-12% slower than Solaris native
threads on a single processor. With more load or CPUs, the difference should
be larger.

@item
Compiling on Linux-x86 using @command{gcc} without frame pointers
(@code{-fomit-frame-pointer} or @code{-fomit-frame-pointer -ffixed-ebp})
makes @command{mysqld} 1-4% faster.
@end itemize

Binary MySQL distributions for Linux that are provided by MySQL AB used
to be compiled with @code{pgcc}. We had to go back to regular @command{gcc}
due to a bug in @code{pgcc} that would generate code that does
not run on AMD. We will continue using @command{gcc} until that bug is resolved.
In the meantime, if you have a non-AMD machine, you can get a faster
binary by compiling with @code{pgcc}.  The standard MySQL
Linux binary is linked statically to make it faster and more portable.


@node Memory use, DNS, Compile and link options, Optimizing the Server
@subsection How MySQL Uses Memory

@cindex memory use

The following list indicates some of the ways that the @command{mysqld} server
uses memory.  Where applicable, the name of the system variable relevant
to the memory use is given:

@itemize @bullet
@item
The key buffer (variable @code{key_buffer_size}) is shared by all
threads; other buffers used by the server are allocated as
needed. @xref{Server parameters}.

@item
Each connection uses some thread-specific space:

@itemize @bullet
@item
A stack (default 64KB, variable @code{thread_stack})

@item
A connection buffer (variable @code{net_buffer_length})

@item
A result buffer (variable @code{net_buffer_length})

@end itemize

The connection buffer and result buffer are
dynamically enlarged up to @code{max_allowed_packet} when needed.  While
a query is running, a copy of the current query string is also allocated.

@item
All threads share the same base memory.

@item
Only compressed @code{ISAM} and @code{MyISAM} tables are memory mapped.  This
is because the 32-bit memory space of 4GB is not large enough for most
big tables. When systems with a 64-bit address space become more
common, we may add general support for memory mapping.

@item
Each request that performs a sequential scan of a table allocates a read buffer
(variable @code{read_buffer_size}).

@item
When reading rows in ``random'' order (for example, after a sort), a
random-read buffer may be allocated to avoid disk seeks.
(variable @code{read_rnd_buffer_size}).

@item
All joins are done in one pass, and most joins can be done without even
using a temporary table. Most temporary tables are memory-based (@code{HEAP})
tables.  Temporary tables with a large record length (calculated as the
sum of all column lengths) or that contain @code{BLOB} columns are
stored on disk.

One problem before MySQL 3.23.2 is that if an internal in-memory
heap table exceeds the size of @code{tmp_table_size}, the error @code{The
table @var{tbl_name} is full} occurs. From 3.23.2 on, this is handled
automatically by changing the in-memory heap table to a disk-based
@code{MyISAM} table as necessary. To work around this problem for older
servers, you can increase the temporary table size by setting the
@code{tmp_table_size} option to @command{mysqld}, or by setting the SQL option
@code{SQL_BIG_TABLES} in the client program.
@xref{SET OPTION, , @code{SET} Syntax}.

In MySQL 3.20, the maximum size of the temporary table is
@code{record_buffer*16}; if you are using this version, you have to increase
the value of @code{record_buffer}. You can also start @command{mysqld} with the
@code{--big-tables} option to always store temporary tables on disk.
However, this will affect the speed of many complicated queries.

@item
Most requests that perform a sort allocate a sort buffer and zero to two temporary
files depending on the result set size. @xref{Temporary files}.

@item
Almost all parsing and calculating is done in a local memory store. No
memory overhead is needed for small items, so the normal slow memory
allocation and freeing is avoided. Memory is allocated only for
unexpectedly large strings; this is done with @code{malloc()} and
@code{free()}.

@item
For each @code{MyISAM} and @code{ISAM} table that is opened, the index file
is opened once and the data file is opened once for each concurrently running
thread. For each concurrent thread, a table structure, column structures for
each column, and a buffer of size @code{3 * @var{N}} are allocated (where @var{N}
is the maximum row length, not counting @code{BLOB} columns). A @code{BLOB}
column requires five to eight bytes plus the length of the @code{BLOB} data.
The @code{MyISAM} and @code{ISAM} storage engines maintain one extra row
buffer for internal use.

@item
For each table having @code{BLOB} columns, a buffer is enlarged dynamically
to read in larger @code{BLOB} values. If you scan a table, a buffer as large
as the largest @code{BLOB} value is allocated.

@item
Handler structures for all in-use tables are saved in a cache and managed as a
FIFO. By default, the cache has 64 entries. If a table has been used by two
running threads at the same time, the cache contains two entries for the
table. @xref{Table cache}.

@item
A @code{FLUSH TABLES} statement or  @command{mysqladmin flush-tables} command
closes all tables that are not in use at once and marks all in-use tables to be
closed when the currently executing thread finishes. This effectively frees
most in-use memory. @code{FLUSH TABLES} does not return until all tables have
been closed.

@end itemize

@command{ps} and other system status programs may report that @command{mysqld}
uses a lot of memory. This may be caused by thread stacks on different
memory addresses. For example, the Solaris version of @command{ps} counts
the unused memory between stacks as used memory. You can verify this by
checking available swap with @code{swap -s}. We have tested
@command{mysqld} with several memory-leakage detectors (both commercial and open
source), so there should be no memory leaks.


@node DNS,  , Memory use, Optimizing the Server
@subsection How MySQL Uses DNS

@cindex DNS
@cindex hostname caching

When a new client connects to @command{mysqld}, @command{mysqld} spawns a
new thread to handle the request.  This thread first checks whether the
hostname is in the hostname cache. If not, the thread attempts to resolve the
hostname:

@itemize @bullet
@item
If the operating system supports the thread-safe @code{gethostbyaddr_r()} and
@code{gethostbyname_r()} calls, the thread uses them to perform hostname
resolution.

@item
If the operating system doesn't support the thread-safe calls, the
thread locks a mutex and calls @code{gethostbyaddr()} and
@code{gethostbyname()} instead. In this case, no other thread
can resolve hostnames that are not in the hostname cache until the
first thread unlocks the mutex.

@end itemize

You can disable DNS hostname lookups by starting @command{mysqld} with the
@code{--skip-name-resolve} option.  However, in this case, you can use only IP
numbers in the MySQL grant tables.

If you have a very slow DNS and many hosts, you can get more performance by
either disabling DNS lookups with @code{--skip-name-resolve} or by
increasing the @code{HOST_CACHE_SIZE} define (default value: 128) and
recompiling @command{mysqld}.

You can disable the hostname cache by starting the server with the
@code{--skip-host-cache} option. To clear the hostname cache, issue a
@code{FLUSH HOSTS} statement or execute the @command{mysqladmin flush-hosts}
command.

If you want to disallow TCP/IP connections entirely, start @command{mysqld} with
the @code{--skip-networking} option.


@node Disk issues,  , Optimizing the Server, MySQL Optimization
@section Disk Issues

@cindex disk issues
@cindex performance, disk issues

@itemize @bullet
@item
Disk seeks are a big performance bottleneck. This problem becomes more
apparent when the amount of data starts to grow so
large that effective caching becomes impossible. For large databases
where you access data more or less randomly, you can be sure that you
will need at least one disk seek to read and a couple of disk seeks to
write things. To minimize this problem, use disks with low seek times.

@item
Increase the number of available disk spindles (and thereby reduce
the seek overhead) by either symlinking files to different disks or striping
the disks:

@table @asis
@item Using symbolic links
This means that, for @code{MyISAM} tables, you symlink the index file and/or
data file from their usual location in the data directory to another disk
(that may also be striped). This makes both the seek and read times better,
assuming that the disk is not used for other purposes as well. @xref{Symbolic
links}.

@item Striping
@cindex striping, defined
Striping means that you have many disks and put the first block on the
first disk, the second block on the second disk, and the Nth block on the
(N mod number_of_disks) disk, and so on. This means if your normal data
size is less than the stripe size (or perfectly aligned), you will get
much better performance. Striping is very dependent on the operating system
and the stripe size, so benchmark your application with different
stripe sizes. @xref{Custom Benchmarks}.

The speed difference for striping is @emph{very} dependent on
the parameters. Depending on how you set the striping parameters and number
of disks, you may get differences measured in orders of magnitude.
You have to choose to optimize for random or sequential access.

@end table

@item
For reliability you may want to use RAID 0+1 (striping plus mirroring), but
in this case, you will need 2*N drives to hold N drives of data. This is
probably the best option if you have the money for it!  However, you may
also have to invest in some volume-management software to handle it
efficiently.

@item
A good option is to vary the RAID level according to how critical a type of
data is. For example, store semi-important data that can be regenerated
on a RAID 0 disk, but store really important data such as host information
and logs on a RAID 0+1 or RAID N disk. RAID N can be a problem if you
have many writes, due to the time required to update the parity bits.

@item
On Linux, you can get much more performance by using @code{hdparm} to
configure your disk's interface.  (Up to 100% under load is not uncommon.)
The following @code{hdparm} options should be quite good for MySQL, and
probably for many other applications:

@example
hdparm -m 16 -d 1
@end example

Note that performance and reliability when using this command depends
on your hardware, so we strongly suggest that you test your system
thoroughly after using @code{hdparm}.  Please consult the @code{hdparm}
manual page for more information.  If @code{hdparm} is not used wisely,
filesystem corruption may result, so back up everything before
experimenting!

@item
You can also set the parameters for the filesystem that the database uses:

If you don't need to know when files were last accessed (which is
not really useful on a database server), you can mount your
filesystems with the @code{-o noatime} option.  That skips updates
to the last access time in inodes on the filesystem, which avoids
some disk seeks.

On many operating systems, you can set a filesystem to be updated
asynchronously by mounting it with the @code{-o async} option.  If your
computer is reasonably stable, this should give you more performance without
sacrificing too much reliability.  (This flag is on by default on Linux.)

@end itemize

@menu
* Symbolic links::              Using Symbolic Links
@end menu


@node Symbolic links,  , Disk issues, Disk issues
@subsection Using Symbolic Links

@cindex symbolic links
@cindex links, symbolic

You can move tables and databases from the database directory to other
locations and replace them with symbolic links to the new locations.
You might want to do this, for example, to move a database to a file
system with more free space or increase the speed of your system by
spreading your tables to different disk.

The recommended way to do this is to just symlink databases to a
different disk. Symlink tables only as a last resort.

@menu
* Symbolic links to databases::  Using Symbolic Links for Databases on Unix
* Symbolic links to tables::    Using Symbolic Links for Tables on Unix
* Windows symbolic links::      Using Symbolic Links for Databases on Windows
@end menu


@node Symbolic links to databases, Symbolic links to tables, Symbolic links, Symbolic links
@subsubsection Using Symbolic Links for Databases on Unix

@cindex databases, symbolic links

On Unix, the way to symlink a database is to first create a directory on some
disk where you have free space and then create a symlink to it from
the MySQL data directory.

@example
shell> mkdir /dr1/databases/test
shell> ln -s /dr1/databases/test @var{/path/to/datadir}
@end example

MySQL doesn't support linking one directory to multiple
databases.  Replacing a database directory with a symbolic link will
work fine as long as you don't make a symbolic link between databases.
Suppose that you have a database @code{db1} under the MySQL data
directory, and then make a symlink @code{db2} that points to @code{db1}:

@example
shell> cd @var{/path/to/datadir}
shell> ln -s db1 db2
@end example

Now, for any table @code{tbl_a} in @code{db1}, there also appears to be
a table @code{tbl_a} in @code{db2}.  If one client updates @code{db1.tbl_a}
and another client updates @code{db2.tbl_a}, there will be problems.

If you really need to do this, you can change one of the source files.
The file to modify depends on your version of MySQL. For MySQL 4.0 and up,
look for the following statement in the @file{mysys/my_symlink.c} file:

@example
if (!(MyFlags & MY_RESOLVE_LINK) || 
    (!lstat(filename,&stat_buff) && S_ISLNK(stat_buff.st_mode)))
@end example

Before MySQL 4.0, look for this statement in the @file{mysys/mf_format.c} file:

@example
if (flag & 32 || (!lstat(to,&stat_buff) && S_ISLNK(stat_buff.st_mode)))
@end example

Change the statement to this:

@example
if (1)
@end example

On Windows, you can use internal symbolic links to directories by compiling
MySQL with @code{-DUSE_SYMDIR}. This allows you to put different
databases on different disks. @xref{Windows symbolic links}.


@node Symbolic links to tables, Windows symbolic links, Symbolic links to databases, Symbolic links
@subsubsection Using Symbolic Links for Tables on Unix

@cindex tables, symbolic links

Before MySQL 4.0, you should not symlink tables unless you are
@emph{very} careful with them. The problem is that if you run @code{ALTER
TABLE}, @code{REPAIR TABLE}, or @code{OPTIMIZE TABLE} on a symlinked
table, the symlinks will be removed and replaced by the original
files. This happens because these statements work by creating a
temporary file in the database directory and replacing the original
file with the temporary file when the statement operation is complete.

You should not symlink tables on systems that don't have a fully
working @code{realpath()} call. (At least Linux and Solaris support
@code{realpath()}). You can check whether your system supports symbolic links
by issuing a @code{SHOW VARIABLES LIKE 'have_symlink'} statement.

In MySQL 4.0, symlinks are fully supported only for @code{MyISAM}
tables.  For other table types, you will probably get strange problems
if you try to use symbolic links on files in the operating system with
any of the preceding statements.

The handling of symbolic links for @code{MyISAM} tables in MySQL 4.0 works
the following way:

@itemize @bullet
@item
In the data directory, you will always have the table definition
file, the data file, and the index file. The data file and index file
can be moved elsewhere and replaced in the data directory by
symlinks. The definition file cannot.

@item
You can symlink the data file and the index file independently to different
directories.

@item
The symlinking can be done manually from the command line with @code{ln -s}
if @command{mysqld} is not running. With SQL, you can instruct the server to
perform the symlinking by using the @code{DATA DIRECTORY} and @code{INDEX
DIRECTORY} options to @code{CREATE TABLE}.
@xref{CREATE TABLE,  , @code{CREATE TABLE}}.

@item
@command{myisamchk} will not replace a symlink with the data file or index file.
It works directly on the file a symlink points to. Any temporary files
are created in the directory where the data file or index file is
located.

@item
When you drop a table that is using symlinks, both the symlink and the
file the symlink points to are dropped.  This is a good reason why you
should @emph{not} run @command{mysqld} as @code{root} or allow
users to have write access to the MySQL database directories.

@item
@c TODO: is this also true for RENAME table?
If you rename a table with @code{ALTER TABLE ... RENAME} and you don't move
the table to another database, the symlinks in the database directory
are renamed to the new names and the data file and index file are
renamed accordingly.

@item
@c TODO: is this also true for RENAME table?
If you use @code{ALTER TABLE ... RENAME} to move a table to another database,
the table is moved to the other database directory. The old
symlinks and the files to which they pointed are deleted.  In other words,
the new table will not be symlinked.

@item
If you are not using symlinks, you should use the @code{--skip-symbolic-links}
option to @command{mysqld} to ensure that no one can use @command{mysqld} to drop
or rename a file outside of the data directory.
@end itemize

@code{SHOW CREATE TABLE} doesn't report if a table has symbolic links
prior to MySQL 4.0.15. This is also true for @command{mysqldump}, which uses
@code{SHOW CREATE TABLE} to generate @code{CREATE TABLE} statements.

Table symlink operations that are not yet supported:

@cindex TODO, symlinks
@itemize @bullet
@item
@code{ALTER TABLE} ignores the @code{DATA DIRECTORY} and @code{INDEX
DIRECTORY} table options.
@item
@code{BACKUP TABLE} and @code{RESTORE TABLE} don't respect symbolic
links.
@item
The @file{.frm} file must @emph{never} be a symbolic link (as indicated
previously, only the data and index files can be symbolic links).  Attempting
to do this (for example, to make synonyms) will produce incorrect results.
Suppose that you have a database @code{db1} under the MySQL data directory,
a table @code{tbl1} in this database, and in the @code{db1} directory you
make a symlink @code{tbl2} that points to @code{tbl1}:

@example
shell> cd @var{/path/to/datadir}/db1
shell> ln -s tbl1.frm tbl2.frm
shell> ln -s tbl1.MYD tbl2.MYD
shell> ln -s tbl1.MYI tbl2.MYI
@end example

Now there will be problems if one thread reads @code{db1.tbl1} and another
thread updates @code{db1.tbl2}:

@itemize @minus
@item
The query cache will be fooled (it will believe @code{tbl1} has not been
updated so will return out-of-date results).
@item
@code{ALTER} statements on @code{tbl2} will also fail.
@end itemize

@end itemize


@node Windows symbolic links,  , Symbolic links to tables, Symbolic links
@subsubsection Using Symbolic Links for Databases on Windows

@cindex symbolic links
@cindex using multiple disks to start data
@cindex disks, splitting data across

Beginning with MySQL 3.23.16, the @command{mysqld-max}
and @code{mysql-max-nt} servers for Windows are
compiled with the @code{-DUSE_SYMDIR} option.  This allows you to put a
database directory on a different disk by setting up a symbolic link to it.
This is similar to the way that symbolic links work on Unix, although the
procedure for setting up the link is different.

As of MySQL 4.0, symbolic links are enabled by default. If you don't need them,
you can disable them with the @code{skip-symbolic-links} option:

@example
[mysqld]
skip-symbolic-links
@end example

Before MySQL 4.0, symbolic links are disabled by default. To enable them,
you should put the following entry in your @file{my.cnf} or @file{my.ini}
file:

@example
[mysqld]
symbolic-links
@end example

On Windows, you make a symbolic link to a MySQL database by creating a file
in the data directory that contains the path to the destination directory.
The file should be named @file{db_name.sym}, where @var{db_name} is the
database name.

Suppose that the MySQL data directory is @file{C:\mysql\data}
and you want to have database @code{foo} located at @file{D:\data\foo}.
Set up a symlink like this:

@enumerate

@item
Make sure that the @file{D:\data\foo} directory exists by creating it if
necessary.  If you
already have a database directory named @file{foo} in the data directory,
you should move it to @file{D:\data}. Otherwise, the symbolic link will be
ineffective.  To avoid problems, the server should not be running when you
move the database directory.

@item
Create a file @file{C:\mysql\data\foo.sym} that contains the pathname
@code{D:\data\foo\}.

@end enumerate

After that, all tables created in the database @code{foo} will be created in
@file{D:\data\foo}.  Note that the symbolic link will not be used if a
directory with the database name exists in the MySQL data directory.


@node Client-Side Scripts, Language Structure, MySQL Optimization, Top
@chapter MySQL Client and Utility Programs

@c TODO: mysqlaccess
@c TODO: point out which programs support the SSL options
@c TODO: option versions where applicable

There are many different MySQL client programs that connect to the server to
access databases or perform administrative tasks. Other utilities are
available as well. These do not communicate with the server but perform
MySQL-related operations.

This chapter provides a brief overview of these programs and then a more
detailed description of each one.  The descriptions indicate how to invoke the
programs and the options they understand.
See @ref{Using MySQL Programs} for general information on invoking programs
and specifying program options.

@menu
* Client-Side Overview::        Overview of the Client-Side Scripts and Utilities
* myisampack::                  @command{myisampack}, the MySQL Compressed Read-only Table Generator
* mysql::                       @command{mysql}, the Command-Line Tool
* mysqladmin::                  @command{mysqladmin}, Administering a MySQL Server
* mysqlbinlog::                 The @command{mysqlbinlog} Binary Log Utility
* mysqlcc::                     @command{mysqlcc}, the MySQL Control Center
* Using mysqlcheck::            The @command{mysqlcheck} Table Maintenance and Repair Program
* mysqldump::                   The @command{mysqldump} Database Backup Program
* mysqlhotcopy::                The @command{mysqlhotcopy} Database Backup Program
* mysqlimport::                 The @command{mysqlimport} Data Import Program
* mysqlshow::                   @command{mysqlshow}, Showing Databases, Tables, and Columns
* perror::                      @command{perror}, Explaining Error Codes
* replace utility::             The @command{replace} String-Replacement Utility
@end menu


@node Client-Side Overview, myisampack, Client-Side Scripts, Client-Side Scripts
@section Overview of the Client-Side Scripts and Utilities

The following list briefly describes the MySQL client programs and utilities:

@c TODO: not listed here: mysqldumpslow

@table @code

@item myisampack
@cindex @command{myisampack}
A utility that compresses @code{MyISAM} tables to produce smaller read-only
tables.
@xref{myisampack, , @command{myisampack}}.

@item mysql
@cindex @command{mysql}
The command-line tool for interactively entering SQL statements or executing
them from a file in batch mode.
@xref{mysql, , @command{mysql}}.

@item mysqlaccess
@cindex @command{mysqlaccess}
A script that checks the access privileges for a host, user, and database
combination.

@item mysqladmin
@cindex @command{mysqladmin}
A client that performs administrative operations, such as creating or
dropping databases, reloading the grant tables, flushing tables to disk, and
reopening log files.  @command{mysqladmin} can also be used to retrieve version,
process, and status information from the server.
@xref{mysqladmin, , @command{mysqladmin}}.

@item mysqlbinlog
@cindex @command{mysqlbinlog}
A utility for reading statements from a binary log. The log of executed
statements contained in the binary log files can be used to help recover
from a crash.
@xref{mysqlbinlog, , @command{mysqlbinlog}}.

@item mysqlcc
@cindex @command{mysqlcc}
A client that provides a graphical interface for interacting with the
server.
@xref{mysqlcc, , @command{mysqlcc}}.

@item mysqlcheck
@cindex @command{mysqlcheck}
A table-maintenance client that checks, repairs, analyzes, and optimizes
tables.
@xref{Using mysqlcheck, , Using @command{mysqlcheck}}.

@item mysqldump
@cindex @command{mysqldump}
A client that dumps a MySQL database into a file as SQL statements or
as tab-separated text files. Enhanced freeware originally by Igor Romanenko.
@xref{mysqldump, , @command{mysqldump}}.

@item mysqlhotcopy
@cindex @command{mysqlhotcopy}
A utility that quickly makes backups of @code{MyISAM} or @code{ISAM} tables
while the server is running.
@xref{mysqlhotcopy, , @command{mysqlhotcopy}}.

@item mysqlimport
@cindex @command{mysqlimport}
A client that imports text files into their respective tables using
@code{LOAD DATA INFILE}.
@xref{mysqlimport, , @command{mysqlimport}}.

@item mysqlshow
@cindex @command{mysqlshow}
A client that displays information about databases, tables, columns,
and indexes.
@xref{mysqlshow, , @command{mysqlshow}}.

@item perror
@cindex @command{perror}
A utility that displays the meaning of system or MySQL error codes.
@xref{perror, , @command{perror}}.

@item replace
@cindex @command{replace}
A utility program that changes strings in place in
files or on the standard input.
@xref{replace utility, , @command{replace} utility}.

@end table

Each MySQL program takes many different options. However, every MySQL program
provides a @code{--help} option that you can use to get a full description
of the program's different options. For example, try @command{mysql --help}.

@cindex environment variables

MySQL clients that communicate with the server using the
@code{mysqlclient} library use the following environment variables:

@tindex @code{MYSQL_UNIX_PORT} environment variable
@tindex environment variable, @code{MYSQL_UNIX_PORT}
@tindex @code{MYSQL_TCP_PORT} environment variable
@tindex environment variable, @code{MYSQL_TCP_PORT}
@tindex @code{MYSQL_PWD} environment variable
@tindex environment variable, @code{MYSQL_PWD}
@tindex @code{MYSQL_DEBUG} environment variable
@tindex environment variable, @code{MYSQL_DEBUG}

@multitable @columnfractions .25 .75
@item @code{MYSQL_UNIX_PORT}
@tab The default Unix socket file; used for connections to @code{localhost}
@item @code{MYSQL_TCP_PORT} 
@tab The default port number; used for TCP/IP connections
@item @code{MYSQL_PWD}
@tab The default password
@item @code{MYSQL_DEBUG}
@tab Debug trace options when debugging
@item @code{TMPDIR}
@tab The directory where temporary tables and files are created
@end multitable

Use of @code{MYSQL_PWD} is insecure.
@xref{Password security}.

You can override the default option values or values specified in
environment variables for all standard programs by specifying options in an
option file or on the command line.
@ref{Program Options}.


@node myisampack, mysql, Client-Side Overview, Client-Side Scripts
@section @command{myisampack}, the MySQL Compressed Read-only Table Generator

@cindex compressed tables
@cindex tables, compressed
@cindex MyISAM, compressed tables
@cindex @command{myisampack}
@cindex @command{pack_isam}

The @command{myisampack} utility compresses @code{MyISAM} tables.
@command{myisampack} works by compressing each column in the table separately.
Usually, @command{myisampack} packs the data file 40%-70%.

When the table is used later, the information needed to decompress columns
is read into memory.  This results in much better performance when accessing
individual records, because you only have to uncompress exactly one record,
not a much larger disk block as when using Stacker on MS-DOS.

MySQL uses @code{mmap()} when possible to perform memory mapping on
compressed tables. If @code{mmap()} doesn't work, MySQL falls back to
normal read/write file operations.

A similar utility, @command{pack_isam}, compresses @code{ISAM} tables. Because
@code{ISAM} tables are deprecated, this section discusses only
@command{myisampack}, but the general procedures for using @command{myisampack}
are also true for @command{pack_isam} unless otherwise specified.

Please note the following:

@itemize @bullet

@item
If the @command{mysqld} server was invoked with the
@code{--skip-external-locking} option, it is not a good idea to invoke
@command{myisampack} if the table might be updated by the server during the
packing process.

@item
After packing a table, it becomes read-only. This is generally intended
(such as when accessing packed tables on a CD). Allowing writes
to a packed table is on our TODO list, but with low priority.

@item
@command{myisampack} can pack @code{BLOB} or @code{TEXT} columns.
The older @command{pack_isam} program for @code{ISAM} tables cannot.

@end itemize

Invoke @command{myisampack} like this:

@example
shell> myisampack [@var{options}] @var{filename} ...
@end example

Each filename should be the name of an index (@file{.MYI}) file.  If you
are not in the database directory, you should specify the pathname to the
file.  It is permissible to omit the @file{.MYI} extension.

@command{myisampack} supports the following options:

@table @code

@item --help, -?
Display a help message and exit.

@item --backup, -b
Make a backup of the table data file using the name @file{@var{tbl_name}.OLD}.

@item --debug[=@var{debug_options}], -# [@var{debug_options}]
Write a debugging log. The @var{debug_options} string often is
@code{'d:t:o,@var{file_name}'}.

@item --force, -f
Produce a packed table even if it becomes larger than the original or if
the temporary file from an earlier invocation of @command{myisampack} exists.
(@command{myisampack} creates a temporary file named @file{@var{tbl_name}.TMD} while
it compresses the table.  If you kill @command{myisampack}, the @file{.TMD}
file might not be deleted.)  Normally, @command{myisampack} exits with an
error if it finds that @file{@var{tbl_name}.TMD} exists.  With @code{--force},
@command{myisampack} packs the table anyway.

@item --join=@var{big_tbl_name}, -j @var{big_tbl_name}
Join all tables named on the command line into a single table
@var{big_tbl_name}.  All tables that are to be combined @emph{must}
have identical structure (same column names and types, same indexes,
and so forth).

@item --packlength=@var{#}, -p @var{#}
Specify the record length storage size, in bytes.  The value should be 1, 2,
or 3.  @command{myisampack} stores all rows with length pointers of 1, 2, or 3
bytes.  In most normal cases, @command{myisampack} can determine the right length
value before it begins packing the file, but it may notice during the packing
process that it could have used a shorter length. In this case,
@command{myisampack} will print a note that the next time you pack the same file,
you could use a shorter record length.

@item --silent, -s
Silent mode.  Write output only when errors occur.

@item --test, -t
Don't actually pack the table, just test packing it.

@item --tmp_dir=@var{path}, -T @var{path}
Use the named directory as the location in which to write the temporary table.

@item --verbose, -v
Verbose mode.  Write information about the progress of the packing operation
and its result.

@item --version, -V
Display version information and exit.

@item --wait, -w

Wait and retry if the table is in use.  If the @command{mysqld} server was
invoked with the @code{--skip-external-locking} option, it is not a good idea
to invoke @command{myisampack} if the table might be updated by the server during
the packing process.

@end table

@cindex examples, compressed tables
The following sequence of commands illustrates a typical table compression
session:

@example
shell> ls -l station.*
-rw-rw-r--   1 monty    my         994128 Apr 17 19:00 station.MYD
-rw-rw-r--   1 monty    my          53248 Apr 17 19:00 station.MYI
-rw-rw-r--   1 monty    my           5767 Apr 17 19:00 station.frm

shell> myisamchk -dvv station

MyISAM file:     station
Isam-version:  2
Creation time: 1996-03-13 10:08:58
Recover time:  1997-02-02  3:06:43
Data records:              1192  Deleted blocks:              0
Datafile parts:            1192  Deleted data:                0
Datafile pointer (bytes):     2  Keyfile pointer (bytes):     2
Max datafile length:   54657023  Max keyfile length:   33554431
Recordlength:               834
Record format: Fixed length

table description:
Key Start Len Index   Type                 Root  Blocksize    Rec/key
1   2     4   unique  unsigned long        1024       1024          1
2   32    30  multip. text                10240       1024          1

Field Start Length Type
1     1     1
2     2     4
3     6     4
4     10    1
5     11    20
6     31    1
7     32    30
8     62    35
9     97    35
10    132   35
11    167   4
12    171   16
13    187   35
14    222   4
15    226   16
16    242   20
17    262   20
18    282   20
19    302   30
20    332   4
21    336   4
22    340   1
23    341   8
24    349   8
25    357   8
26    365   2
27    367   2
28    369   4
29    373   4
30    377   1
31    378   2
32    380   8
33    388   4
34    392   4
35    396   4
36    400   4
37    404   1
38    405   4
39    409   4
40    413   4
41    417   4
42    421   4
43    425   4
44    429   20
45    449   30
46    479   1
47    480   1
48    481   79
49    560   79
50    639   79
51    718   79
52    797   8
53    805   1
54    806   1
55    807   20
56    827   4
57    831   4

shell> myisampack station.MYI
Compressing station.MYI: (1192 records)
- Calculating statistics

normal:     20  empty-space:   16  empty-zero:     12  empty-fill:  11
pre-space:   0  end-space:     12  table-lookups:   5  zero:         7
Original trees:  57  After join: 17
- Compressing file
87.14%
Remember to run myisamchk -rq on compressed tables

shell> ls -l station.*
-rw-rw-r--   1 monty    my         127874 Apr 17 19:00 station.MYD
-rw-rw-r--   1 monty    my          55296 Apr 17 19:04 station.MYI
-rw-rw-r--   1 monty    my           5767 Apr 17 19:00 station.frm

shell> myisamchk -dvv station

MyISAM file:     station
Isam-version:  2
Creation time: 1996-03-13 10:08:58
Recover time:  1997-04-17 19:04:26
Data records:               1192  Deleted blocks:              0
Datafile parts:             1192  Deleted data:                0
Datafile pointer (bytes):      3  Keyfile pointer (bytes):     1
Max datafile length:    16777215  Max keyfile length:     131071
Recordlength:                834
Record format: Compressed

table description:
Key Start Len Index   Type                 Root  Blocksize    Rec/key
1   2     4   unique  unsigned long       10240       1024          1
2   32    30  multip. text                54272       1024          1

Field Start Length Type                         Huff tree  Bits
1     1     1      constant                             1     0
2     2     4      zerofill(1)                          2     9
3     6     4      no zeros, zerofill(1)                2     9
4     10    1                                           3     9
5     11    20     table-lookup                         4     0
6     31    1                                           3     9
7     32    30     no endspace, not_always              5     9
8     62    35     no endspace, not_always, no empty    6     9
9     97    35     no empty                             7     9
10    132   35     no endspace, not_always, no empty    6     9
11    167   4      zerofill(1)                          2     9
12    171   16     no endspace, not_always, no empty    5     9
13    187   35     no endspace, not_always, no empty    6     9
14    222   4      zerofill(1)                          2     9
15    226   16     no endspace, not_always, no empty    5     9
16    242   20     no endspace, not_always              8     9
17    262   20     no endspace, no empty                8     9
18    282   20     no endspace, no empty                5     9
19    302   30     no endspace, no empty                6     9
20    332   4      always zero                          2     9
21    336   4      always zero                          2     9
22    340   1                                           3     9
23    341   8      table-lookup                         9     0
24    349   8      table-lookup                        10     0
25    357   8      always zero                          2     9
26    365   2                                           2     9
27    367   2      no zeros, zerofill(1)                2     9
28    369   4      no zeros, zerofill(1)                2     9
29    373   4      table-lookup                        11     0
30    377   1                                           3     9
31    378   2      no zeros, zerofill(1)                2     9
32    380   8      no zeros                             2     9
33    388   4      always zero                          2     9
34    392   4      table-lookup                        12     0
35    396   4      no zeros, zerofill(1)               13     9
36    400   4      no zeros, zerofill(1)                2     9
37    404   1                                           2     9
38    405   4      no zeros                             2     9
39    409   4      always zero                          2     9
40    413   4      no zeros                             2     9
41    417   4      always zero                          2     9
42    421   4      no zeros                             2     9
43    425   4      always zero                          2     9
44    429   20     no empty                             3     9
45    449   30     no empty                             3     9
46    479   1                                          14     4
47    480   1                                          14     4
48    481   79     no endspace, no empty               15     9
49    560   79     no empty                             2     9
50    639   79     no empty                             2     9
51    718   79     no endspace                         16     9
52    797   8      no empty                             2     9
53    805   1                                          17     1
54    806   1                                           3     9
55    807   20     no empty                             3     9
56    827   4      no zeros, zerofill(2)                2     9
57    831   4      no zeros, zerofill(1)                2     9
@end example

@command{myisampack} displays the following kinds of information:

@table @code
@item normal
The number of columns for which no extra packing is used.

@item empty-space
The number of columns containing
values that are only spaces; these will occupy one bit.

@item empty-zero
The number of columns containing
values that are only binary zeros; these will occupy one bit.

@item empty-fill
The number of integer columns that don't occupy the full byte range of their
type; these are changed to a smaller type.  For example, a @code{BIGINT}
column (eight bytes) can be stored as a @code{TINYINT} column (one byte) if
all its values are in the range from @code{-128} to @code{127}.

@item pre-space
The number of decimal columns that are stored with leading spaces. In this
case, each value will contain a count for the number of leading spaces.

@item end-space
The number of columns that have a lot of trailing spaces.  In this case, each
value will contain a count for the number of trailing spaces.

@item table-lookup
The column had only a small number of different values, which were
converted to an @code{ENUM} before Huffman compression.

@item zero
The number of columns for which all values are zero.

@item Original trees
The initial number of Huffman trees.

@item After join
The number of distinct Huffman trees left after joining
trees to save some header space.
@end table

After a table has been compressed, @command{myisamchk -dvv} prints additional
information about each column:

@table @code
@item Type
The column type. The value may contain any of the following descriptors:

@table @code
@item constant
All rows have the same value.

@item no endspace
Don't store endspace.

@item no endspace, not_always
Don't store endspace and don't do endspace compression for all values.

@item no endspace, no empty
Don't store endspace. Don't store empty values.

@item table-lookup
The column was converted to an @code{ENUM}.

@item zerofill(@var{n})
The most significant @var{n} bytes in the value are always 0 and are not
stored.

@item no zeros
Don't store zeros.

@item always zero
Zero values are stored using one bit.
@end table

@item Huff tree
The number of the Huffman tree associated with the column.

@item Bits
The number of bits used in the Huffman tree.
@end table

After you run @command{myisampack}, you must run
@command{myisamchk} to re-create any indexes.  At this time, you
can also sort the index blocks and create statistics needed for
the MySQL optimizer to work more efficiently:

@example
shell> myisamchk -rq --sort-index --analyze @var{tbl_name}.MYI
@end example

A similar procedure applies for @code{ISAM} tables. After using
@command{pack_isam}, use @command{isamchk} to re-create the indexes:

@example
shell> isamchk -rq --sort-index --analyze @var{tbl_name}.ISM
@end example

After you have installed the packed table into the MySQL database directory,
you should execute @command{mysqladmin flush-tables} to force @command{mysqld}
to start using the new table.

To unpack a packed table, use the @code{--unpack} option to @command{myisamchk}
or @command{isamchk}.


@node mysql, mysqladmin, myisampack, Client-Side Scripts
@section @command{mysql}, the Command-Line Tool

@c TODO: describe input-line editing

@cindex command-line tool
@cindex tools, command-line
@cindex scripts, SQL
@cindex SQL scripts
@cindex @command{mysql}

@menu
* mysql Commands::              @command{mysql} Commands
* Batch Commands::              Executing SQL Statements from a Text File
* mysql Tips::                  @command{mysql} Tips
@end menu

@command{mysql} is a simple SQL shell (with GNU @code{readline} capabilities).
It supports interactive and non-interactive use. When used interactively,
query results are presented in an ASCII-table format. When used
non-interactively (for example, as a filter), the result is presented in
tab-separated format.  The output format can be changed using command-line
options.

If you have problems due to insufficient memory for large result sets, use the
@code{--quick} option.  This forces @command{mysql} to retrieve results from
the server a row at a time rather than retrieving the entire result set
and buffering it in memory before displaying it.  This is done by using
@code{mysql_use_result()} rather than @code{mysql_store_result()} to
retrieve the result set.

Using @command{mysql} is very easy. Invoke it from the prompt of your command
interpreter as follows:

@example
shell> mysql @var{db_name}
@end example

Or:

@example
shell> mysql --user=@var{user_name} --password=@var{your_password} @var{db_name}
@end example

Then type an SQL statement, end it with @samp{;}, @code{\g}, or @code{\G}
and press Enter.

You can run a script simply like this:

@example
shell> mysql @var{db_name} < @var{script.sql} > @var{output.tab}
@end example

@cindex @command{mysql} command-line options
@cindex command-line options, @command{mysql}
@cindex options, command-line, @command{mysql}
@cindex startup parameters, @command{mysql}
@command{mysql} supports the following options:

@table @code

@item --help, -?
@cindex @code{help}, @command{mysql} option
Display a help message and exit.

@item --batch, -B
@cindex @code{batch}, @command{mysql} option
Print results using tab as the column separator, with each row on a new line.
With this option, @command{mysql} doesn't use the history file.

@item --character-sets-dir=@var{path}
@cindex @code{character-sets-dir}, @command{mysql} option
The directory where character sets are installed.  @xref{Character sets}.

@item --compress, -C
@cindex @code{compress}, @command{mysql} option
Compress all information sent between the client and the server if both
support compression.

@item --database=@var{db_name}, -D @var{db_name}
@cindex @code{database}, @command{mysql} option
The database to use. This is useful mainly in an option file.

@item --debug[=@var{debug_options}], -# [@var{debug_options}]
@cindex @code{debug}, @command{mysql} option
Write a debugging log. The @var{debug_options} string often is
@code{'d:t:o,@var{file_name}'}.
The default is @code{'d:t:o,/tmp/mysql.trace'}.

@item --debug-info, -T
@cindex @code{debug-info}, @command{mysql} option
Print some debugging information when the program exits.

@item --default-character-set=@var{charset}
@cindex @code{default-character-set}, @command{mysql} option
Use @var{charset} as the default character set.  @xref{Character sets}.

@item --execute=@var{statement}, -e @var{statement}
@cindex @code{execute}, @command{mysql} option
Execute the statement and quit. The default output format is like that produced with
@code{--batch}.

@item --force, -f
@cindex @code{force}, @command{mysql} option
Continue even if an SQL error occurs.

@item --host=@var{host_name}, -h @var{host_name}
@cindex @code{host}, @command{mysql} option
Connect to the MySQL server on the given host.

@item --html, -H
@cindex @code{html}, @command{mysql} option
Produce HTML output.

@item --ignore-space, -i
@cindex @code{ignore-space}, @command{mysql} option
Ignore spaces after function names.
The effect of this is described in the discussion for @code{IGNORE_SPACE} in
@ref{Server SQL mode}.

@item --local-infile[=@{0|1@}]
@cindex @code{local-infile}, @command{mysql} option
Enable or disable @code{LOCAL} capability for @code{LOAD DATA INFILE}.
With no value, the option enables @code{LOCAL}. It may be given as
@code{--local-infile=0} or @code{--local-infile=1} to explicitly disable
or enable @code{LOCAL}. Enabling @code{LOCAL} has no effect if the server
does not also support it.

@item --named-commands, -G
@cindex @code{named-commands}, @command{mysql} option
Named commands are @emph{enabled}.  Long format commands are allowed as
well as shortened \* commands. For example, @code{quit} and @code{\q} both
are recognized.

@item --no-auto-rehash, -A
@cindex @code{no-auto-rehash}, @command{mysql} option
No automatic rehashing.  This option causes @command{mysql} to start faster,
but you must issue the @code{rehash} command if you want to use table and
column name completion.

@item --no-beep, -b
@cindex @code{no-beep}, @command{mysql} option
Do not beep when errors occur.

@item --no-named-commands, -g
@cindex @code{no-named-commands}, @command{mysql} option
Named commands are disabled. Use the @code{\*} form only, or use
named commands only at the beginning of a line ending with a semicolon
(@samp{;}). As of MySQL 3.23.22, @command{mysql} starts with this option
@emph{enabled} by default!  However, even with this option, long-format
commands still work from the first line.

@item --no-pager
@cindex @code{no-pager}, @command{mysql} option
Do not use a pager for displaying query output.
Output paging is discussed further in
@ref{mysql Commands,  , @command{mysql} Commands}.

@item --no-tee
@cindex @code{no-tee}, @command{mysql} option
Do not copy output to a file.
Tee files are discussed further in
@ref{mysql Commands,  , @command{mysql} Commands}.

@item --one-database, -O
@cindex @code{one-database}, @command{mysql} option
Ignore statements except those for the default database named on the
command line.  This is useful for skipping updates to other databases in
the binary log.

@item --pager[=@var{command}]
@cindex @code{pager}, @command{mysql} option
Use the given command for paging query output.  If the command is
omitted, the default pager is the value of your @code{PAGER} environment
variable. Valid pagers are @command{less}, @command{more}, @command{cat [>
filename]}, and so forth.  This option works only on Unix.  It does not
work in batch mode.
Output paging is discussed further in
@ref{mysql Commands,  , @command{mysql} Commands}.

@item --password[=@var{password}], -p[@var{password}]
@cindex @code{password}, @command{mysql} option
The password to use when connecting to the server.  If you use the
short option form (@code{-p}), you @emph{cannot} have a space between the
option and the password.  If you omit the @var{password} value following the
@code{--password} or @code{-p} option on the command line, you will be
prompted for one.

@item --port=@var{port_num}, -P @var{port_num}
@cindex @code{port}, @command{mysql} option
The TCP/IP port number to use for the connection.

@item --prompt=@var{format_str}
@cindex @code{prompt}, @command{mysql} option
Set the prompt to the specified format. The default is @code{mysql>}.
The special sequences that the prompt can contain are described in
@ref{mysql Commands,  , @command{mysql} Commands}.

@item --protocol=@{TCP | SOCKET | PIPE | MEMORY@}
@cindex @code{protocol}, @command{mysql} option
The connection protocol to use.  New in MySQL 4.1.

@item --quick, -q
@cindex @code{quick}, @command{mysql} option
Don't cache each query result, print each row as it is received. This may slow
down the server if the output is suspended.  With this option, @command{mysql}
doesn't use the history file.

@item --raw, -r
@cindex @code{raw}, @command{mysql} option
Write column values without escape conversion. Often used with the
@code{--batch} option.

@item --reconnect
@cindex @code{reconnect}, @command{mysql} option
If the connection to the server is lost, automatically try to reconnect. A
single reconnect attempt is made each time the connection is lost.  To
suppress reconnection behavior, use @code{--skip-reconnect}.
New in MySQL 4.1.0.

@item --safe-updates, --i-am-a-dummy, -U
@cindex @code{safe-updates}, @command{mysql} option
Allow only @code{UPDATE} and @code{DELETE} statements that specify rows
to affect using key values.  If you have this option in an option file,
you can override it by using @code{--safe-updates} on the command line.
See @ref{mysql Tips,  , @command{mysql} Tips} for more information about
this option.

@item --sigint-ignore
Ignore @code{SIGINT} signals (typically the result of typing Control-C).
This option was added in MySQL 4.1.6.

@item --silent, -s
@cindex @code{silent}, @command{mysql} option
Silent mode. Produce less output.  This option can be given multiple times
to produce less and less output.

@item --skip-column-names, -N
@cindex @code{skip-column-names}, @command{mysql} option
Don't write column names in results.

@item --skip-line-numbers, -L
@cindex @code{skip-line-numbers}, @command{mysql} option
Don't write line numbers for errors. Useful when you want to compare result
files that include error messages.

@item --socket=@var{path}, -S @var{path}
@cindex @code{socket}, @command{mysql} option
The socket file to use for the connection.

@item --table, -t
@cindex @code{table}, @command{mysql} option
Display
output in table format. This is the default for interactive use, but can be
used to produce table output in batch mode.

@item --tee=@var{file_name}
@cindex @code{tee}, @command{mysql} option
Append a copy of output to the given file. This option does not
work in batch mode.  Tee files are discussed further in
@ref{mysql Commands,  , @command{mysql} Commands}.

@item --unbuffered, -n
@cindex @code{unbuffered}, @command{mysql} option
Flush the buffer after each query.

@item --user=@var{user_name}, -u @var{user_name}
@cindex @code{user}, @command{mysql} option
The MySQL username to use when connecting to the server.

@item --verbose, -v
@cindex @code{verbose}, @command{mysql} option
Verbose mode. Produce more output. This option can be given multiple times
to produce more and more output.
(For example, @code{-v -v -v} produces the table output format even in batch
mode.)

@item --version, -V
@cindex @code{version}, @command{mysql} option
Display version information and exit.

@item --vertical, -E
@cindex @code{vertical}, @command{mysql} option
Print the rows of query output vertically. Without this option, you can
specify vertical output for individual statements by terminating them
with @code{\G}.

@item --wait, -w
@cindex @code{wait}, @command{mysql} option
If the connection cannot be established, wait and retry instead of aborting.

@item --xml, -X
@cindex @code{xml}, @command{mysql} option
Produce XML output.

@end table

You can also set the following variables by using @code{--@var{var_name}=@var{value}}
options:

@cindex timeout, @code{connect_timeout} variable
@cindex @code{connect_timeout} variable
@cindex @code{max_allowed_packet} variable
@cindex @code{max_join_size} variable
@cindex @code{net_buffer_length} variable
@cindex @code{select_limit} variable

@table @code

@item connect_timeout
The number of seconds before connection timeout.
(Default value is 0.)

@item max_allowed_packet
The maximum packet length to send to or receive from the server.
(Default value is 16MB.)

@item max_join_size
The automatic limit for rows in a join when using @code{--safe-updates}.
(Default value is 1,000,000.)

@item net_buffer_length
The buffer size for TCP/IP and socket communication.
(Default value is 16KB.)

@item select_limit
The automatic limit for @code{SELECT} statements when using
@code{--safe-updates}.
(Default value is 1,000.)

@end table

It is also possible to set variables by using
@code{--set-variable=@var{var_name}=@var{value}} or @code{-O @var{var_name}=@var{value}}
syntax. However, this syntax is deprecated as of MySQL 4.0.

@tindex @code{MYSQL_HISTFILE} environment variable
@tindex environment variable, @code{MYSQL_HISTFILE}
@tindex @code{HOME} environment variable
@tindex environment variable, @code{HOME}
@cindex mysql history file
@cindex command-line history, mysql
@tindex .mysql_history file

On Unix, the @command{mysql} client writes a record of executed statements to a
history file.  By default, the history file is named @file{.mysql_history}
and is created in your home directory.  To specify a different file,
set the value of the @code{MYSQL_HISTFILE} environment variable.

If you do not want to maintain a history file, first remove
@file{.mysql_history} if it exists, and then use either of the following
techniques:

@itemize @bullet

@item
Set the @code{MYSQL_HISTFILE} variable to @file{/dev/null}. To cause this
setting to take effect each time you log in, put the setting in one of
your shell's startup files.

@item
Create @file{.mysql_history} as a symbolic link to @file{/dev/null}:

@example
shell> ln -s /dev/null $HOME/.mysql_history
@end example

You need do this only once.

@end itemize


@node mysql Commands, Batch Commands, mysql, mysql
@subsection @command{mysql} Commands

@c TODO: describe 4.1 help system

@command{mysql} sends SQL statements that you issue to the server to be
executed.  There is also a set of commands that @command{mysql} itself
interprets.  For a list of these commands, type @code{help} or @code{\h} at
the @code{mysql>} prompt:

@cindex mysql commands, list of
@example
mysql> help

MySQL commands:
?         (\h)    Synonym for `help'.
clear     (\c)    Clear command.
connect   (\r)    Reconnect to the server.
                  Optional arguments are db and host.
delimiter (\d)    Set query delimiter.
edit      (\e)    Edit command with $EDITOR.
ego       (\G)    Send command to mysql server,
                  display result vertically.
exit      (\q)    Exit mysql. Same as quit.
go        (\g)    Send command to mysql server.
help      (\h)    Display this help.
nopager   (\n)    Disable pager, print to stdout.
notee     (\t)    Don't write into outfile.
pager     (\P)    Set PAGER [to_pager].
                  Print the query results via PAGER.
print     (\p)    Print current command.
prompt    (\R)    Change your mysql prompt.
quit      (\q)    Quit mysql.
rehash    (\#)    Rebuild completion hash.
source    (\.)    Execute an SQL script file.
                  Takes a file name as an argument.
status    (\s)    Get status information from the server.
system    (\!)    Execute a system shell command.
tee       (\T)    Set outfile [to_outfile].
                  Append everything into given outfile.
use       (\u)    Use another database.
                  Takes database name as argument.
@end example

Each command has both a long and short form.
The long form is not case sensitive; the short form is.
The long form can be followed by an optional semicolon terminator, but the
short form should not.

The @code{edit}, @code{nopager}, @code{pager}, and @code{system} commands
work only in Unix.

@cindex mysql status command
The @code{status} command provides some information about the
connection and the server you are using. If you are running in
@code{--safe-updates} mode, @code{status} also prints the values for
the @command{mysql} variables that affect your queries.

To log queries and their output, use the @code{tee} command.  All the data
displayed on the screen will be appended into a given file. This can be very
useful for debugging purposes also.  You can enable this feature on the
command line with the @code{--tee} option, or interactively with the @code{tee}
command.  The @code{tee} file can be disabled interactively with the
@code{notee} command. Executing @code{tee} again re-enables logging.
Without a parameter, the previous file will be used. Note that @code{tee}
flushes query results to the file after each statement, just before @command{mysql}
prints its next prompt.

Browsing or searching query results in interactive mode by using Unix
programs such as @command{less}, @command{more}, or any other similar program is
now possible with the @code{--pager} option. If you specify no value for the
option, @command{mysql} checks the value of the @code{PAGER} environment
variable and sets the pager to that.  Output paging can be enabled
interactively with the @code{pager} command and disabled with
@code{nopager}.  The command takes an optional argument; if given, the
paging program is set to that. With no argument, the pager is set to the
pager that was set on the command line, or @code{stdout} if no pager was
specified.

Output paging works only in Unix because it uses the @code{popen()}
function, which doesn't exist on Windows. For Windows, the @code{tee}
option can be used instead to save query output, although this is not as
convenient as @code{pager} for browsing output in some situations.

A few tips about the @code{pager} command:

@itemize @bullet
@item
You can use it to write to a file and the results will go only to the file:

@example
mysql> pager cat > /tmp/log.txt
@end example

You can also pass any options for the program that you want to use as your
pager:

@example
mysql> pager less -n -i -S
@end example

@item
In the preceding example, note the @code{-S} option. You may find it very
useful for browsing wide query results.  Sometimes a very wide result set is
difficult to read on the screen.  The @code{-S} option to @command{less} can
make the result set much more readable because you can scroll it
horizontally using the left-arrow and right-arrow keys.  You can also use
@code{-S} interactively within @command{less} to switch the horizontal-browse
mode on and off.  For more information, read the @command{less} manual page:

@example
shell> man less
@end example

@item
You can specify very complex pager commands for handling query output:

@example
mysql> pager cat | tee /dr1/tmp/res.txt \
          | tee /dr2/tmp/res2.txt | less -n -i -S
@end example

In this example, the command would send query results to two files in two
different directories on two different filesystems mounted on @file{/dr1}
and @file{/dr2}, yet still display the results onscreen via @command{less}.

@end itemize

You can also combine the @code{tee} and @code{pager} functions. Have a
@command{tee} file enabled and @code{pager} set to @command{less}, and you will be
able to browse the results using the @command{less} program and still have
everything appended into a file the same time. The difference between the
Unix @command{tee} used with the @code{pager} command and the @command{mysql}
built-in @code{tee} command is that the built-in @code{tee} works even if
you don't have the Unix @command{tee} available. The built-in @code{tee} also
logs everything that is printed on the screen, whereas the Unix @command{tee}
used with @code{pager} doesn't log quite that much. Additionally, @code{tee}
file logging can be turned on and off interactively from within
@command{mysql}. This is useful when you want to log some queries to a file,
but not others.

@cindex mysql prompt command
From MySQL 4.0.2 on, the default @code{mysql>} prompt can be reconfigured.
The string for defining the prompt can contain the following special
sequences:

@c FIX these columnfractions have NOT been measured!

@multitable @columnfractions .15 .75
@item @strong{Option} @tab @strong{Description}
@item @code{\v}   @tab  The server version
@item @code{\d}   @tab  The current database
@item @code{\h}   @tab  The server host
@item @code{\p}   @tab  The current TCP/IP host
@item @code{\u}   @tab  Your username
@item @code{\U}   @tab  Your full @code{@var{user_name}@@@var{host_name}} account name
@item @code{\\}   @tab  A literal @samp{\} backslash character
@item @code{\n}   @tab  A newline character
@item @code{\t}   @tab  A tab character
@item @code{\ }   @tab  A space (a space follows the backslash)
@item @code{\_}   @tab  A space
@item @code{\R}   @tab  The current time, in 24-hour military time (0-23)
@item @code{\r}   @tab  The current time, standard 12-hour time (1-12)
@item @code{\m}   @tab  Minutes of the current time
@item @code{\y}   @tab  The current year, two digits
@item @code{\Y}   @tab  The current year, four digits
@item @code{\D}   @tab  The full current date
@item @code{\s}   @tab  Seconds of the current time
@item @code{\w}   @tab  The current day of the week in three-letter format (Mon, Tue, ...)
@item @code{\P}   @tab  am/pm
@item @code{\o}   @tab  The current month in numeric format
@item @code{\O}   @tab  The current month in three-letter format (Jan, Feb, ...)
@item @code{\c}   @tab  A counter that increments for each statement you issue
@item @code{\S}   @tab  Semicolon
@item @code{\'}   @tab  Single quote
@item @code{\"}   @tab  Double quote
@end multitable

@samp{\} followed by any other letter just becomes that letter.

If you specify the @code{prompt} command with no argument, @command{mysql} resets
the prompt to the default of @code{mysql>}.

You can set the prompt in several ways:

@itemize @bullet
@item Use an environment variable

You can set the @code{MYSQL_PS1} environment variable to a prompt string.  For
example:

@example
shell> export MYSQL_PS1="(\u@@\h) [\d]> "
@end example

@item Use an option file

You can set the @code{prompt} option in the @code{[mysql]} group of any MySQL
option file, such as @file{/etc/my.cnf} or the @file{.my.cnf} file in
your home directory.
For example:

@example
[mysql]
prompt=(\\u@@\\h) [\\d]>\\_
@end example

In this example, note that the backslashes are doubled.
If you set the prompt using the @code{prompt} option in an option
file, it is advisable to double the backslashes when using the special
prompt options.  There is
some overlap in the set of allowable prompt options and the set of special
escape sequences that are recognized in option files.
(These sequences are listed in @ref{Option files}.)
The overlap may cause you problems if you use single backslashes.
For example, @code{\s} will be interpreted as a space rather than as the
current seconds value. The following example shows how to define a prompt
within an option file to
include the current time in @code{HH:MM:SS>} format:

@example
[mysql]
prompt="\\r:\\m:\\s> "
@end example

@item Use a command-line option

You can set the @code{--prompt} option on the command line to @command{mysql}.
For example:

@example
shell> mysql --prompt="(\u@@\h) [\d]> "
(user@@host) [database]> 
@end example

@item Interactively

You can change your prompt interactively by using the @code{prompt} (or
@code{\R}) command.  For example:

@example
mysql> prompt (\u@@\h) [\d]>\_
PROMPT set to '(\u@@\h) [\d]>\_'
(@var{user}@@@var{host}) [@var{database}]> 
(@var{user}@@@var{host}) [@var{database}]> prompt
Returning to default PROMPT of mysql> 
mysql> 
@end example

@end itemize


@node Batch Commands, mysql Tips, mysql Commands, mysql
@subsection Executing SQL Statements from a Text File

The @command{mysql} client typically is used interactively, like this:

@example
shell> mysql @var{db_name}
@end example

However, it's also possible to put your SQL statements in a file and then
tell @command{mysql} to read its input from that file.  To do so, create a text
file @file{text_file} that contains the statements you wish to execute.
Then invoke @command{mysql} as shown here:

@example
shell> mysql @var{db_name} < @var{text_file}
@end example

You can also start your text file with a @code{USE @var{db_name}} statement.  In
this case, it is unnecessary to specify the database name on the command
line:

@example
shell> mysql < text_file
@end example

If you are already running @command{mysql}, you can execute an SQL
script file using the @code{source} or @code{\.} command:

@example
mysql> source @var{filename}
mysql> \. @var{filename}
@end example

Sometimes you may want your script to display progress information to the user;
for this you can insert some lines like

@example
SELECT '<info_to_display>' AS ' ';
@end example

which will output <info_to_display>.

For more information about batch mode, see @ref{Batch mode}.


@node mysql Tips,  , Batch Commands, mysql
@subsection @command{mysql} Tips

This section describes some techniques that can help you use @command{mysql} more
effectively.

@menu
* Vertical query results::      Displaying Query Results Vertically
* safe-updates::                Using the @code{--safe-updates} Option
* mysql reconnect::             Disabling @command{mysql} Auto-Reconnect
@end menu


@node Vertical query results, safe-updates, mysql Tips, mysql Tips
@subsubsection Displaying Query Results Vertically

Some query results are much more readable when displayed vertically, instead
of in the usual horizontal table format. Queries can be displayed vertically 
by terminating the query with \G instead of a semicolon.
For example, longer text values that
include newlines often are much easier to read with vertical output:

@example
mysql> SELECT * FROM mails WHERE LENGTH(txt) < 300 LIMIT 300,1\G
*************************** 1. row ***************************
  msg_nro: 3068
     date: 2000-03-01 23:29:50
time_zone: +0200
mail_from: Monty
    reply: monty@@no.spam.com
  mail_to: "Thimble Smith" <tim@@no.spam.com>
      sbj: UTF-8
      txt: >>>>> "Thimble" == Thimble Smith writes:

Thimble> Hi.  I think this is a good idea.  Is anyone familiar
Thimble> with UTF-8 or Unicode? Otherwise, I'll put this on my
Thimble> TODO list and see what happens.

Yes, please do that.

Regards,
Monty
     file: inbox-jani-1
     hash: 190402944
1 row in set (0.09 sec)
@end example


@node safe-updates, mysql reconnect, Vertical query results, mysql Tips
@subsubsection Using the @code{--safe-updates} Option

@cindex @code{safe-updates} option

For beginners, a useful startup option is @code{--safe-updates} (or
@code{--i-am-a-dummy}, which has the same effect).  This option was
introduced in MySQL 3.23.11.  It is helpful for cases when you might
have issued a @code{DELETE FROM @var{tbl_name}} statement but forgotten the
@code{WHERE} clause. Normally, such a statement will delete all rows from the
table.  With @code{--safe-updates}, you can delete rows only by specifying
the key values that identify them. This helps prevent accidents.

When you use the @code{--safe-updates} option, @command{mysql} issues the
following statement when it connects to the MySQL server:

@example
SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=1000, SQL_MAX_JOIN_SIZE=1000000;
@end example

@xref{SET OPTION,  , @code{SET}}.

The @code{SET} statement has the following effects:

@itemize @bullet
@item
You are not allowed to execute an @code{UPDATE} or @code{DELETE} statement
unless you specify a key constraint in the @code{WHERE} clause or provide a
@code{LIMIT} clause (or both).
For example:

@example
UPDATE @var{tbl_name} SET @var{not_key_column}=# WHERE @var{key_column}=#;

UPDATE @var{tbl_name} SET @var{not_key_column}=# LIMIT 1;
@end example

@item
All large @code{SELECT} results are automatically limited to 1,000 rows
unless the statement includes a @code{LIMIT} clause.

@item
Multiple-table @code{SELECT} statements that will probably need to examine
more than 1,000,000 row combinations are aborted.

@end itemize

To specify limits other than 1,000 and 1,000,000, you can override the
defaults by using @code{--select_limit} and @code{--max_join_size} options:

@example
shell> mysql --safe-updates --select_limit=500 --max_join_size=10000
@end example


@node mysql reconnect,  , safe-updates, mysql Tips
@subsubsection Disabling @command{mysql} Auto-Reconnect

If the @command{mysql} client loses its connection to the server while sending
a query, it will immediately and automatically try to reconnect once to the
server and send the query again.  However, even if @command{mysql} succeeds in
reconnecting, your first connection has ended and all your previous session
objects and settings are lost: temporary tables, the autocommit mode, and
user and session variables.  This behavior may be dangerous for you, as in
the following example where the server was shut down and restarted without
you knowing it:

@example
mysql> SET @@a=1;
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO t VALUES(@@a);
ERROR 2006: MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    1
Current database: test

Query OK, 1 row affected (1.30 sec)

mysql> SELECT * FROM t;
+------+
| a    |
+------+
| NULL |
+------+
1 row in set (0.05 sec)
@end example

The @code{@@a} user variable has been lost with the connection, and after
the reconnection it is undefined. If it is important to have @command{mysql}
terminate with an error if the connection has been lost, you can start the
@command{mysql} client with the @code{--skip-reconnect} option.

@c TODO: Add mysqlaccess section here


@node mysqladmin, mysqlbinlog, mysql, Client-Side Scripts
@section @command{mysqladmin}, Administering a MySQL Server

@cindex administration, server
@cindex server administration
@cindex @command{mysqladmin}

@command{mysqladmin} is a client for performing administrative operations.
You can use it to check the server's configuration and current status, create
and drop databases, and more.

Invoke @command{mysqladmin} like this:

@example
shell> mysqladmin [@var{options}] @var{command} [@var{command-option}] @var{command} ...
@end example

@command{mysqladmin} supports the following commands:

@table @code
@item create @var{db_name}
Create a new database named @var{db_name}.

@item drop @var{db_name}
Delete the database named @var{db_name} and all its tables.

@item extended-status
Display the server status variables and their values.

@item flush-hosts
Flush all information in the host cache.

@item flush-logs
Flush all logs.

@item flush-privileges
Reload the grant tables (same as @code{reload}).

@item flush-status
Clear status variables.

@item flush-tables
Flush all tables.

@item flush-threads
Flush the thread cache.
(Added in MySQL 3.23.16.)

@item kill id,id,...
Kill server threads.

@item password @var{new-password}
Set a new password. This changes the password to @code{new-password}
for the account that you use with @command{mysqladmin} for connecting to the
server.

If @var{new-password} contains spaces or other characters that are special
to your command interpreter, you will need to enclose it within quotes.
On Windows, be sure to use double quotes rather than single quotes;
single quotes will be not be stripped from the password, they will be
interpreted as part of the password.  For example:

shell> mysqladmin password "my new password"

@item ping
Check whether the server is alive.
The return status from @command{mysqladmin} is 0 if the server is running,
1 if it is not. Beginning with MySQL 4.0.22, the status is 0 even in case
of an error such as @code{Access denied}, because that means the server is
running but disallowed the connection, which is different from the server
not running.

@item processlist
Show a list of active server threads. This is like the output of the
@code{SHOW PROCESSLIST} statement.
If the @code{--verbose} option is given, the output is like that of
@code{SHOW FULL PROCESSLIST}.

@item reload
Reload the grant tables.

@item refresh
Flush all tables and close and open log files.

@item shutdown
Stop the server.

@item start-slave
Start replication on a slave server.
(Added in MySQL 3.23.16.)

@item status
Display a short server status message.

@item stop-slave
Stop replication on a slave server.
(Added in MySQL 3.23.16.)

@item variables
Display the server system variables and their values.

@item version
Display version information from the server.
@end table

All commands can be shortened to any unique prefix.  For example:

@example
shell> mysqladmin proc stat
+----+-------+-----------+----+-------------+------+-------+------+
| Id | User  | Host      | db | Command     | Time | State | Info |
+----+-------+-----------+----+-------------+------+-------+------+
| 6  | monty | localhost |    | Processlist | 0    |       |      |
+----+-------+-----------+----+-------------+------+-------+------+
Uptime: 10077  Threads: 1  Questions: 9  Slow queries: 0
Opens: 6 Flush tables: 1  Open tables: 2
Memory in use: 1092K  Max memory used: 1116K
@end example

@cindex status command, results
The @command{mysqladmin status} command result displays the following values:

@table @code

@item Uptime
@cindex uptime

The number of seconds the MySQL server has been running.

@item Threads
@cindex threads

The number of active threads (clients).

@item Questions
@cindex questions

The number of questions (queries) from clients since the server was started.

@item Slow queries
@cindex slow queries

The number of queries that have taken more than @code{long_query_time}
seconds.  @xref{Slow query log}.

@item Opens
@cindex opens

The number of tables the server has opened.

@item Flush tables
@cindex flush tables
@cindex tables, flush

The number of @code{flush ...}, @code{refresh}, and @code{reload} commands the
server has executed.

@item Open tables
@cindex open tables

The number of tables that currently are open.

@item Memory in use
@cindex memory use

The amount of
memory allocated directly by @command{mysqld} code.
This value is displayed only when MySQL has been compiled with
@code{--with-debug=full}.

@item Maximum memory used
@cindex maximum memory used

The maximum amount of memory allocated directly by @command{mysqld} code.
This value is displayed only when MySQL has been compiled with
@code{--with-debug=full}.

@end table

If you execute @command{mysqladmin shutdown} when connecting to a local server
using a Unix socket file, @command{mysqladmin} waits until the server's process
ID file has been removed, to ensure that the server has stopped properly.

@cindex @command{mysqladmin} command-line options
@cindex command-line options, @command{mysqladmin}
@cindex options, command-line, @command{mysqladmin}
@cindex startup parameters, @command{mysqladmin}

@command{mysqladmin} supports the following options:

@table @code

@item --help, -?
Display a help message and exit.

@item --character-sets-dir=@var{path}
The directory where character sets are installed.  @xref{Character sets}.

@item --compress, -C
Compress all information sent between the client and the server if both
support compression.

@item --count=@var{#}, -c @var{#}
The number of iterations to make. This works only with @code{--sleep}
(@code{-i}).

@item --debug[=@var{debug_options}], -# [@var{debug_options}]
Write a debugging log. The @var{debug_options} string often is
@code{'d:t:o,@var{file_name}'}.
The default is @code{'d:t:o,/tmp/mysqladmin.trace'}.

@item --force, -f
Don't ask for confirmation for the @code{drop database} command.
With multiple commands, continue even if an error occurs.

@item --host=@var{host_name}, -h @var{host_name}
Connect to the MySQL server on the given host.

@item --password[=@var{password}], -p[@var{password}]
The password to use when connecting to the server.  If you use the
short option form (@code{-p}), you @emph{cannot} have a space between the
option and the password.  If you omit the @var{password} value following the
@code{--password} or @code{-p} option on the command line, you will be
prompted for one.

@item --port=@var{port_num}, -P @var{port_num}
The TCP/IP port number to use for the connection.

@item --protocol=@{TCP | SOCKET | PIPE | MEMORY@}
The connection protocol to use.  New in MySQL 4.1.

@item --relative, -r
Show the difference between the current and previous values when used with
@code{-i}. Currently, this option works only with the @code{extended-status}
command.

@item --silent, -s
Exit silently if a connection to the server cannot be established.

@item --sleep=@var{delay}, -i @var{delay}
Execute commands again and again, sleeping for @var{delay} seconds in
between.

@item --socket=@var{path}, -S @var{path}
The socket file to use for the connection.

@item --user=@var{user_name}, -u @var{user_name}
The MySQL username to use when connecting to the server.

@item --verbose, -v
Verbose mode.  Print out more information on what the program does.

@item --version, -V
Display version information and exit.

@item --vertical, -E
Print output vertically. This is similar to @code{--relative}, but
prints output vertically.

@item --wait[=@var{#}], -w[@var{#}]
If the connection cannot be established, wait and retry instead of aborting.
If an option value is given, it indicates the number of times to retry.
The default is one time.

@end table

You can also set the following variables by using @code{--@var{var_name}=@var{value}}
options:

@cindex timeout, @code{connect_timeout} variable
@cindex @code{connect_timeout} variable
@cindex timeout, @code{shutdown_timeout} variable
@cindex @code{shutdown_timeout} variable

@table @code

@item connect_timeout
The number of seconds before connection timeout.
(Default value is 0.)

@item shutdown_timeout
The number of seconds to wait for shutdown.
(Default value is 0.)

@end table

It is also possible to set variables by using
@code{--set-variable=@var{var_name}=@var{value}} or @code{-O @var{var_name}=@var{value}}
syntax. However, this syntax is deprecated as of MySQL 4.0.


@node mysqlbinlog, mysqlcc, mysqladmin, Client-Side Scripts
@section The @command{mysqlbinlog} Binary Log Utility

@cindex @command{mysqlbinlog}

The binary log files that the server generates are written in binary format.
To examine these files in text format, use the @command{mysqlbinlog} utility.
It is available as of MySQL 3.23.14.

Invoke @command{mysqlbinlog} like this:

@example
shell> mysqlbinlog [@var{options}] @var{log-file} ...
@end example

For example, to display the contents of the binary log @file{binlog.000003},
use this command:

@example
shell> mysqlbinlog binlog.0000003
@end example

The output includes all statements contained in @file{binlog.000003},
together with other information such as the time each statement took, the
thread ID of the client that issued it, the timestamp when it was issued,
and so forth.

Normally, you use @command{mysqlbinlog} to read binary log files directly and
apply them to the local MySQL server. It is also possible to read binary
logs from a remote server by using the @code{--read-from-remote-server}
option.

When you read remote binary logs, the connection parameter options can be
given to indicate how to connect to the server, but they are ignored unless
you also specify the @code{--read-from-remote-server} option. These options
are @code{--host}, @code{--password}, @code{--port}, @code{--protocol},
@code{--socket}, and @code{--user}.

You can also use @command{mysqlbinlog} to read relay log files written by a
slave server in a replication setup. Relay logs have the same format as
binary log files.

The binary log is discussed further in @ref{Binary log}.

@command{mysqlbinlog} supports the following options:

@table @code

@item --help, -?
Display a help message and exit.

@item --database=@var{db_name}, -d @var{db_name}
List entries for just this database (local log only).

@item --force-read, -f
With this option, if @command{mysqlbinlog} reads a binary log event that
it does not recognize, it prints a warning, ignores the event, and continues.
Without this option, @command{mysqlbinlog} stops if it reads such an event.

@item --host=@var{host_name}, -h @var{host_name}
Get the binary log from the MySQL server on the given host.

@item --local-load=@var{path}, -l @var{path}
Prepare local temporary files for @code{LOAD DATA INFILE} in the specified
directory.

@item --offset=@var{N}, -o @var{N}
Skip the first @var{N} entries.

@item --password[=@var{password}], -p[@var{password}]
The password to use when connecting to the server.  If you use the
short option form (@code{-p}), you @emph{cannot} have a space between the
option and the password.  If you omit the @var{password} value following the
@code{--password} or @code{-p} option on the command line, you will be
prompted for one.

@item --port=@var{port_num}, -P @var{port_num}
The TCP/IP port number to use for connecting to a remote server.

@item --position=@var{N}, -j @var{N}
Deprecated, use @code{--start-position} instead (starting from MySQL 4.1.4).

@item --protocol=@{TCP | SOCKET | PIPE | MEMORY@}
The connection protocol to use.  New in MySQL 4.1.

@item --read-from-remote-server, -R
Read the binary log from a MySQL server.
Any connection parameter options are ignored unless this option is given as
well. These options are @code{--host}, @code{--password}, @code{--port},
@code{--protocol},
@code{--socket}, and @code{--user}.

@item --result-file=@var{name}, -r @var{name}
Direct output to the given file.

@item --short-form, -s
Display only the statements contained in the log, without any extra
information.

@item --socket=@var{path}, -S @var{path}
The socket file to use for the connection.

@item --start-datetime=@var{datetime}
Start reading the binary log at the first event having a datetime equal or
posterior to the @code{datetime} argument. Available as of MySQL 4.1.4.

@item --stop-datetime=@var{datetime}
Stop reading the binary log at the first event having a datetime equal or
posterior to the @code{datetime} argument.  Available as of MySQL 4.1.4. Useful
for point-in-time recovery.

@item --start-position=@var{N}
Start reading the binary log at the first event having a position equal to
the @code{N} argument. Available as of MySQL 4.1.4 (previously named
@code{--position}).

@item --stop-position=@var{N}
Stop reading the binary log at the first event having a position equal or
greater than the @code{N} argument. Available as of MySQL 4.1.4.

@item --to-last-log, -t
Do not stop at the end of the requested binary log of the MySQL server, but
rather continue printing until the end of the last binary log. If you send
the output to the same MySQL server, this may lead to an endless loop.  This
option requires @code{--read-from-remote-server}. Available as of MySQL 4.1.2.

@item --disable-log-bin, -D
Disable binary logging. This is useful for avoiding an endless loop if you
use the @code{--to-last-log} option and are sending the output to the same
MySQL server.  This option also is useful when restoring after a crash
to avoid duplication of the statements you already have logged. @strong{Note}:
This option requires that you have the @code{SUPER} privilege. Available
as of MySQL 4.1.8.

@item --user=@var{user_name}, -u @var{user_name}
The MySQL username to use when connecting to a remote server.

@item --version, -V
Display version information and exit.

@end table

You can also set the following variable by using @code{--@var{var_name}=@var{value}}
options:

@cindex @code{open_files_limit} variable

@table @code

@item open_files_limit
Specify the number of open file descriptors to reserve.

@end table

You can pipe the output of @command{mysqlbinlog} into a @command{mysql} client to
execute the statements contained in the binary log. This is used to recover
from a crash when you have an old backup (@pxref{Backup}):

@example
shell> mysqlbinlog @var{hostname}-bin.000001 | mysql
@end example

Or:

@example
shell> mysqlbinlog @var{hostname}-bin.[0-9]* | mysql
@end example

You can also redirect the output of @command{mysqlbinlog} to a text file
instead, if you need to modify the statement log first (for example, to
remove statements that you don't want to execute for some reason). After
editing the file, execute the statements that it contains by using it as
input to the @command{mysql} program.

@command{mysqlbinlog} has the @code{--position} option, which prints only
those statements with an offset in the binary log greater than or equal to
a given position (the given position must match the start of one event). It
also has options to stop or start when it sees an event of a given date and
time. This enables you to perform point-in-time recovery using the
@code{--stop-datetime} option (to be able to say, for example, "roll forward
my databases to how they were today at 10:30 AM").

If you have more than one binary log to execute on the MySQL server,
the safe method is to process them all using a single connection to the
server.  Here is an example that demonstrates what may be @emph{unsafe}:

@example
shell> mysqlbinlog @var{hostname}-bin.000001 | mysql # DANGER!!
shell> mysqlbinlog @var{hostname}-bin.000002 | mysql # DANGER!!
@end example

Processing binary logs this way using different connections to the server
will cause problems if the first log file contains a @code{CREATE TEMPORARY
TABLE} statement and the second log contains a statement that uses the
temporary table. When the first @command{mysql} process terminates, the server
will drop the temporary table. When the second @command{mysql} process attempts
to use the table, the server will report ``unknown table.''

To avoid problems like this, use a single connection to execute the contents
of all binary logs that you want to process.  Here is one way to do that:

@example
shell> mysqlbinlog @var{hostname}-bin.000001 @var{hostname}-bin.000002 | mysql
@end example

Another approach is to do this:

@example
shell> mysqlbinlog @var{hostname}-bin.000001 >  /tmp/statements.sql
shell> mysqlbinlog @var{hostname}-bin.000002 >> /tmp/statements.sql
shell> mysql -e "source /tmp/statements.sql"
@end example

In MySQL 3.23, the binary log did not contain the data to load for
@code{LOAD DATA INFILE} statements. To execute such a statement from a
binary log file, the original data file was needed.  Starting from MySQL
4.0.14, the binary log does contain the data, so @command{mysqlbinlog} can
produce output that reproduces the @code{LOAD DATA INFILE} operation without
the original data file.  @command{mysqlbinlog} copies the data to a temporary
file and writes a @code{LOAD DATA LOCAL INFILE} statement that refers to the
file.  The default location of the directory where these files are written
is system-specific. To specify a directory explicitly, use the
@code{--local-load} option.

Because @command{mysqlbinlog} converts @code{LOAD DATA INFILE} statements to
@code{LOAD DATA LOCAL INFILE} statements (that is, it adds @code{LOCAL}),
both the client and the server that you use to process the statements must be
configured to allow @code{LOCAL} capability.
@xref{LOAD DATA LOCAL,  , @code{LOAD DATA LOCAL}}.

@strong{Warning:} The temporary files created for @code{LOAD DATA LOCAL}
statements are @emph{not} automatically deleted
because they are needed until you actually execute those statements.  You
should delete the temporary files yourself after you no longer need the
statement log.  The files can be found in the temporary file directory and
have names like @file{original_file_name-#-#}.

In the future, we will fix this problem by allowing @command{mysqlbinlog}
to connect directly to a @command{mysqld} server.  Then it will be possible
to safely remove the log files automatically as soon as the @code{LOAD DATA
INFILE} statements have been executed.

Before MySQL 4.1, @command{mysqlbinlog} could not prepare output suitable for
@command{mysql} if the binary log contained interlaced statements originating
from different clients that used temporary tables of the same name. This is
fixed in MySQL 4.1. However, the problem still existed for @code{LOAD DATA
INFILE} statements until it was fixed in MySQL 4.1.8.


@node mysqlcc, Using mysqlcheck, mysqlbinlog, Client-Side Scripts
@section @command{mysqlcc}, the MySQL Control Center

@cindex graphical tool
@cindex GUI tool
@cindex tools, graphical
@cindex tools, GUI
@cindex @command{mysqlcc}

@command{mysqlcc}, the MySQL Control Center, is a platform-independent client that
provides a graphical user interface (GUI) to the MySQL database server.
It supports interactive use, including syntax highlighting and tab completion.
It provides database and table management, and allows server administration.

@command{mysqlcc} is now deprecated and it is recommended that users choose the new
MySQL Administrator and MySQL Query Browser, found at @uref{http://dev.mysql.com/downloads/}.

@c @command{mysqlcc} is not included with MySQL distributions, but can be downloaded
@c separately at @uref{http://dev.mysql.com/downloads/}.
Currently, @command{mysqlcc} runs on Windows and Linux platforms.

Invoke @command{mysqlcc} by double-clicking its icon in a graphical environment.
From the command line, invoke it like this:

@example
shell> mysqlcc [@var{options}]
@end example

@cindex @command{mysqlcc} command-line options
@cindex command-line options, @command{mysqlcc}
@cindex options, command-line, @command{mysqlcc}
@cindex startup parameters, @command{mysqlcc}
@command{mysqlcc} supports the following options:

@table @code

@item --help, -?
@cindex @code{help}, @command{mysqlcc} option
Display a help message and exit.

@item --blocking_queries, -b
@cindex @code{blocking_queries}, @command{mysqlcc} option
Use blocking queries.

@item --compress, -C
@cindex @code{compress}, @command{mysqlcc} option
Compress all information sent between the client and the server if both
support compression.

@item --connection_name=@var{name}, -c @var{name}
@cindex @code{connection_name}, @command{mysqlcc} option
This option is a synonym for @code{--server}.

@item --database=@var{db_name}, -d @var{db_name}
@cindex @code{database}, @command{mysqlcc} option
The database to use. This is useful mainly in an option file.

@item --history_size=@var{#}, -H @var{#}
@cindex @code{history_size}, @command{mysqlcc} option
The history size for the query window.

@item --host=@var{host_name}, -h @var{host_name}
@cindex @code{host}, @command{mysqlcc} option
Connect to the MySQL server on the given host.

@item --local-infile[=@{0|1@}]
@cindex @code{local-infile}, @command{mysqlcc} option
Enable or disable @code{LOCAL} capability for @code{LOAD DATA INFILE}.
With no value, the option enables @code{LOCAL}. It may be given as
@code{--local-infile=0} or @code{--local-infile=1} to explicitly disable
or enable @code{LOCAL}. Enabling @code{LOCAL} has no effect if the server
does not also support it.

@item --password[=@var{password}], -p[@var{password}]
@cindex @code{password}, @command{mysqlcc} option
The password to use when connecting to the server.  If you use the
short option form (@code{-p}), you @emph{cannot} have a space between the
option and the password.  If you omit the @var{password} value following the
@code{--password} or @code{-p} option on the command line, you will be
prompted for one.

@item --plugins_path=@var{name}, -g @var{name}
@cindex @code{plugins_path}, @command{mysqlcc} option
The path to the directory where MySQL Control Center plugins are located.

@item --port=@var{port_num}, -P @var{port_num}
@cindex @code{port}, @command{mysqlcc} option
The TCP/IP port number to use for the connection.

@item --query, -q
@cindex @code{query}, @command{mysqlcc} option
Open a query window on startup.

@item --register, -r
@cindex @code{register}, @command{mysqlcc} option
Open the Register Server dialog on startup.

@item --server=@var{name}, -s @var{name}
@cindex @code{server}, @command{mysqlcc} option
The MySQL Control Center connection name.

@item --socket=@var{path}, -S @var{path}
@cindex @code{socket}, @command{mysqlcc} option
The socket file to use for the connection.

@item --syntax, -y
@cindex @code{syntax}, @command{mysqlcc} option
Enable syntax highlighting and completion.

@item --syntax_file=@var{name}, -Y @var{name}
@cindex @code{syntax_file}, @command{mysqlcc} option
The syntax file for completion.

@item --translations_path=@var{name}, -T @var{name}
@cindex @code{translations_path}, @command{mysqlcc} option
The path to the directory where MySQL Control Center translations are located.

@item --user=@var{user_name}, -u @var{user_name}
@cindex @code{user}, @command{mysqlcc} option
The MySQL username to use when connecting to the server.

@item --version, -V
@cindex @code{version}, @command{mysqlcc} option
Display version information and exit.

@end table

You can also set the following variables by using @code{--@var{var_name}=@var{value}}
options:

@cindex timeout, @code{connect_timeout} variable
@cindex @code{connect_timeout} variable
@cindex @code{max_allowed_packet} variable
@cindex @code{max_join_size} variable
@cindex @code{net_buffer_length} variable
@cindex @code{select_limit} variable

@table @code

@item connect_timeout
The number of seconds before connection timeout.
(Default value is 0.)

@item max_allowed_packet
The maximum packet length to send to or receive from the server.
(Default value is 16MB.)

@item max_join_size
The automatic limit for rows in a join.
(Default value is 1,000,000.)

@item net_buffer_length
The buffer size for TCP/IP and socket communication.
(Default value is 16KB.)

@item select_limit
The automatic limit for @code{SELECT} statements.
(Default value is 1,000.)

@end table

It is also possible to set variables by using
@code{--set-variable=@var{var_name}=@var{value}} or @code{-O @var{var_name}=@var{value}}
syntax. However, this syntax is deprecated as of MySQL 4.0.


@node Using mysqlcheck, mysqldump, mysqlcc, Client-Side Scripts
@section The @command{mysqlcheck} Table Maintenance and Repair Program

@c TODO: This is no longer fully accurate. mysqlcheck can be used for some
@c operations on table types other than MyISAM.

@c TODO: There probably should be more reference to this program from within
@c the table maintenance section.

The @command{mysqlcheck} client checks and repairs @code{MyISAM} tables.  It
can also optimize and analyze tables. @command{mysqlcheck} is available as of
MySQL 3.23.38.

@command{mysqlcheck} is similar in function to @command{myisamchk}, but works
differently.  The main operational difference is that @command{mysqlcheck} must
be used when the @command{mysqld} server is running, whereas @command{myisamchk}
should be used when it is not. The benefit of using @command{mysqlcheck} is
that you do not have to stop the server to check or repair your tables.

@command{mysqlcheck} uses the SQL statements @code{CHECK TABLE}, @code{REPAIR
TABLE}, @code{ANALYZE TABLE}, and @code{OPTIMIZE TABLE} in a convenient way
for the user. It determines which statements to use for the operation you want
to perform, then sends the statements to the server to be executed.

There are three general ways to invoke @command{mysqlcheck}:

@example
shell> mysqlcheck [@var{options}] @var{db_name} [@var{tables}]
shell> mysqlcheck [@var{options}] --databases @var{DB1} [@var{DB2} @var{DB3}...]
shell> mysqlcheck [@var{options}] --all-databases
@end example

If you don't name any tables or use the @code{--databases} or
@code{--all-databases} option, entire databases will be checked.

@command{mysqlcheck} has a special feature compared to the other clients. The
default behavior of checking tables (@code{--check}) can be changed by renaming
the binary. If you want to have a tool that repairs tables by default, you
should just make a copy of @command{mysqlcheck} named @command{mysqlrepair}, or make
a symbolic link to @command{mysqlcheck} named @command{mysqlrepair}. If you invoke
@code{mysqlrepair}, it will repair tables by command.

The following names can be used to change @command{mysqlcheck} default behavior:

@multitable @columnfractions .25 .75
@item @command{mysqlrepair}   @tab The default option will be @code{--repair}
@item @command{mysqlanalyze}  @tab The default option will be @code{--analyze}
@item @command{mysqloptimize} @tab The default option will be @code{--optimize}
@end multitable

@command{mysqlcheck} supports the following options:

@table @code

@item --help, -?
Display a help message and exit.

@item --all-databases, -A
Check all tables in all databases. This is the same as using the
@code{--databases} option and naming all the databases on the command line.

@item --all-in-1, -1
Instead of issuing a statement for each table, execute a single statement for
each database that names all the tables from that database to be processed.

@item  --analyze, -a
Analyze the tables.

@item --auto-repair
If a checked table is corrupted, automatically fix it. Any necessary repairs
are done after all tables have been checked.

@item --character-sets-dir=@var{path}
The directory where character sets are installed.  @xref{Character sets}.

@item --check, -c
Check the tables for errors.

@item --check-only-changed, -C
Check only tables that have changed since the last check or that haven't been
closed properly.

@item --compress
Compress all information sent between the client and the server if both
support compression.

@item --databases, -B
Process all tables in the named databases. With this option, all name
arguments are regarded as database names, not as table names.

@item --debug[=@var{debug_options}], -# [@var{debug_options}]
Write a debugging log. The @var{debug_options} string often is
@code{'d:t:o,@var{file_name}'}.

@item --default-character-set=@var{charset}
Use @var{charset} as the default character set.  @xref{Character sets}.

@item --extended, -e
If you are using this option to check tables, it ensures that they are
100% consistent but will take a long time.

If you are using this option to repair tables, it runs an extended
repair that may not only take a long time to execute, but
may produce a lot of garbage rows also!

@item --fast, -F
Check only tables that haven't been closed properly.

@item --force, -f
Continue even if an SQL error occurs.

@item --host=@var{host_name}, -h @var{host_name}
Connect to the MySQL server on the given host.

@item --medium-check, -m
Do a check that is faster than an @code{--extended} operation.
This finds only 99.99% of all errors, which should be good enough in most cases.

@item --optimize, -o
Optimize the tables.

@item --password[=@var{password}], -p[@var{password}]
The password to use when connecting to the server.  If you use the
short option form (@code{-p}), you @emph{cannot} have a space between the
option and the password.  If you omit the @var{password} value following the
@code{--password} or @code{-p} option on the command line, you will be
prompted for one.

@item --port=@var{port_num}, -P @var{port_num}
The TCP/IP port number to use for the connection.

@item --protocol=@{TCP | SOCKET | PIPE | MEMORY@}
The connection protocol to use.  New in MySQL 4.1.

@item --quick, -q
If you are using this option to check tables, it prevents the check
from scanning the rows to check for incorrect links. This is the fastest
check method.

If you are using this option to repair tables, it tries to repair
only the index tree. This is the fastest repair method.

@item --repair, -r
Do a repair that
can fix almost anything except unique keys that aren't unique.

@item --silent, -s
Silent mode.
Print only error messages.

@item --socket=@var{path}, -S @var{path}
The socket file to use for the connection.

@item --tables
Overrides the @code{--databases} or @code{-B} option. All arguments 
following the option are regarded as table names.

@item --user=@var{user_name}, -u @var{user_name}
The MySQL username to use when connecting to the server.

@item --verbose, -v
Verbose mode.
Print information about the various stages of program operation.

@item --version, -V
Display version information and exit.

@end table


@node mysqldump, mysqlhotcopy, Using mysqlcheck, Client-Side Scripts
@section The @command{mysqldump} Database Backup Program

@c TODO: indicate what privileges are required for the various dump operations
@c SELECT, LOCK, RELOAD

@cindex dumping, databases
@cindex databases, dumping
@cindex tables, dumping
@cindex backing up, databases

@cindex @command{mysqldump}
The @command{mysqldump} client can be used
to dump a database or a collection of databases for backup or for
transferring the data to another SQL server (not necessarily a MySQL
server).  The dump will contain SQL statements to create the table
and/or populate the table.

If you are doing a backup on the server, and your tables all are
@code{MyISAM} tables, you could consider using
the @command{mysqlhotcopy} instead (faster backup, faster
restore). @xref{mysqlhotcopy, , @command{mysqlhotcopy}}.

There are three general ways to invoke @command{mysqldump}:

@example
shell> mysqldump [@var{options}] @var{db_name} [@var{tables}]
shell> mysqldump [@var{options}] --databases @var{DB1} [@var{DB2} @var{DB3}...]
shell> mysqldump [@var{options}] --all-databases
@end example

If you don't name any tables or use the @code{--databases} or
@code{--all-databases} option, entire databases will be dumped.

To get a list of the options your version of @command{mysqldump} supports,
execute @command{mysqldump --help}.

If you run @command{mysqldump} without the @code{--quick} or
@code{--opt} option, @command{mysqldump} will load the whole result set into
memory before dumping the result.  This will probably be a problem if
you are dumping a big database. As of MySQL 4.1, @code{--opt} is on by
default, but can be disabled with @code{--skip-opt}.

If you are using a recent copy of the @command{mysqldump} program
and you are going to generate a dump that will be reloaded into a very old MySQL
server, you should not use the @code{--opt} or @code{-e} options.

Out-of-range numeric values such as @code{-inf} and @code{inf}, as well
as NaN (not-a-number) values are dumped by @command{mysqldump} as @code{NULL}.
You can see this using the following sample table:

@example
mysql> CREATE TABLE t (f DOUBLE);
mysql> INSERT INTO t VALUES(1e+111111111111111111111);
mysql> INSERT INTO t VALUES(-1e111111111111111111111);
mysql> SELECT f FROM t;
+------+
| f    |
+------+
|  inf |
| -inf |
+------+
@end example

For this table, @command{mysqldump} produces the following data output:

@example
--
-- Dumping data for table `t`
--

INSERT INTO t VALUES (NULL);
INSERT INTO t VALUES (NULL);
@end example

The significance of this behavior is that if you dump and restore the
table, the new table has contents that differ from the original contents.
Note that since MySQL 4.1.2 you cannot insert @code{inf} in the table,
so this @command{mysqldump} behavior is only relevant when you deal
with old servers.

@command{mysqldump} supports the following options:

@table @code

@item --help, -?
Display a help message and exit.

@item --add-drop-table
Add a @code{DROP TABLE} statement before each @code{CREATE TABLE} statement.

@item --add-locks
Surround each table dump with @code{LOCK TABLES} and @code{UNLOCK TABLES}
statements. This results in faster inserts when the dump file is reloaded.
@xref{Insert speed}.

@item --all-databases, -A
Dump all tables in all databases. This is the same as using the
@code{--databases} option and naming all the databases on the command line.

@item --allow-keywords
Allow creation of column names that are keywords.  This works by
prefixing each column name with the table name.

@item --comments[=@{0|1@}]
If set to @code{0}, suppresses additional information in the dump file such
as program version, server version, and host. @code{--skip-comments} has the
same effect as @code{--comments=0}.  The default value is @code{1} to not
suppress the extra information.  New in MySQL 4.0.17.

@item --compatible=@var{name}
Produce output that
is compatible with other database systems or with older MySQL servers.
The value of @code{name} can be
@code{ansi},
@code{mysql323},
@code{mysql40},
@code{postgresql},
@code{oracle},
@code{mssql},
@code{db2},
@code{maxdb},
@code{no_key_options},
@code{no_table_options},
or
@code{no_field_options}.
To use several values, separate them by commas.
These values have the same meaning as the corresponding options for setting
the server SQL mode.
@xref{Server SQL mode}.

This option requires a server version of 4.1.0 or higher.
With older servers, it does nothing.

@item --complete-insert, -c
Use complete @code{INSERT} statements that include column names.

@item --compress, -C
Compress all information sent between the client and the server if both
support compression.

@item --create-options
Include all MySQL-specific table options in the @code{CREATE TABLE} statements.
Before MySQL 4.1.2, use @code{--all} instead.

@item --databases, -B
To dump several databases. Note the difference in usage. In this case, no
tables are given. All name arguments on the command line are regarded as
database names.  A @code{USE @var{db_name}} statement is included in the
output before each new database.

@item --debug[=@var{debug_options}], -# [@var{debug_options}]
Write a debugging log. The @var{debug_options} string often is
@code{'d:t:o,@var{file_name}'}.

@item --default-character-set=@var{charset}
Use @var{charset} as the default character set.  @xref{Character sets}.
If not specified, @command{mysqldump} from MySQL 4.1.2 or later
uses @code{utf8}; earlier versions use @code{latin1}.

@item --delayed
Insert rows using @code{INSERT DELAYED} statements.

@item --delete-master-logs
On a master replication server, delete the binary
logs after performing the dump operation.
This option automatically enables @code{--first-slave}.
It was added in MySQL 3.23.57 (for MySQL 3.23) and MySQL 4.0.13 (for MySQL
4.0).

@item --disable-keys, -K
For each table, surround the @code{INSERT} statements with
@code{/*!40000 ALTER TABLE @var{tbl_name} DISABLE KEYS */;} and
@code{/*!40000 ALTER TABLE @var{tbl_name} ENABLE KEYS */;} statements.
This makes loading the dump file into a MySQL 4.0 server faster because the
indexes are created after all rows are inserted.
This option is effective only for @code{MyISAM} tables.

@item --extended-insert, -e
Use multiple-row @code{INSERT} syntax that include several @code{VALUES} lists.
This results in a smaller dump file and speeds up inserts when the file is
reloaded.

@item --fields-terminated-by=...
@itemx --fields-enclosed-by=...
@itemx --fields-optionally-enclosed-by=...
@itemx --fields-escaped-by=...
@itemx --lines-terminated-by=...
These options are used with the @code{-T} option and have the same
meaning as the corresponding clauses for @code{LOAD DATA INFILE}.
@xref{LOAD DATA, , @code{LOAD DATA}}.

@item --first-slave, -x
Deprecated, renamed to @code{--lock-all-tables} in MySQL 4.1.8.

@item --flush-logs, -F
Flush the MySQL server log files before starting the dump. Note that if you
use this option in combination with the @code{--all-databases} (or
@code{-A}) option, the logs are flushed @emph{for each database dumped}.
The exception is when using @code{--lock-all-tables}
or @code{--master-data}:
In this case, the logs are flushed only once, corresponding to the moment
that all tables are locked. If you want your dump and the log flush to
happen at exactly the same moment, you should use @code{--flush-logs}
together with either @code{--lock-all-tables} or @code{--master-data}.

@item --force, -f
Continue even if an SQL error occurs during a table dump.

@item --host=@var{host_name}, -h @var{host_name}
Dump data from the MySQL server on the given host. The default host
is @code{localhost}.

@item --hex-blob
Dump binary string columns using hexadecimal notation (for example,
@code{'abc'} becomes @code{0x616263}. The affected columns are @code{BINARY},
@code{VARBINARY}, and @code{BLOB} in MySQL 4.1 and up, and @code{CHAR
BINARY}, @code{VARCHAR BINARY}, and @code{BLOB} in MySQL 4.0.  This option
was added in MySQL 4.0.23 and 4.1.8.

@item --lock-all-tables, -x
Locks all tables across all databases. This is achieved by acquiring a global
read lock for the duration of the whole dump. This option automatically
turns off @code{--single-transaction} and @code{--lock-tables}. Added in
MySQL 4.1.8.

@item --lock-tables, -l
Lock all tables before starting the dump.  The tables are locked with
@code{READ LOCAL} to allow concurrent inserts in the case of @code{MyISAM}
tables.

Please note that when dumping multiple databases, @code{--lock-tables} locks
tables for each database separately. So, using this option will not guarantee
that the tables in the dump file will be logically consistent between
databases.  Tables in different databases may be dumped in completely
different states.

@item --master-data[=@var{value}]
This option causes the binary log position and filename to be appended to the
output. If the option value is equal to 1, the position and filename are
written to the dump output in the form of a @code{CHANGE MASTER} statement
that will make a slave server start from the correct
position in the master's binary logs if you use this SQL dump of the master
to set up a slave.
If the option value is equal to 2, the @code{CHANGE MASTER} statement is
written as an SQL comment. 
This is the default action if @var{value} is omitted.
@var{value} may be given as of MySQL 4.1.8; before that, do not specify
an option value.

The @code{--master-data}  option turns on @code{--lock-all-tables}, unless 
@code{--single-transaction} also is specified (in which case, a 
global read lock is only acquired a short time at the beginning of the
dump. See also the description for
@code{--single-transaction}. In all cases,
any action on logs happens at the exact moment of the dump.
This option automatically turns off @code{--lock-tables}.

@item --no-create-db, -n
This option suppresses the @code{CREATE DATABASE /*!32312 IF NOT EXISTS*/
db_name} statements that are otherwise included in the output if the
@code{--databases} or @code{--all-databases} option is given.

@item --no-create-info, -t
Don't write @code{CREATE TABLE} statements that re-create each dumped table.

@item --no-data, -d
Don't write any row information for the table.  This is very useful if you
just want to get a dump of the structure for a table.

@item --opt
This option is shorthand; it is the same as specifying @code{--add-drop-table
--add-locks --create-options --disable-keys --extended-insert
--lock-tables --quick --set-charset}.  It should
give you a fast dump operation and produce a dump file that can be reloaded
into a MySQL server quickly. @strong{As of MySQL 4.1, @code{--opt} is on by default,
but can be disabled with @code{--skip-opt}}. To disable only certain of the
options enabled by @code{--opt}, use their @code{--skip} forms; for example,
@code{--skip-add-drop-table} or @code{--skip-quick}.

@item --password[=@var{password}], -p[@var{password}]
The password to use when connecting to the server.  If you use the
short option form (@code{-p}), you @emph{cannot} have a space between the
option and the password.  If you omit the @var{password} value following the
@code{--password} or @code{-p} option on the command line, you will be
prompted for one.

@item --port=@var{port_num}, -P @var{port_num}
The TCP/IP port number to use for the connection.

@item --protocol=@{TCP | SOCKET | PIPE | MEMORY@}
The connection protocol to use.  New in MySQL 4.1.

@item  --quick, -q
This option is useful for dumping large tables.
It forces @command{mysqldump} to retrieve rows for a table from
the server a row at a time rather than retrieving the entire row set
and buffering it in memory before writing it out.

@item --quote-names, -Q
Quote database, table, and column names within @samp{`} characters.
If the server SQL mode includes the @code{ANSI_QUOTES} option, names are
quoted within @samp{"} characters.
As of MySQL 4.1.1, @code{--quote-names} is on by default,
but can be disabled with @code{--skip-quote-names}.

@item --result-file=@var{file}, -r @var{file}
Direct output to a given file. This option should be used on Windows, because
it prevents newline @samp{\n} characters from being converted to @samp{\r\n}
carriage return/newline sequences.

@item --set-charset
Add @code{SET NAMES @var{default_character_set}} to the output. This option
is enabled by default. To suppress the @code{SET NAMES} statement, use
@code{--skip-set-charset}. This option was added in MySQL 4.1.2.

@item --single-transaction
This option issues a @code{BEGIN} SQL statement before dumping data from
the server. It is mostly useful with @code{InnoDB} tables and
@code{READ COMMITTED} transaction isolation level, because in this mode it
will dump the consistent state of the database at the time then
@code{BEGIN} was issued without blocking any applications.

When using this option, you should keep in mind that only InnoDB
tables will be dumped in a consistent state. For example, any @code{MyISAM} or
@code{HEAP} tables dumped while using this option may still change
state.

The @code{--single-transaction} option was added in MySQL 4.0.2.
This option is mutually exclusive with the @code{--lock-tables} option,
because @code{LOCK TABLES} causes any pending transactions to be committed
implicitly.

@item --socket=@var{path}, -S @var{path}
The socket file to use when connecting to @code{localhost} (which is the
default host).

@item --skip-comments
See the description for the @code{--comments} option.

@item  --tab=@var{path}, -T @var{path}
Produces tab-separated data files.  For each dumped table, @command{mysqldump}
creates a @file{@var{tbl_name}.sql} file that contains the @code{CREATE TABLE}
statement that creates the table, and a @file{@var{tbl_name}.txt} file that
contains its data.  The option value is the directory in which to write the
files.

By default, the @file{.txt} data files are formatted using tab characters
between column values and a newline at the end of each line.  The format can
be specified explicitly using the @code{--fields-@var{xxx}} and
@code{--lines--@var{xxx}} options.

@strong{Note}: This option should be used only when @command{mysqldump} is run
on the same machine as the @command{mysqld} server. You must use a MySQL
account that has the @code{FILE} privilege, and the server must have
permission to write files in the directory you specify.

@item --tables
Overrides the @code{--databases} or @code{-B} option. All arguments 
following the option are regarded as table names.

@item --user=@var{user_name}, -u @var{user_name}
The MySQL username to use when connecting to the server.

@item --verbose, -v
Verbose mode.  Print out more information on what the program does.

@item --version, -V
Display version information and exit.

@item --where='@var{where-condition}', -w '@var{where-condition}'
Dump only records selected by the given @code{WHERE} condition.  Note that
quotes around the condition are mandatory if it contains spaces or
characters that are special to your command interpreter.

Examples:

@example
"--where=user='jimf'"
"-wuserid>1"
"-wuserid<1"
@end example

@item --xml, -X
Write dump output as well-formed XML.

@end table

You can also set the following variables by using @code{--@var{var_name}=@var{value}}
options:

@table @code

@item max_allowed_packet
The maximum size of the buffer for client/server communication.
The value of the variable can be up to 16MB before MySQL 4.0, and
up to 1GB from MySQL 4.0 on.
When creating multiple-row-insert statements (as with option
@code{--extended-insert} or @code{--opt}), @command{mysqldump} will create
rows up to @code{max_allowed_packet} length. If you increase this
variable, you should also ensure that the @code{max_allowed_packet}
variable in the MySQL server is at least this large.

@item net_buffer_length
The initial size of the buffer for client/server communication.

@end table

It is also possible to set variables by using
@code{--set-variable=@var{var_name}=@var{value}} or @code{-O @var{var_name}=@var{value}}
syntax. However, this syntax is deprecated as of MySQL 4.0.

The most common use of @command{mysqldump} is probably for making a backup of
entire databases.

@example
shell> mysqldump --opt @var{db_name} > @var{backup-file.sql}
@end example

You can read the dump file back into the server with:

@example
shell> mysql @var{db_name} < @var{backup-file.sql}
@end example

Or:

@example
shell> mysql -e "source @var{/path-to-backup/backup-file.sql}" @var{db_name}
@end example

@command{mysqldump} is also very useful for populating databases by copying
data from one MySQL server to another:

@example
shell> mysqldump --opt @var{db_name} | mysql --host=@var{remote_host} -C @var{db_name}
@end example

It is possible to dump several databases with one command:

@example
shell> mysqldump --databases @var{db_name1} [@var{db_name2} ...] > my_databases.sql
@end example

If you want to dump all databases, use the @code{--all-databases} option:

@example
shell> mysqldump --all-databases > all_databases.sql
@end example

If tables are stored in the InnoDB storage engine, @code{mysqldump} provides a
way of making an online backup of these (see command below). This backup just
needs to acquire a global read lock on all tables (using @code{FLUSH TABLES
WITH READ LOCK}) at the beginning of the dump. As soon as this lock has been
acquired, the binary log coordinates are read and lock is released. So if and
only if one long updating statement is running when the @code{FLUSH...} is
issued, the MySQL server may get stalled until that long statement finishes,
and then the dump becomes lock-free. So if the MySQL server receives only
short (in the sense of "short execution time") updating statements, even if
there are plenty of them, the initial lock period should not be noticeable.

@example
shell> mysqldump --all-databases --single-transaction > all_databases.sql
@end example

For point-in-time recovery (also known as "roll-forward", when you need to
restore an old backup and replay the changes which happened since that backup),
it is often useful to rotate the binary log (@ref{Binary log}) or at least
know the binary log coordinates to which the dump corresponds:

@example
shell> mysqldump --all-databases --master-data=2 > all_databases.sql
or
shell> mysqldump --all-databases --flush-logs --master-data=2 > all_databases.sql
@end example

The simultaneous use of @code{--master-data} and @code{--single-transaction}
works as of MySQL 4.1.8. It provides a convenient way to make an online backup
suitable for point-in-time recovery, if tables are stored in the InnoDB storage
engine.

For more information on making backups, see @ref{Backup}.


@node mysqlhotcopy, mysqlimport, mysqldump, Client-Side Scripts
@section The @command{mysqlhotcopy} Database Backup Program

@c TODO: need *general* mysqlhotcopy invocation syntax. Only specific
@c examples are given here.

@cindex dumping, databases
@cindex databases, dumping
@cindex tables, dumping
@cindex backing up, databases

@command{mysqlhotcopy} is a Perl script that was originally written and
contributed by Tim Bunce. It uses @code{LOCK TABLES},
@code{FLUSH TABLES}, and @code{cp} or @code{scp} to quickly make a backup of
a database.  It's the fastest way to make a backup of the database or single
tables, but it can be run only on the same machine where the database
directories are located.  @command{mysqlhotcopy} works only for backing up
@code{MyISAM} and @code{ISAM} tables.
It runs on Unix, and as of MySQL 4.0.18 also on NetWare.

@c TODO: explain what these examples mean

@example
shell> mysqlhotcopy @var{db_name} [@var{/path/to/new_directory}]
@end example

@example
shell> mysqlhotcopy @var{db_name_1} ... @var{db_name_n} @var{/path/to/new_directory}
@end example

@example
shell> mysqlhotcopy @var{db_name}./@var{regex}/
@end example

@command{mysqlhotcopy} supports the following options:

@table @code

@item --help, -?
Display a help message and exit.

@item --allowold
Don't abort if target already exists (rename it by adding an @code{_old}
suffix).

@item --checkpoint=@var{db_name.tbl_name}
Insert checkpoint entries into the specified @var{db_name.tbl_name}.

@item --debug
Enable debug output.

@item --dryrun, -n
Report actions without doing them.

@item --flushlog
Flush logs after all tables are locked.

@item --keepold
Don't delete previous (now renamed) target when done.

@item --method=@var{#}
Method for copy (@code{cp} or @code{scp}).

@item --noindices
Don't include full index files in the backup. This makes the backup smaller
and faster.  The indexes can be reconstructed later with @command{myisamchk -rq}
for @code{MyISAM} tables or @command{isamchk -rq} for @code{ISAM} tables.

@item --password=@var{password}, -p@var{password}
The password to use when connecting to the server.  Note that the password
value is not optional for this option, unlike for other MySQL programs.

@item --port=@var{port_num}, -P @var{port_num}
The TCP/IP port number to use when connecting to the local server.

@item --quiet, -q
Be silent except for errors.

@item --regexp=@var{expr}
Copy all databases with names matching the given regular expression.

@item --socket=@var{path}, -S @var{path}
The Unix socket file to use for the connection.

@item --suffix=@var{str}
The suffix for names of copied databases.

@item --tmpdir=@var{path}
The temporary directory (instead of @file{/tmp}).

@item --user=@var{user_name}, -u @var{user_name}
The MySQL username to use when connecting to the server.

@end table

@command{mysqlhotcopy} reads the @code{[client]} and  @code{[mysqlhotcopy]}
option groups from option files.

To execute @command{mysqlhotcopy}, you must have access to the files
for the tables that you are backing up, the @code{SELECT} privilege
for those tables, and the @code{RELOAD} privilege (to be able to
execute @code{FLUSH TABLES}).

Use @code{perldoc} for additional @command{mysqlhotcopy} documentation:

@example
shell> perldoc mysqlhotcopy
@end example


@node mysqlimport, mysqlshow, mysqlhotcopy, Client-Side Scripts
@section The @command{mysqlimport} Data Import Program

@cindex importing, data
@cindex data, importing
@cindex files, text
@cindex text files, importing
@cindex @command{mysqlimport}

The @command{mysqlimport} client provides a command-line interface to the
@code{LOAD DATA INFILE} SQL statement.  Most options to @command{mysqlimport}
correspond directly to clauses of @code{LOAD DATA INFILE}.
@xref{LOAD DATA, , @code{LOAD DATA}}.

Invoke @command{mysqlimport} like this:

@example
shell> mysqlimport [@var{options}] @var{db_name} @var{textfile1} [@var{textfile2} ...]
@end example

For each text file named on the command line, @command{mysqlimport} strips any
extension from the filename and uses the result to determine the name of the
table into which to import the file's contents.  For example, files named
@file{patient.txt}, @file{patient.text}, and @file{patient} all would be
imported into a table named @code{patient}.

@command{mysqlimport} supports the following options:

@table @code

@item --help, -?
Display a help message and exit.

@item --columns=@var{column_list}, -c @var{column_list}
This option takes a comma-separated list of column names as its value. The
order of the column names indicates how to match up data file columns with
table columns.

@item --compress, -C
Compress all information sent between the client and the server if both
support compression.

@item --debug[=@var{debug_options}], -# [@var{debug_options}]
Write a debugging log. The @var{debug_options} string often is
@code{'d:t:o,@var{file_name}'}.

@item --delete, -D
Empty the table before importing the text file.

@item --fields-terminated-by=...
@itemx --fields-enclosed-by=...
@itemx --fields-optionally-enclosed-by=...
@itemx --fields-escaped-by=...
@itemx --lines-terminated-by=...
These options have the same meaning as the corresponding clauses for
@code{LOAD DATA INFILE}. @xref{LOAD DATA, , @code{LOAD DATA}}.

@item --force, -f
Ignore errors.  For example, if a table for a text file doesn't exist,
continue processing any remaining files.  Without @code{--force},
@command{mysqlimport} exits if a table doesn't exist.

@item --host=@var{host_name}, -h @var{host_name}
Import data to the MySQL server on the given host. The default host
is @code{localhost}.

@item --ignore, -i
See the description for the @code{--replace} option.

@item --ignore-lines=@var{n}
Ignore the first @var{n} lines of the data file.

@item --local, -L
Read input files locally from the client host.

@item --lock-tables, -l
Lock @emph{all} tables for writing before processing any text files. This
ensures that all tables are synchronized on the server.

@item --password[=@var{password}], -p[@var{password}]
The password to use when connecting to the server.  If you use the
short option form (@code{-p}), you @emph{cannot} have a space between the
option and the password.  If you omit the @var{password} value following the
@code{--password} or @code{-p} option on the command line, you will be
prompted for one.

@item --port=@var{port_num}, -P @var{port_num}
The TCP/IP port number to use for the connection.

@item --protocol=@{TCP | SOCKET | PIPE | MEMORY@}
The connection protocol to use.  New in MySQL 4.1.

@item --replace, -r
The @code{--replace} and @code{--ignore} options control handling of input
records that duplicate existing records on unique key values.  If you specify
@code{--replace}, new rows replace existing rows that have the same unique key
value. If you specify @code{--ignore}, input rows that duplicate an existing
row on a unique key value are skipped.  If you don't specify either option, an
error occurs when a duplicate key value is found, and the rest of the text
file is ignored.

@item  --silent, -s
Silent mode.  Produce output only when errors occur.

@item --socket=@var{path}, -S @var{path}
The socket file to use when connecting to @code{localhost} (which is the
default host).

@item --user=@var{user_name}, -u @var{user_name}
The MySQL username to use when connecting to the server.

@item --verbose, -v
Verbose mode.  Print out more information what the program does.

@item --version, -V
Display version information and exit.

@end table

Here is a sample session that demonstrates use of @command{mysqlimport}:

@example
shell> mysql -e 'CREATE TABLE imptest(id INT, n VARCHAR(30))' test
shell> ed
a
100     Max Sydow
101     Count Dracula
.
w imptest.txt
32
q
shell> od -c imptest.txt
0000000   1   0   0  \t   M   a   x       S   y   d   o   w  \n   1   0
0000020   1  \t   C   o   u   n   t       D   r   a   c   u   l   a  \n
0000040
shell> mysqlimport --local test imptest.txt
test.imptest: Records: 2  Deleted: 0  Skipped: 0  Warnings: 0
shell> mysql -e 'SELECT * FROM imptest' test
+------+---------------+
| id   | n             |
+------+---------------+
|  100 | Max Sydow     |
|  101 | Count Dracula |
+------+---------------+
@end example


@node mysqlshow, perror, mysqlimport, Client-Side Scripts
@section @command{mysqlshow}, Showing Databases, Tables, and Columns

@cindex databases, displaying
@cindex displaying, database information
@cindex tables, displaying
@cindex columns, displaying
@cindex showing, database information

The @command{mysqlshow} client can be used to quickly look at which databases
exist, their tables, and a table's columns or indexes.

@command{mysqlshow} provides a command-line interface to several SQL
@code{SHOW} statements.  The same information can be obtained by using those
statements directly.  For example, you can issue them from the @command{mysql}
client program.
@xref{SHOW,  , @code{SHOW}}.

Invoke @command{mysqlshow} like this:

@example
shell> mysqlshow [@var{options}] [@var{db_name} [@var{tbl_name} [@var{col_name}]]]
@end example

@itemize @bullet
@item
If no database is given, all matching databases are shown.
@item
If no table is given, all matching tables in the database are shown.
@item
If no column is given, all matching columns and column types in the table
are shown.
@end itemize

Note that in newer MySQL versions, you see only those
database, tables, or columns for which you have some privileges.

If the last argument contains shell or SQL wildcard characters (@samp{*},
@samp{?}, @samp{%}, or @samp{_}), only those names that are matched by the
wildcard are shown.  If a database name contains any underscores, those
should be escaped with a backslash (some Unix shells will require two) in
order to get a list of the proper tables or columns. @samp{*} and @samp{?}
characters are converted into SQL @samp{%} and @samp{_} wildcard characters.
This might cause some confusion when you try to display the columns for a
table with a @samp{_} in the name, because in this case @command{mysqlshow}
shows you only the table names that match the pattern.  This is easily fixed
by adding an extra @samp{%} last on the command line as a separate
argument.

@command{mysqlshow} supports the following options:

@table @code

@item --help, -?
Display a help message and exit.

@item --character-sets-dir=@var{path}
The directory where character sets are installed.  @xref{Character sets}.

@item --compress, -C
Compress all information sent between the client and the server if both
support compression.

@item --debug[=@var{debug_options}], -# [@var{debug_options}]
Write a debugging log. The @var{debug_options} string often is
@code{'d:t:o,@var{file_name}'}.

@item --default-character-set=@var{charset}
Use @var{charset} as the default character set.  @xref{Character sets}.

@item --host=@var{host_name}, -h @var{host_name}
Connect to the MySQL server on the given host.

@item --keys, -k
Show table indexes.

@item --password[=@var{password}], -p[@var{password}]
The password to use when connecting to the server.  If you use the
short option form (@code{-p}), you @emph{cannot} have a space between the
option and the password.  If you omit the @var{password} value following the
@code{--password} or @code{-p} option on the command line, you will be
prompted for one.

@item --port=@var{port_num}, -P @var{port_num}
The TCP/IP port number to use for the connection.

@item --protocol=@{TCP | SOCKET | PIPE | MEMORY@}
The connection protocol to use.  New in MySQL 4.1.

@item --socket=@var{path}, -S @var{path}
The socket file to use when connecting to @code{localhost} (which is the
default host).

@item --status, -i
Display extra information about each table.

@item --user=@var{user_name}, -u @var{user_name}
The MySQL username to use when connecting to the server.

@item --verbose, -v
Verbose mode.  Print out more information what the program does.
This option can be used multiple times to increase the amount of information.

@item --version, -V
Display version information and exit.

@end table


@node perror, replace utility, mysqlshow, Client-Side Scripts
@section @command{perror}, Explaining Error Codes

@cindex error messages, displaying
@cindex perror

@cindex errno
@cindex Errcode

For most system errors, MySQL displays, in addition to an internal text
message, the system error code in one of the following styles:

@example
message ... (errno: #)
message ... (Errcode: #)
@end example

You can find out what the error code means by either examining the
documentation for your system or by using the @command{perror} utility.

@command{perror} prints a description for a system error code or for a storage
engine (table handler) error code.

Invoke @command{perror} like this:

@example
shell> perror [@var{options}] @var{errorcode} ...
@end example

Example:

@example
shell> perror 13 64
Error code  13:  Permission denied
Error code  64:  Machine is not on the network
@end example

Note that the meaning of system error messages may be dependent on your
operating system. A given error code may mean different things on different
operating systems.


@node replace utility,  , perror, Client-Side Scripts
@section The @command{replace} String-Replacement Utility

@cindex string replacement, replace utility
@cindex replace utility

The @command{replace} utility program changes strings in place in files or on
the standard input. It uses a finite state machine to match longer strings
first. It can be used to swap strings. For example, the following command
swaps @code{a} and @code{b} in the given files, @file{file1} and @file{file2}:

@example
shell> replace a b b a -- file1 file2 ...
@end example

Use the @code{--} option to indicate where the string-replacement list
ends and the filenames begin.

Any file named on the command line is modified in place, so you may want to
make a copy of the original before converting it.

If no files are named on the command line, @command{replace} reads the standard
input and writes to the standard output.  In this case, no @code{--} option is
needed.

The @command{replace} program is used by @command{msql2mysql}.
@xref{msql2mysql,  , @command{msql2mysql}}.

@command{replace} supports the following options:

@table @code

@item -?, -I
Display a help message and exit.

@item -# @var{debug_options}
Write a debugging log. The @code{@var{debug_options}} string often is
@code{'d:t:o,@var{file_name}'}.

@item -s
Silent mode.  Print out less information what the program does.

@item -v
Verbose mode.  Print out more information what the program does.

@item -V
Display version information and exit.

@end table


@node Language Structure, Charset, Client-Side Scripts, Top
@chapter Language Structure

This chapter discusses the rules for writing the following elements of SQL
statements when using MySQL:

@itemize @bullet

@item
Literal values such as strings and numbers

@item
Identifiers such as table and column names

@item
User and system variables

@item
Comments

@item
Reserved words

@end itemize

@menu
* Literals::                    Literal Values
* Legal names::                 Database, Table, Index, Column, and Alias Names
* Variables::                   User Variables
* System Variables::            System Variables
* Comments::                    Comment Syntax
* Reserved words::              Treatment of Reserved Words in MySQL
@end menu


@node Literals, Legal names, Language Structure, Language Structure
@section Literal Values

@cindex strings, defined
@cindex strings, escaping characters
@cindex literals
@cindex escape characters
@cindex backslash, escape character


This section describes how to write literal values in MySQL. These include
strings, numbers, hexadecimal values, boolean values, and @code{NULL}. The section also
covers the various nuances and ``gotchas'' that
you may run into when dealing with these basic types in MySQL.

@menu
* String syntax::               Strings
* Number syntax::               Numbers
* Hexadecimal values::          Hexadecimal Values
* Boolean values::              Boolean Values
* NULL values::                 @code{NULL} Values
@end menu


@node String syntax, Number syntax, Literals, Literals
@subsection Strings

A string is a sequence of characters, surrounded by either single quote
(@samp{'}) or double quote (@samp{"}) characters.  Examples:

@example
'a string'
"another string"
@end example

If the server SQL mode has @code{ANSI_QUOTES} enabled, string literals can be
quoted only with single quotes. A string quoted with double quotes will be
interpreted as an identifier.

As of MySQL 4.1.1, string literals may have an optional character set
introducer and @code{COLLATE} clause:

@cindex introducer, string literal
@cindex string literal introducer

@example
[_@var{charset_name}]'@var{string}' [COLLATE @var{collation_name}]
@end example

Examples:
@example
SELECT _latin1'@var{string}';
SELECT _latin1'@var{string}' COLLATE latin1_danish_ci;
@end example

For more information about these forms of string syntax, see
@ref{Charset-literal}.

Within a string, certain sequences have special meaning.  Each of these
sequences begins with a backslash (@samp{\}), known as the @emph{escape
character}.  MySQL recognizes the following escape sequences:

@c these aren't really functions, but that's probably the most reasonable index

@multitable @columnfractions .10 .90
@item @code{\0}
@findex \0 (ASCII 0)
@findex NUL
@tab An ASCII 0 (@code{NUL}) character.

@item @code{\'}
@findex \' (single quote)
@findex single quote (\')
@tab A single quote (@samp{'}) character.

@item @code{\"}
@findex \" (double quote)
@findex double quote (\")
@tab A double quote (@samp{"}) character.

@item @code{\b}
@findex \b (backspace)
@findex backspace (\b)
@tab A backspace character.

@item @code{\n}
@findex \n (newline)
@findex newline (\n)
@findex \n (linefeed)
@findex linefeed (\n)
@tab A newline (linefeed) character.

@item @code{\r}
@findex \r (carriage return)
@findex return (\r)
@findex carriage return (\r)
@tab A carriage return character.

@item @code{\t}
@findex \t (tab)
@findex tab (\t)
@tab A tab character.

@item @code{\Z}
@findex \Z (Control-Z) ASCII 26
@findex (Control-Z) \Z
@tab ASCII 26 (Control-Z).  This character can be encoded as @samp{\Z}
to allow you to
work around the problem that ASCII 26 stands for END-OF-FILE on Windows.
(ASCII 26 will cause problems if you try to use
@code{mysql @var{db_name} < @var{file_name}}.)

@item @code{\\}
@findex \\ (escape)
@findex escape (\\)
@tab A backslash (@samp{\}) character.

@item @code{\%}
@findex % (wildcard character)
@findex Wildcard character (%)
@tab A @samp{%} character. See note following table.

@item @code{\_}
@findex _ (wildcard character)
@findex Wildcard character (_)
@tab A @samp{_} character. See note following table.

@end multitable

These sequences are case sensitive. For example, @samp{\b} is interpreted as
a backspace, but @samp{\B} is interpreted as @samp{B}.

The @samp{\%} and @samp{\_} sequences are used to search for literal
instances of @samp{%} and @samp{_} in pattern-matching contexts where
they would otherwise be interpreted as wildcard characters. @xref{String
comparison functions}.
Note that if you use @samp{\%} or @samp{\_} in other contexts, they
return the strings @samp{\%} and @samp{\_} and not @samp{%} and
@samp{_}.

In all other escape sequences, backslash is ignored.  That is,
the escaped character is interpreted as if it was not escaped.

@cindex quotes, in strings
@noindent
There are several ways to include quotes within a string:

@itemize @bullet
@item
A @samp{'} inside a string quoted with @samp{'} may be written as @samp{''}.

@item
A @samp{"} inside a string quoted with @samp{"} may be written as @samp{""}.

@item
You can precede the quote character with an escape character (@samp{\}).

@item
A @samp{'} inside a string quoted with @samp{"} needs no special treatment
and need not be doubled or escaped.  In the same way, @samp{"} inside a
string quoted with @samp{'} needs no special treatment.
@end itemize

The following @code{SELECT} statements demonstrate how quoting and
escaping work:

@example
mysql> SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello';
+-------+---------+-----------+--------+--------+
| hello | "hello" | ""hello"" | hel'lo | 'hello |
+-------+---------+-----------+--------+--------+

mysql> SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello";
+-------+---------+-----------+--------+--------+
| hello | 'hello' | ''hello'' | hel"lo | "hello |
+-------+---------+-----------+--------+--------+

mysql> SELECT 'This\nIs\nFour\nLines';
+--------------------+
| This
Is
Four
Lines |
+--------------------+

mysql> SELECT 'disappearing\ backslash';
+------------------------+
| disappearing backslash |
+------------------------+
@end example

@cindex quoting binary data

If you want to insert binary data into a string column (such as a
@code{BLOB}), the following characters must be represented by escape
sequences:

@multitable @columnfractions .10 .90


@item @code{NUL}
@tab @code{NUL} byte (ASCII 0).
Represent this character by @samp{\0} (a backslash followed by an ASCII @samp{0} character).

@item @code{\}
@tab Backslash (ASCII 92).  Represent this character by @samp{\\}.

@item @code{'}
@tab Single quote (ASCII 39).  Represent this character by @samp{\'}.

@item @code{"}
@tab Double quote (ASCII 34).  Represent this character by @samp{\"}.

@end multitable

@cindex quoting
@cindex @code{BLOB}, inserting binary data
@findex mysql_real_escape_string()
@findex DBI->quote
When writing application programs, any string that might contain any of these
special characters
must be properly escaped before the string is used as a data value in an SQL
statement that is sent to the MySQL server.
You can do this in two ways:

@itemize @bullet
@item
Process the string with a function that escapes the special characters.  For
example, in a C program, you can use the @code{mysql_real_escape_string()}
C API function to escape characters.
@xref{mysql_real_escape_string,  , @code{mysql_real_escape_string()}}.
The Perl DBI interface provides a
@code{quote} method to convert special characters to the proper escape
sequences.  @xref{Perl}.

@item
As an alternative to explicitly escaping special characters,
many MySQL APIs provide a placeholder capability
that allows you to insert special markers into a query string, and then bind
data values to them when you issue the query.  In this case, the API takes
care of escaping special characters in the values for you.

@end itemize


@node Number syntax, Hexadecimal values, String syntax, Literals
@subsection Numbers

@cindex numbers
@cindex valid numbers, examples
@cindex integers
@cindex floats
@cindex negative values
@findex TRUE
@findex FALSE

Integers are represented as a sequence of digits. Floats use @samp{.} as a
decimal separator.  Either type of number may be preceded by @samp{-} to
indicate a negative value.

Examples of valid integers:

@example
1221
0
-32
@end example

Examples of valid floating-point numbers:

@example
294.42
-32032.6809e+10
148.00
@end example

An integer may be used in a floating-point context; it is interpreted
as the equivalent floating-point number.


@node Hexadecimal values, Boolean values, Number syntax, Literals
@subsection Hexadecimal Values

@tindex hexadecimal values

MySQL supports hexadecimal values.  In numeric contexts, these act
like integers (64-bit precision). In string contexts, these act like binary
strings, where each pair of hex digits is converted to a character:

@example
mysql> SELECT x'4D7953514C';
        -> 'MySQL'
mysql> SELECT 0xa+0;
        -> 10
mysql> SELECT 0x5061756c;
        -> 'Paul'
@end example

In MySQL 4.1 (and in MySQL 4.0 when using the @code{--new} option), the default
type of a hexadecimal value is a string.  If you want to ensure that
the value is treated as a number, you can use @code{CAST(... AS UNSIGNED)}:

@example
mysql> SELECT 0x41, CAST(0x41 AS UNSIGNED);
        -> 'A', 65
@end example

The @code{0x} syntax is based on ODBC.  Hexadecimal strings are often used by
ODBC to supply values for @code{BLOB} columns.
The @code{x'hexstring'} syntax is new in 4.0 and is based on standard SQL.

Beginning with MySQL 4.0.1, you can convert a string or a number to a string
in hexadecimal format with the @code{HEX()} function:

@example
mysql> SELECT HEX('cat');
        -> '636174'
mysql> SELECT 0x636174;
        -> 'cat'
@end example

@node Boolean values, NULL values, Hexadecimal values, Literals
@subsection Boolean Values

Beginning with MySQL 4.1, the constant @code{TRUE} evaluates to @code{1} and
the constant @code{FALSE} evaluates to @code{0}. The constant names can be
written in any lettercase.

@example
mysql> SELECT TRUE, true, FALSE, false;
        -> 1, 1, 0, 0
@end example


@node NULL values,  , Boolean values, Literals
@subsection @code{NULL} Values

@tindex NULL value

The @code{NULL} value means ``no data.''
@code{NULL} can be written in any lettercase.

Be aware that the @code{NULL} value is different from values such
as @code{0} for numeric types or the empty string for string types.
@xref{Problems with NULL, , Problems with @code{NULL}}.

For text file import or export operations performed with @code{LOAD DATA
INFILE} or @code{SELECT ... INTO OUTFILE}, @code{NULL} is represented by
the @code{\N} sequence.
@xref{LOAD DATA, , @code{LOAD DATA}}.


@node Legal names, Variables, Literals, Language Structure
@section Database, Table, Index, Column, and Alias Names

@menu
* Identifier qualifiers::       Identifier Qualifiers
* Name case sensitivity::       Identifier Case Sensitivity
@end menu

@cindex identifiers
@cindex names
@cindex legal names
@cindex databases, names
@cindex tables, names
@cindex indexes, names
@cindex columns, names
@cindex aliases, names

Database, table, index, column, and alias names are identifiers.
This section describes the allowable syntax for identifiers in MySQL.

The following table describes the maximum length and allowable characters for
each type of identifier.

@multitable @columnfractions .15 .15 .70
@item @strong{Identifier} @tab @strong{Maximum Length (bytes)} @tab @strong{Allowed Characters}
@item Database @tab 64 @tab Any character that is allowed in a directory name, except @samp{/}, @samp{\}, or @samp{.}
@item Table @tab 64 @tab Any character that is allowed in a filename, except @samp{/}, @samp{\}, or @samp{.}
@item Column @tab 64 @tab All characters
@item Index @tab 64 @tab All characters
@item Alias @tab 255 @tab All characters
@end multitable

In addition to the restrictions noted in the table, no identifier can
contain ASCII 0 or a byte with a value of 255.  Database, table, and
column names should not end with space characters.  Before MySQL 4.1,
identifier quote characters should not be used in identifiers.

Beginning with MySQL 4.1, identifiers are stored using Unicode (UTF8).
This applies to identifiers in table definitions that stored in @file{.frm}
files and to identifiers stored in the grant tables in the @code{mysql}
database. Although Unicode identifiers can include multi-byte characters, note
that the maximum lengths shown in the table are byte counts. If an identifier
does contain multi-byte characters, the number of @emph{characters} allowed in
the identifier is less than the value shown in the table.

@tindex identifiers, quoting
@tindex quoting of identifiers
@tindex `
@tindex "

An identifier may be quoted or unquoted.  If an identifier is a reserved
word or contains special characters, you @emph{must} quote it whenever you
refer to it.  For a list of reserved words, see @ref{Reserved words}.
Special characters are those outside the set of alphanumeric characters from
the current character set, @samp{_}, and @samp{$}.

The identifier quote character is the backtick (@samp{`}):

@example
mysql> SELECT * FROM `select` WHERE `select`.id > 100;
@end example

If the server SQL mode includes the @code{ANSI_QUOTES} mode option,
it is also allowable to quote identifiers with double quotes:

@example
mysql> CREATE TABLE "test" (col INT);
ERROR 1064: You have an error in your SQL syntax. (...)
mysql> SET sql_mode='ANSI_QUOTES';
mysql> CREATE TABLE "test" (col INT);
Query OK, 0 rows affected (0.00 sec)
@end example

@xref{Server SQL mode}.

As of MySQL 4.1, identifier quote characters can be included within an
identifier if you quote the identifier. If the character to be included within
the identifier is the same as that used to quote the identifier itself,
double the character. The following statement creates a table named @code{a`b}
that contains a column named @code{c"d}:

@example
mysql> CREATE TABLE `a``b` (`c"d` INT);
@end example

Identifier quoting was introduced in MySQL 3.23.6 to allow use of
identifiers that are reserved words or that contain special characters.
Before 3.23.6, you cannot use identifiers that require quotes, so the rules for
legal identifiers are more restrictive:

@itemize @bullet
@item
A name may consist of alphanumeric characters from the current character set,
@samp{_}, and @samp{$}. The default character set is ISO-8859-1
(Latin1). This may be changed with the @code{--default-character-set} option
to @command{mysqld}.
@xref{Character sets}.

@item
A name may start with any character that is legal in a name.  In particular,
a name may start with a digit; this differs from many other database
systems!  However, an unquoted name cannot consist @emph{only} of digits.

@item
You cannot use the @samp{.} character in names because it is used to extend the
format by which you can refer to columns (@pxref{Identifier qualifiers}).
@end itemize

It is recommended that you do not use names like @code{1e}, because
an expression like @code{1e+1} is ambiguous. It might be interpreted as the
expression @code{1e + 1} or as the number @code{1e+1}, depending on context.


@node Identifier qualifiers, Name case sensitivity, Legal names, Legal names
@subsection Identifier Qualifiers

MySQL allows names that consist of a single identifier or
multiple identifiers. The components of a multiple-part name should be
separated by period (@samp{.}) characters. The initial parts of a
multiple-part name act as qualifiers that affect the context within which
the final identifier is interpreted.

In MySQL you can refer to a column using any of the following forms:

@multitable @columnfractions .30 .70
@item @strong{Column Reference} @tab @strong{Meaning}
@item @var{col_name} @tab The column @var{col_name}
from whichever table used in the query contains a column of that name.
@item @var{tbl_name.col_name} @tab The column @var{col_name} from table
@var{tbl_name} of the default database.
@item @var{db_name.tbl_name.col_name} @tab The column @var{col_name} from table
@var{tbl_name} of the database @var{db_name}.  This syntax is unavailable
before MySQL 3.22.
@end multitable

If any components of a multiple-part name require quoting, quote them
individually rather than quoting the name as a whole. For example,
@code{`my-table`.`my-column`} is legal, whereas @code{`my-table.my-column`} is
not.

You need not specify a @var{tbl_name} or @var{db_name.tbl_name} prefix for
a column reference in a statement unless the reference would be ambiguous.
Suppose that tables @code{t1} and @code{t2} each contain a column
@code{c}, and you retrieve @code{c} in a @code{SELECT} statement that uses
both @code{t1} and @code{t2}.  In this case, @code{c} is ambiguous because it
is not unique among the tables used in the statement. You must qualify it
with a table name as @code{t1.c} or @code{t2.c} to indicate which table you
mean.  Similarly, to retrieve from a table @code{t} in database @code{db1}
and from a table @code{t} in database @code{db2} in the same statement,
you must refer to columns in those tables as @code{db1.t.col_name}
and @code{db2.t.col_name}.

@cindex ODBC compatibility
@cindex compatibility, with ODBC
The syntax @var{.tbl_name} means the table @var{tbl_name} in the current
database.  This syntax is accepted for ODBC compatibility because some ODBC
programs prefix table names with a @samp{.} character.


@node Name case sensitivity,  , Identifier qualifiers, Legal names
@subsection Identifier Case Sensitivity

@cindex identifiers, case sensitivity
@cindex case sensitivity, in identifiers
@cindex names, case sensitivity
@cindex case sensitivity, in names
@cindex database names, case sensitivity
@cindex table names, case sensitivity
@cindex column names, case sensitivity
@cindex alias names, case sensitivity

In MySQL, databases correspond to directories within the data directory.
Tables within a database correspond to at least one file within the database
directory (and possibly more, depending on the storage engine).
Consequently, the case sensitivity of the
underlying operating system determines the case sensitivity of database and
table names.  This means database and table names are not case sensitive in
Windows, and case sensitive in most varieties of Unix. One notable
exception is Mac OS X, which is Unix-based but uses a default filesystem type
(HFS+) that is not
case sensitive.  However, Mac OS X also supports UFS volumes, which are case
sensitive just as on any Unix.
@xref{Extensions to ANSI}.

@strong{Note}: Although database and table names are not case sensitive on
some platforms, you should not refer to a given database or table using
different
cases within the same query.  The following query would not work because it
refers to a table both as @code{my_table} and as @code{MY_TABLE}:

@example
mysql> SELECT * FROM my_table WHERE MY_TABLE.col=1;
@end example

Column names, index names,
and column aliases are not case sensitive on any platform.

Table aliases are case sensitive before MySQL 4.1.1.  The following
query would not work because it refers to the alias both as @code{a} and
as @code{A}:

@example
mysql> SELECT @var{col_name} FROM @var{tbl_name} AS a
    -> WHERE a.@var{col_name} = 1 OR A.@var{col_name} = 2;
@end example

If you have trouble remembering the allowable lettercase for database
and table names, adopt a consistent convention, such as always creating
databases and tables using lowercase names.

How table and database names are stored on disk and used in MySQL is defined by the
@code{lower_case_table_names} system variable, which you can set when
starting @command{mysqld}.  @code{lower_case_table_names} can take one of
the following values:

@multitable @columnfractions .10 .90

@item @strong{Value} @tab @strong{Meaning}
@item @code{0} @tab Table and database names are stored on disk using the lettercase specified in the @code{CREATE TABLE} or @code{CREATE DATABASE} statement. Name comparisons are case sensitive.  This is the default on Unix systems. Note that if you force this to 0 with @code{--lower-case-table-names=0} on a case-insensitive filesystem and access @code{MyISAM} tablenames using different lettercases, this may lead to index corruption.

@item @code{1} @tab Table names are stored in lowercase on disk and name comparisons are not case sensitive. MySQL converts all table names to lowercase on storage and lookup.  This behavior also applies to database names as of MySQL 4.0.2, and to table aliases as of 4.1.1. This value is the default on Windows and Mac OS X systems.

@item @code{2} @tab Table and database names are stored on disk using the lettercase specified in the @code{CREATE TABLE} or @code{CREATE DATABASE} statement, but MySQL converts them to lowercase on lookup.  Name comparisons are not case sensitive.  @strong{Note}: This works @emph{only} on filesystems that are not case sensitive! @code{InnoDB} table names are stored in lowercase, as for @code{lower_case_table_names=1}. Setting @code{lower_case_table_names} to @code{2} can be done as of MySQL 4.0.18.

@end multitable

If you are using MySQL on only one platform, you don't normally have to
change the @code{lower_case_table_names} variable. However, you may
encounter difficulties if you want to transfer tables between platforms
that differ in filesystem case sensitivity. For example, on Unix, you
can have two different tables named @code{my_table} and @code{MY_TABLE},
but on Windows those names are considered the same.  To avoid data
transfer problems stemming from database or table name lettercase, you
have two options:

@itemize @bullet
@item
Use @code{lower_case_table_names=1} on all systems. The main disadvantage
with this is that when you use @code{SHOW TABLES} or @code{SHOW DATABASES},
you don't see the names in their original lettercase.

@item
Use @code{lower_case_table_names=0} on Unix and @code{lower_case_table_names=2}
on Windows. This preserves the lettercase of database and table names.
The disadvantage of this is that you must ensure that your queries always refer
to your database and table names with the correct lettercase on Windows. If
you transfer your queries to Unix, where lettercase is significant, they will
not work if the lettercase is incorrect.
@end itemize

Note that before setting @code{lower_case_table_names} to 1 on Unix, you must
first convert your old database and table names to lowercase before restarting
@command{mysqld}.

@node Variables, System Variables, Legal names, Language Structure
@section User Variables

@cindex variables, user
@cindex user variables
@cindex names, variables

MySQL supports user variables as of version 3.23.6. You can store a value in
a user variable and refer to it later, which allows you to pass values from
one statement to another. User variables are connection-specific. That is,
a variable defined by one client cannot be seen or used by other clients.
All variables for a client connection are automatically freed when the
client exits.

User variables are written as @code{@@@var{var_name}}, where the variable name
@var{var_name} may consist of alphanumeric characters from the current
character set, @samp{.}, @samp{_}, and @samp{$}. The default character set
is ISO-8859-1 (Latin1). This may be changed with the
@code{--default-character-set} option to @command{mysqld}. @xref{Character
sets}. User variable names are not case sensitive beginning with MySQL 5.0.
Before that, they are case sensitive.

One way to set a user variable is by issuing a @code{SET} statement:

@example
SET @@@var{var_name} = @var{expr} [, @@@var{var_name} = @var{expr}] ...
@end example

For @code{SET}, either @code{=} or @code{:=} can be used as the assignment
operator.  The @var{expr} assigned to each variable can evaluate
to an integer, real, string, or @code{NULL} value.

You can also assign a value to a user variable in statements other than
@code{SET}.  In this case, the assignment operator must be @code{:=} and not
@code{=} because @code{=} is treated as a comparison operator
in non-@code{SET} statements:

@example
mysql> SET @@t1=0, @@t2=0, @@t3=0;
mysql> SELECT @@t1:=(@@t2:=1)+@@t3:=4,@@t1,@@t2,@@t3;
+----------------------+------+------+------+
| @@t1:=(@@t2:=1)+@@t3:=4 | @@t1  | @@t2  | @@t3  |
+----------------------+------+------+------+
|                    5 |    5 |    1 |    4 |
+----------------------+------+------+------+
@end example

User variables may be used where expressions are allowed.  This
does not currently include contexts that explicitly require a number, such
as in the @code{LIMIT} clause of a @code{SELECT} statement, or the
@code{IGNORE number LINES} clause of a @code{LOAD DATA} statement.

If you refer to a variable that has not been initialized, its value
is @code{NULL}.

@strong{Note}: In a @code{SELECT} statement, each expression is evaluated
only when sent to the client.  This means that in a @code{HAVING},
@code{GROUP BY}, or @code{ORDER BY} clause, you cannot refer to an expression
that involves variables that are set in the @code{SELECT} list. For example,
the following statement will @emph{not} work as expected:

@example
mysql> SELECT (@@aa:=id) AS a, (@@aa+3) AS b FROM @var{tbl_name} HAVING b=5;
@end example

The reference to @code{b} in the @code{HAVING} clause refers to an alias
for an expression in the @code{SELECT} list that uses @code{@@aa}. This
does not work as expected: @code{@@aa} will not contain the value of the
current row, but the value of @code{id} from the previous selected row.

The general rule is to never assign @emph{and} use the same variable in
the same statement.

Another issue with setting a variable and using it in the same statement
is that the default result type of a variable is based on the type of
the variable at the start of the statement.  The following example
illustrates this:

@example
mysql> SET @@a='test';
mysql> SELECT @@a,(@@a:=20) FROM @var{tbl_name};
@end example

For this @code{SELECT} statement, MySQL will report to the client that
column one is a string and convert all accesses of @code{@@a} to strings,
even though @@a is set to a number for the second row.  After the
@code{SELECT} statement executes, @code{@@a} will be regarded as a
number for the next statement.

To avoid problems with this behavior, either do not set and use the same
variable within a single statement, or else set the variable to @code{0},
@code{0.0}, or @code{''} to define its type before you use it.

An unassigned variable has a value of @code{NULL} with a type of string.


@node System Variables, Comments, Variables, Language Structure
@section System Variables

@cindex variables, System
@cindex system variables
@cindex server variables

@menu
* Structured System Variables::  Structured System Variables
@end menu

Starting from MySQL 4.0.3, we provide better access to a lot of system
and connection variables. Many variables can be changed dynamically while
the server is running. This allows you to modify server operation without
having to stop and restart it.

@c NOTE: next few paragraphs also appear in @node Server system variables.
@c If you make changes one place, change them both.

The @command{mysqld} server maintains two kinds of variables.
Global variables affect the overall operation of the server.
Session variables affect its operation for individual client connections.

When the server starts, it initializes all global variables to their default
values. These defaults may be changed by options specified in option files
or on the command line.  After the server starts, those global variables
that are dynamic can be changed by connecting to the server and issuing
a @code{SET GLOBAL @var{var_name}} statement. To change a global variable,
you must have the @code{SUPER} privilege.

The server also maintains a set of session variables for each client
that connects. The client's session variables are initialized at connect
time using the current values of the corresponding global variables. For
those session variables that are dynamic, the client can change them
by issuing a @code{SET SESSION @var{var_name}} statement. Setting a session
variable requires no special privilege, but a client can change only its
own session variables, not those of any other client.

A change to a global variable is visible to any client that accesses that
global variable. However, it affects the corresponding session variable
that is intialized from the global variable only for clients that connect
after the change.  It does not affect the session variable for any client
that is already connected (not even that of the client that issues the
@code{SET GLOBAL} statement).

Global or session variables may be set or retrieved using several syntax
forms.  The following examples use @code{sort_buffer_size} as a sample variable
name.

To set the value of a @code{GLOBAL} variable, use one
of the following syntaxes:

@example
mysql> SET GLOBAL sort_buffer_size=@var{value};
mysql> SET @@@@global.sort_buffer_size=@var{value};
@end example

To set the value of a @code{SESSION} variable, use one of the
following syntaxes:

@example
mysql> SET SESSION sort_buffer_size=@var{value};
mysql> SET @@@@session.sort_buffer_size=@var{value};
mysql> SET sort_buffer_size=@var{value};
@end example

@code{LOCAL} is a synonym for @code{SESSION}.

If you don't specify @code{GLOBAL}, @code{SESSION}, or @code{LOCAL} when
setting a variable, @code{SESSION} is the default.
@xref{SET OPTION,  , @code{SET OPTION}}.

To retrieve the value of a @code{GLOBAL} variable, use one of the
following statements:

@example
mysql> SELECT @@@@global.sort_buffer_size;
mysql> SHOW GLOBAL VARIABLES like 'sort_buffer_size';
@end example

To retrieve the value of a @code{SESSION} variable, use one of the
following statements:

@example
mysql> SELECT @@@@sort_buffer_size;
mysql> SELECT @@@@session.sort_buffer_size;
mysql> SHOW SESSION VARIABLES like 'sort_buffer_size';
@end example

Here, too, @code{LOCAL} is a synonym for @code{SESSION}.

When you retrieve a variable with @code{SELECT @@@@@var{var_name}} (that is, you
do not specify @code{global.}, @code{session.}, or @code{local.}, MySQL returns
the @code{SESSION} value if it exists and the @code{GLOBAL} value otherwise.

For @code{SHOW VARIABLES}, if you do not specify @code{GLOBAL},
@code{SESSION}, or @code{LOCAL}, MySQL returns the @code{SESSION} value.

The reason for requiring the @code{GLOBAL} keyword when setting
@code{GLOBAL}-only variables but not when retrieving them is to prevent
problems in the future.  If we remove a @code{SESSION}
variable with the same name as a @code{GLOBAL} variable, a client with the
@code{SUPER} privilege might accidentally change the @code{GLOBAL} variable
rather than just the @code{SESSION} variable for its own connection.  If we
add a @code{SESSION} variable with the same name as a @code{GLOBAL}
variable, a client that intends to change the @code{GLOBAL} variable might
find only its own @code{SESSION} variable changed.

Further information about system startup options and system
variables can be found in @ref{Server options} and
@ref{Server system variables}.
A list of the variables that can be set at runtime is given in
@ref{Dynamic System Variables}.


@node Structured System Variables,  , System Variables, System Variables
@subsection Structured System Variables

Structured system variables are supported beginning with MySQL 4.1.1.
A structured variable differs from a regular system variable in two
respects:

@itemize @bullet
@item
Its value is a structure with components that specify
server parameters considered to be closely related.
@item
There might be several instances of a given type of structured variable.
Each one has a different name and refers to a different resource
maintained by the server.
@end itemize

Currently, MySQL supports one structured variable type. It specifies
parameters that govern the operation of key caches. A key cache structured
variable has these components:

@itemize @bullet
@item
@code{key_buffer_size}
@item
@code{key_cache_block_size}
@item
@code{key_cache_division_limit}
@item
@code{key_cache_age_threshold}
@end itemize

The purpose of this section is to describe the syntax for referring to
structured variables. Key cache variables are used for syntax examples,
but specific details about how key caches operate are found elsewhere, in
@ref{MyISAM key cache,  , @code{MyISAM} key cache}.

To refer to a component of a structured variable instance, you can use a
compound name in @code{instance_name.component_name} format. Examples:

@example
hot_cache.key_buffer_size
hot_cache.key_cache_block_size
cold_cache.key_cache_block_size
@end example

For each structured system variable, an instance with the name of
@code{default} is always predefined.  If you refer to a component of a
structured variable without any instance name, the @code{default} instance
is used.  Thus, @code{default.key_buffer_size} and @code{key_buffer_size}
both refer to the same system variable.

The naming rules for structured variable instances and components are as
follows:

@itemize @bullet
@item
For a given type of structured variable, each instance must have a name
that is unique @emph{within} variables of that type. However, instance names
need not be unique @emph{across} structured variable types. For example,
each structured variable will have an instance named @code{default},
so @code{default} is not unique across variable types.

@item
The names of the components of each structured variable type must be
unique across all system variable names.  If this were not true (that is, if
two different types of structured variables could share component
member names), it would not be clear which default structured variable
to use for references to member names that are not qualified by an
instance name.

@item
If a structured variable instance name is not legal as an unquoted identifier,
refer to it as a quoted identifier using backticks. For example,
@code{hot-cache} is not legal, but @code{`hot-cache`} is.

@item
@code{global}, @code{session}, and @code{local} are not legal instance
names. This avoids a conflict with notation such as @code{@@@@global.@var{var_name}}
for referring to non-structured system variables.

@end itemize

At the moment, the first two rules have no possibility of being violated
because the only structured variable type is the one for key caches.
These rules will assume greater significance if some other type of structured
variable is created in the future.

With one exception, it is allowable to refer to structured variable
components using compound names in any context where simple variable
names can occur.  For example, you can assign a value to a structured
variable using a command-line option:

@example
shell> mysqld --hot_cache.key_buffer_size=64K
@end example

In an option file, do this:

@example
[mysqld]
hot_cache.key_buffer_size=64K
@end example

If you start the server with such an option, it creates a key cache
named @code{hot_cache} with a size of 64KB in addition to the default
key cache that has a default size of 8MB.

Suppose that you start the server as follows:

@example
shell> mysqld --key_buffer_size=256K \
         --extra_cache.key_buffer_size=128K \
         --extra_cache.key_cache_block_size=2048
@end example

In this case, the server sets the size of the default key cache to 256KB.
(You could also have written @code{--default.key_buffer_size=256K}.)
In addition, the server creates a second key cache named @code{extra_cache}
that has a size of 128KB, with the size of block buffers for caching
table index blocks set to 2048 bytes.

The following example starts the server with three different key caches
having sizes in a 3:1:1 ratio:

@example
shell> mysqld --key_buffer_size=6M \
         --hot_cache.key_buffer_size=2M \
         --cold_cache.key_buffer_size=2M
@end example

Structured variable values may be set and retrieved at runtime as well.
For example, to set a key cache named @code{hot_cache} to a size of 10MB,
use either of these statements:

@example
mysql> SET GLOBAL hot_cache.key_buffer_size = 10*1024*1024;
mysql> SET @@@@global.hot_cache.key_buffer_size = 10*1024*1024;
@end example

To retrieve the cache size, do this:

@example
mysql> SELECT @@@@global.hot_cache.key_buffer_size;
@end example

However, the following statement does not work. The variable is not
interpreted as a compound name, but as a simple string for a @code{LIKE}
pattern-matching operation:

@example
mysql> SHOW GLOBAL VARIABLES LIKE 'hot_cache.key_buffer_size';
@end example

This is the exception to being able to use structured variable names anywhere
a simple variable name may occur.


@node Comments, Reserved words, System Variables, Language Structure
@section Comment Syntax

@findex Comment syntax

@cindex comments, adding

@c TODO: this is really the place to describe /*!...*/ and /*!nnnnn ... */
@c comment syntax.

The MySQL server supports three comment styles:

@itemize @bullet
@item
From a @samp{#} character to the end of the line.

@item
From a @samp{--@ } sequence to the end of the line.
This style is supported as of MySQL 3.23.3.
Note that the @samp{--@ } (double-dash) comment style requires the second dash
to be followed by at least one space (or by a control character such as a
newline). This syntax differs slightly from standard SQL comment syntax, as discussed in
@ref{ANSI diff comments}.

@item
From a @samp{/*} sequence to the following @samp{*/} sequence.
The closing sequence need not be on the same line, so this
syntax allows a comment to extend over multiple lines.

@end itemize

The following example demonstrates all three comment styles:

@example
mysql> SELECT 1+1;     # This comment continues to the end of line
mysql> SELECT 1+1;     -- This comment continues to the end of line
mysql> SELECT 1 /* this is an in-line comment */ + 1;
mysql> SELECT 1+
/*
this is a
multiple-line comment
*/
1;
@end example

The comment syntax just described applies to how the @command{mysqld} server
parses SQL statements. The @command{mysql} client program also performs some
parsing of statements before sending them to the server. (For example, it
does this to determine statement boundaries within a multiple-statement input
line.) However, there are some limitations on the way that @command{mysql}
parses @code{/* ... */} comments:

@itemize @bullet

@item
A semicolon within the comment is taken to indicate the end of the current
SQL statement and anything following it to indicate the beginning of the
next statement.  This problem was fixed in MySQL 4.0.13.

@item
A single quote, double quote, or backtick character is taken to indicate the beginning
of a quoted string or identifier, even within a comment.  If the quote is not matched by a
second quote within the comment, the parser doesn't realize the comment has
ended.  If you are running @command{mysql} interactively, you can tell that it
has gotten confused like this because the prompt changes from @code{mysql>}
to @code{'>}, @code{">}, or @code{`>}.
This problem was fixed in MySQL 4.1.1.

@item
An exclamation point used with this style of comment delimiter (e.g. 
@code{/*! ... */}) marks portions of SQL statements for conditional 
execution. For more information and examples, see @ref{Extensions to ANSI}.

@end itemize

For affected versions of MySQL,
these limitations apply both when you run @command{mysql} interactively
and when you put commands in a file and use @command{mysql} in batch mode to
process the file with @command{mysql < @var{file_name}}.


@node Reserved words,  , Comments, Language Structure
@section Treatment of Reserved Words in MySQL

@cindex keywords
@cindex reserved words, exceptions

A common problem stems from trying to use an identifier such as a table or
column name that is the name of a built-in MySQL data type or function,
such as @code{TIMESTAMP} or @code{GROUP}.  You're allowed
to do this (for example, @code{ABS} is allowed as a column name). However,
by default, no whitespace is allowed in function invocations between the
function name and the following @samp{(} character. This requirement allows
a function call to be distinguished from a reference to a column name.

A side effect of this behavior is that omitting a space in some contexts
causes an identifier to be interpreted as a function name. For example, this
statement is legal:

@example
mysql> CREATE TABLE abs (val INT);
@end example

But omitting the space after @code{abs} causes a syntax error because the
statement then appears to invoke the @code{ABS()} function:

@example
mysql> CREATE TABLE abs(val INT);
@end example

If the server SQL mode includes the @code{IGNORE_SPACE} mode value, the
server allows function invocations to have whitespace between a function
name and the following @samp{(} character. This causes function names to be
treated as reserved words. As a result, identifiers that are the same as
function names must be quoted as described in @ref{Legal names}.  The server
SQL mode is controlled as described in @ref{Server SQL mode}.

The words in the following table are explicitly reserved in MySQL. Most of
them are forbidden by standard SQL as column and/or table names (for example,
@code{GROUP}).  A few are reserved because MySQL needs them and (currently)
uses a @command{yacc} parser.  A reserved word can be used as an identifier if
you quote it.

@include reservedwords.texi

MySQL allows some keywords to be used as unquoted identifiers because many
people have already used them.  Examples are those in the following list:

@itemize @bullet
@item @code{ACTION}
@item @code{BIT}
@item @code{DATE}
@item @code{ENUM}
@item @code{NO}
@item @code{TEXT}
@item @code{TIME}
@item @code{TIMESTAMP}
@end itemize


@node Charset, Column types, Language Structure, Top
@chapter Character Set Support

@cindex Character sets
@cindex Unicode
@cindex UTF8
@cindex UTF-8
@cindex UCS-2

@c TODO:

@c Note: Put credits in contributors section.
@c Add indexing.
@c Add info about how to configure in various charsets
@c ENUM and SET can have character set clauses as well

@menu
* Charset-general::             Character Sets and Collations in General
* Charset-MySQL::               Character Sets and Collations in MySQL
* Charset-defaults::            Determining the Default Character Set and Collation
* Charset-operations::          Operations Affected by Character Set Support
* Charset-Unicode::             Unicode Support
* Charset-metadata::            UTF8 for Metadata
* Charset-compatibility::       Compatibility with Other DBMSs
* Charset-config-file::         New Character Set Configuration File Format
* Charset-national::            National Character Set
* Charset-upgrading::           Upgrading Character Sets from MySQL 4.0
* Charset-charsets::            Character Sets and Collations That MySQL Supports
@end menu

Improved support for character set handling was added to MySQL in Version
4.1.  The features described here are as implemented in MySQL 4.1.1.
(MySQL 4.1.0 has some but not all of these features, and some of them are
implemented differently.)

This chapter discusses the following topics:

@itemize @bullet
@item What are character sets and collations?
@item The multiple-level default system
@item New syntax in MySQL 4.1
@item Affected functions and operations
@item Unicode support
@item The meaning of each individual character set and collation

@end itemize

Character set support currently is included in the @code{MyISAM},
@code{MEMORY} (@code{HEAP}), and (as of MySQL 4.1.2) @code{InnoDB} storage
engines.  The @code{ISAM} storage engine does not include character set
support; there are no plans to change this, because @code{ISAM} is
deprecated.


@node Charset-general, Charset-MySQL, Charset, Charset
@section Character Sets and Collations in General


A @strong{character set} is a set of symbols and encodings. A 
@strong{collation} is a set of rules for comparing characters in a
character set. Let's make the distinction clear with an example of an 
imaginary character set.

Suppose that we have an alphabet with four letters: @samp{A}, @samp{B}, 
@samp{a}, @samp{b}. We give each letter a number: @samp{A} = 0, 
@samp{B} = 1, @samp{a} = 2, @samp{b} = 3. The letter @samp{A} is a 
symbol, the number 0 is the @strong{encoding} for @samp{A}, and the 
combination of all four letters and their encodings is a 
@strong{character set}.

Now, suppose that we want to compare two string values, @samp{A} and @samp{B}.
The simplest way to do this is to look at the encodings: 0 for
@samp{A} and 1 for @samp{B}. Because 0 is less than 1, we say @samp{A} is less
than @samp{B}. Now, what we've just done is apply a collation to our
character set. The collation is a set of rules (only one rule in
this case): ``compare the encodings.'' We call this simplest of all
possible collations a @strong{binary} collation.

But what if we want to say that the lowercase and uppercase
letters are equivalent? Then we would have at least two rules: (1)
treat the lowercase letters @samp{a} and @samp{b} as equivalent to @samp{A} and
@samp{B}; (2) then compare the encodings. We call this a
@strong{case-insensitive} collation. It's a little more complex than a
binary collation.

In real life, most character sets have many characters: not just
@samp{A} and @samp{B} but whole alphabets, sometimes multiple alphabets or
eastern writing systems with thousands of characters, along with
many special symbols and punctuation marks. Also in real life, most
collations have many rules: not just case insensitivity but also
accent insensitivity (an ``accent'' is a mark attached to a character
as in German @samp{@"O}) and multiple-character mappings (such as the
rule that @samp{@"O} = @samp{OE} in one of the two German collations).

MySQL 4.1 can do these things for you:

@itemize @bullet
@item Store strings using a variety of character sets
@item Compare strings using a variety of collations
@item Mix strings with different character sets or collations in the
same server, the same database, or even the same table
@item Allow specification of character set and collation at any
level

@end itemize

In these respects, not only is MySQL 4.1 far more flexible than
MySQL 4.0, it also is far ahead of other DBMSs. However, to use the
new features effectively, you will need to learn what character
sets and collations are available, how to change their defaults,
and what the various string operators do with them.


@node Charset-MySQL, Charset-defaults, Charset-general, Charset
@section Character Sets and Collations in MySQL

The MySQL server can support multiple character sets. To list the available
character sets, use the @code{SHOW CHARACTER SET} statement:

@c NOTE: If you rerun the following command, trim off the Maxlen column.
@c Otherwise, the lines are too long to fit nicely on the page.

@example
mysql> SHOW CHARACTER SET;
+----------+-----------------------------+---------------------+
| Charset  | Description                 | Default collation   |
+----------+-----------------------------+---------------------+
| big5     | Big5 Traditional Chinese    | big5_chinese_ci     |
| dec8     | DEC West European           | dec8_swedish_ci     |
| cp850    | DOS West European           | cp850_general_ci    |
| hp8      | HP West European            | hp8_english_ci      |
| koi8r    | KOI8-R Relcom Russian       | koi8r_general_ci    |
| latin1   | ISO 8859-1 West European    | latin1_swedish_ci   |
| latin2   | ISO 8859-2 Central European | latin2_general_ci   |
...
@end example

The output actually includes another column that is not shown so that the
example fits better on the page.

Any given character set always has at least one collation. It may have
several collations.

To list the collations for a character set, use the @code{SHOW COLLATION}
statement. For example, to see the collations for the @code{latin1}
(``ISO-8859-1 West European'') character set, use this statement to find
those collation names that begin with @code{latin1}:

@example
mysql> SHOW COLLATION LIKE 'latin1%';
+-------------------+---------+----+---------+----------+---------+
| Collation         | Charset | Id | Default | Compiled | Sortlen |
+-------------------+---------+----+---------+----------+---------+
| latin1_german1_ci | latin1  |  5 |         |          |       0 |
| latin1_swedish_ci | latin1  |  8 | Yes     | Yes      |       1 |
| latin1_danish_ci  | latin1  | 15 |         |          |       0 |
| latin1_german2_ci | latin1  | 31 |         | Yes      |       2 |
| latin1_bin        | latin1  | 47 |         | Yes      |       1 |
| latin1_general_ci | latin1  | 48 |         |          |       0 |
| latin1_general_cs | latin1  | 49 |         |          |       0 |
| latin1_spanish_ci | latin1  | 94 |         |          |       0 |
+-------------------+---------+----+---------+----------+---------+
@end example

The @code{latin1} collations have the following meanings:

@multitable @columnfractions .4 .6

@item @strong{Collation} @tab @strong{Meaning}
@item @code{latin1_bin} @tab Binary according to @code{latin1} encoding
@item @code{latin1_danish_ci} @tab Danish/Norwegian
@item @code{latin1_general_ci} @tab Multilingual
@item @code{latin1_general_cs} @tab Multilingual, case sensitive
@item @code{latin1_german1_ci} @tab German DIN-1
@item @code{latin1_german2_ci} @tab German DIN-2
@item @code{latin1_spanish_ci} @tab Modern Spanish
@item @code{latin1_swedish_ci} @tab Swedish/Finnish

@end multitable

Collations have these general characteristics:

@itemize @bullet
@item
Two different character sets cannot have the same collation.

@item
Each character set has one collation that is the @emph{default
collation}. For example, the default collation for @code{latin1} is
@code{latin1_swedish_ci}.

@item
There is a convention for collation names: They start
with the name of the character set with which they are associated, they
usually include a language name, and they end with @code{_ci} (case
insensitive), @code{_cs} (case sensitive), or @code{_bin} (binary).

@end itemize


@node Charset-defaults, Charset-operations, Charset-MySQL, Charset
@section Determining the Default Character Set and Collation

@menu
* Charset-server::              Server Character Set and Collation
* Charset-database::            Database Character Set and Collation
* Charset-table::               Table Character Set and Collation
* Charset-column::              Column Character Set and Collation
* Charset-examples::            Examples of Character Set and Collation Assignment
* Charset-connection::          Connection Character Sets and Collations
* Charset-literal::             Character String Literal Character Set and Collation
* Charset-collate::             Using @code{COLLATE} in SQL Statements
* Charset-collate-precedence::  @code{COLLATE} Clause Precedence
* Charset-binary-op::           @code{BINARY} Operator
* Charset-collate-tricky::      Some Special Cases Where the Collation Determination Is Tricky
* Charset-collation-charset::   Collations Must Be for the Right Character Set
* Charset-collation-effect::    An Example of the Effect of Collation
@end menu

There are default settings for character sets and collations at
four levels: server, database, table, and connection. The following
description may appear complex, but it has been found in practice
that multiple-level defaulting leads to natural and obvious
results.


@node Charset-server, Charset-database, Charset-defaults, Charset-defaults
@subsection Server Character Set and Collation

The MySQL Server has a server character set and a server collation,
which may not be null.

MySQL determines the server character set and server collation
thus:

@itemize @bullet

@item
According to the option settings in effect when the server starts
@item
According to the values set at runtime

@end itemize

At the server level, the decision is simple. The server
character set and collation depend initially on the
options that you use when you start @command{mysqld}. You can use
@code{--default-character-set} for the character set, and
along with it you can add @code{--default-collation} for the
collation. If you don't specify a character set, that is the same as saying
@code{--default-character-set=latin1}. If you specify only a character set
(for example, @code{latin1}) but not a collation, that is the same as saying
@code{--default-charset=latin1} @code{--default-collation=latin1_swedish_ci}
because @code{latin1_swedish_ci} is the default collation for @code{latin1}.
Therefore, the following three commands all have the same effect:

@example
shell> mysqld
shell> mysqld --default-character-set=latin1
shell> mysqld --default-character-set=latin1 \
           --default-collation=latin1_swedish_ci
@end example


One way to change the settings is by recompiling. If you want to
change the default server character set and collation when building
from sources, use: @code{--with-charset} and @code{--with-collation}
as arguments for @command{configure}. For example:

@example
shell> ./configure --with-charset=latin1
@end example

Or:

@example
shell> ./configure --with-charset=latin1 \
           --with-collation=latin1_german1_ci
@end example

Both @command{mysqld} and @command{configure} verify that the character
set/collation combination is valid. If not, each program displays an error
message and terminates.

The current server character set and collation are available as the values of
the @code{character_set_server} and @code{collation_server} system variables.
These variables can be changed at runtime.


@node Charset-database, Charset-table, Charset-server, Charset-defaults
@subsection Database Character Set and Collation

Every database has a database character set and a database
collation, which may not be null. The @code{CREATE DATABASE} and @code{ALTER
DATABASE} statements have optional clauses for specifying the
database character set and collation:

@example
CREATE DATABASE @var{db_name}
    [[DEFAULT] CHARACTER SET @var{charset_name}]
    [[DEFAULT] COLLATE @var{collation_name}]

ALTER DATABASE @var{db_name}
    [[DEFAULT] CHARACTER SET @var{charset_name}]
    [[DEFAULT] COLLATE @var{collation_name}]
@end example

Example:

@example
CREATE DATABASE @var{db_name}
    DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;
@end example

MySQL chooses the database character set and database collation
thus:

@itemize @bullet
@item If both @code{CHARACTER SET @var{X}} and @code{COLLATE @var{Y}} were specified, then
character set @var{X} and collation @var{Y}.
@item If @code{CHARACTER SET @var{X}} was specified without @code{COLLATE}, then
character set @var{X} and its default collation.
@item Otherwise, the server character set and server collation.

@end itemize


MySQL's @code{CREATE DATABASE ... DEFAULT CHARACTER SET ...} syntax is
analogous to the standard SQL @code{CREATE SCHEMA ... CHARACTER SET ...}
syntax. Because of this, it is possible to create databases with
different character sets and collations on the same MySQL
server.


The database character set and collation are used as default
values if the table character set and collation are not specified
in @code{CREATE TABLE} statements. They have no other purpose.

The character set and collation for the default database are available as
the values of the @code{character_set_database} and
@code{collation_database} system variables.  The server sets these variables
whenever the default database changes.  If there is no default database, the
variables have the same value as the corresponding server-level variables,
@code{character_set_server} and @code{collation_server}.


@node Charset-table, Charset-column, Charset-database, Charset-defaults
@subsection Table Character Set and Collation

Every table has a table character set and a table collation, which
may not be null. The @code{CREATE TABLE} and @code{ALTER TABLE} statements
have optional clauses for specifying the table character set and
collation:

@example
CREATE TABLE @var{tbl_name} (@var{column_list})
    [DEFAULT CHARACTER SET @var{charset_name} [COLLATE @var{collation_name}]]

ALTER TABLE @var{tbl_name}
    [DEFAULT CHARACTER SET @var{charset_name}] [COLLATE @var{collation_name}]
@end example

Example:

@example
CREATE TABLE t1 ( ... )
    DEFAULT CHARACTER SET latin1 COLLATE latin1_danish_ci;
@end example


MySQL chooses the table character set and collation thus:

@itemize @bullet
@item If both @code{CHARACTER SET @var{X}} and @code{COLLATE @var{Y}} were specified, then
character set @var{X} and collation @var{Y}.
@item If @code{CHARACTER SET @var{X}} was specified without @code{COLLATE}, then
character set @var{X} and its default collation.
@item Otherwise, the database character set and collation.

@end itemize



The table character set and collation are used as default
values if the column character set and collation are not specified
in individual column definitions. The table character set and
collation are MySQL extensions; there are no such things in
standard SQL.


@node Charset-column, Charset-examples, Charset-table, Charset-defaults
@subsection Column Character Set and Collation

Every ``character'' column (that is, a column of type @code{CHAR},
@code{VARCHAR}, or @code{TEXT}) has a column character set and a column
collation, which may not be null. Column definition syntax has optional
clauses for specifying the column character set and collation:

@example
@var{col_name} @{CHAR | VARCHAR | TEXT@} (@var{col_length})
    [CHARACTER SET @var{charset_name} [COLLATE @var{collation_name}]]
@end example

Example:

@example
CREATE TABLE Table1
(
    column1 VARCHAR(5) CHARACTER SET latin1 COLLATE latin1_german1_ci
);
@end example


MySQL chooses the column character set and collation thus:

@itemize @bullet
@item If both @code{CHARACTER SET @var{X}} and @code{COLLATE @var{Y}} were specified, then
character set @var{X} and collation @var{Y}.
@item If @code{CHARACTER SET X} was specified without @code{COLLATE}, then
character set @code{X} and its default collation.
@item Otherwise, the table character set and collation.

@end itemize

The @code{CHARACTER SET} and @code{COLLATE} clauses are standard SQL.


@node Charset-examples, Charset-connection, Charset-column, Charset-defaults
@subsection Examples of Character Set and Collation Assignment

The following examples show how MySQL determines default character set and
collation values.

@subsubheading Example 1: Table + Column Definition

@example
CREATE TABLE t1
(
    c1 CHAR(10) CHARACTER SET latin1 COLLATE latin1_german1_ci
) DEFAULT CHARACTER SET latin2 COLLATE latin2_bin;
@end example

Here we have a column with a @code{latin1} character set
and a @code{latin1_german1_ci} collation. The definition is explicit, so
that's straightforward. Notice that there's no problem storing a
@code{latin1} column in a @code{latin2} table.

@subsubheading Example 2: Table + Column Definition

@example
CREATE TABLE t1
(
    c1 CHAR(10) CHARACTER SET latin1
) DEFAULT CHARACTER SET latin1 COLLATE latin1_danish_ci;
@end example

This time we have a column with a @code{latin1} character
set and a default collation. Now, although it might seem natural,
the default collation is not taken from the table level. Instead,
because the default collation for @code{latin1} is always
@code{latin1_swedish_ci},
column @code{c1} will have a collation of @code{latin1_swedish_ci} (not
@code{latin1_danish_ci}).

@subsubheading Example 3: Table + Column Definition


@example
CREATE TABLE t1
(
    c1 CHAR(10)
) DEFAULT CHARACTER SET latin1 COLLATE latin1_danish_ci;
@end example

We have a column with a default character set and
a default collation. In this circumstance, MySQL looks up to the
table level for inspiration in determining the column character set and
collation. So, the character set for column @code{c1} is
@code{latin1} and its collation is @code{latin1_danish_ci}.

@subsubheading Example 4: Database + Table + Column Definition

@example
CREATE DATABASE d1
    DEFAULT CHARACTER SET latin2 COLLATE latin2_czech_ci;
USE d1;
CREATE TABLE t1
(
    c1 CHAR(10)
);
@end example

We create a column without specifying its
character set and collation. We're also not specifying a character
set and a collation at the table level. In this circumstance, MySQL
looks up to the database level for inspiration. (The database's
settings become the table's settings, and thereafter become the
column's setting.) So, the character set for column @code{c1} is @code{latin2}
and its collation is @code{latin2_czech_ci}.


@node Charset-connection, Charset-literal, Charset-examples, Charset-defaults
@subsection Connection Character Sets and Collations

Several character set and collation system variables relate to a client's
interaction with the server. Some of these have already been mentioned in
earlier sections:

@itemize @bullet

@item
The server character set and collation are available as the values of the
@code{character_set_server} and @code{collation_server} variables.

@item
The character set and collation of the default database are available as the
values of the @code{character_set_database} and @code{collation_database}
variables.

@end itemize

Additional character set and collation variables are involved in handling
traffic for the connection between a client and the server.  Every client has
connection-related character set and collation variables.

Consider what a ``connection'' is: It's what you make when you connect to
the server. The client sends SQL statements, such as queries, over the
connection to the server. The server sends responses, such as result sets,
over the connection back to the client. This leads to several questions
about character set and collation handling for client connections, each of
which can be answered in terms of system variables:

@itemize @bullet

@item
What character set is the query in when it leaves the client?

The server takes the @code{character_set_client} variable to be the
character set in which queries are sent by the client.

@item
What character set should the server translate a query to after receiving it?

For this, @code{character_set_connection} and @code{collation_connection}
are used by the server.  It converts queries sent by the client from
@code{character_set_client} to @code{character_set_connection}
(except for string literals that have an introducer such as @code{_latin1} or
@code{_utf8}).
@code{collation_connection} is important for comparisons of literal strings.
For comparisons of strings with column values, it does not matter because
columns have a higher collation precedence.

@item
What character set should the server translate to before shipping result
sets or error messages back to the client?

The @code{character_set_results} variable indicates the character set in
which the server returns query results to the client. This includes result
data such as column values, and result metadata such as column names.

@end itemize

You can fine-tune the settings for these variables, or you can depend on the
defaults (in which case, you can skip this section).

There are two statements that affect the connection character sets:

@example
SET NAMES '@var{charset_name}'
SET CHARACTER SET @var{charset_name}
@end example

@code{SET NAMES} indicates what is in the SQL statements that the client
sends. Thus, @code{SET NAMES 'cp1251'} tells the server ``future incoming
messages from this client will be in character set @code{cp1251}.'' It
also specifies the character set for results that the server sends back to
the client.  (For example, it indicates what character set column values
will have if you use a @code{SELECT} statement.)

A @code{SET NAMES '@var{x}'} statement
is equivalent to these three statements:

@example
mysql> SET character_set_client = @var{x};
mysql> SET character_set_results = @var{x};
mysql> SET character_set_connection = @var{x};
@end example

Setting @code{character_set_connection} to @code{x} also sets
@code{collation_connection} to the default collation for @code{x}.

@code{SET CHARACTER SET} is similar but sets the connection character set
and collation to be those of the default database.  A @code{SET CHARACTER SET
x} statement is equivalent to these three statements:

@example
mysql> SET character_set_client = @var{x};
mysql> SET character_set_results = @var{x};
mysql> SET collation_connection = @@@@collation_database;
@end example

When a client connects, it sends to the server the name of the character set
that it wants to use. The server sets the @code{character_set_client},
@code{character_set_results}, and @code{character_set_connection} variables
to that character set. (In effect, the server performs a @code{SET NAMES}
operation using the character set.)

With the @command{mysql} client, it is not necessary to execute @code{SET NAMES}
every time you start up if you want to use a character set different from
the default. You can add the @code{--default-character-set}  option setting
to your @command{mysql} statement line, or in your option file.  For example,
the following option file setting changes the three character set variables
set to @code{koi8r} each time you run @command{mysql}:

@example
[mysql]
default-character-set=koi8r
@end example

Example: Suppose that @code{column1} is defined as @code{CHAR(5) CHARACTER
SET latin2}.  If you do not say @code{SET NAMES} or @code{SET CHARACTER SET},
then for @code{SELECT column1 FROM t}, the server will send back all the
values for @code{column1} using the character set that the client specified
when it connected. On the other hand, if you say @code{SET NAMES 'latin1'}
or @code{SET CHARACTER SET latin1}, then just before sending results back,
the server will convert the @code{latin2} values to @code{latin1}.
Conversion may be lossy if there are characters that are not in both
character sets.

If you do not want the server to perform any conversion, set
@code{character_set_results} to @code{NULL}:

@example
mysql> SET character_set_results = NULL;
@end example

@node Charset-literal, Charset-collate, Charset-connection, Charset-defaults
@subsection Character String Literal Character Set and Collation

Every character string literal has a character set and a collation,
which may not be null.

A character string literal may have an optional character set
introducer and @code{COLLATE} clause:

@cindex introducer, string literal
@cindex string literal introducer

@example
[_@var{charset_name}]'@var{string}' [COLLATE @var{collation_name}]
@end example

Examples:
@example
SELECT '@var{string}';
SELECT _latin1'@var{string}';
SELECT _latin1'@var{string}' COLLATE latin1_danish_ci;
@end example

For the simple statement @code{SELECT '@var{string}'}, the string has the character
set and collation defined by the @code{character_set_connection} and
@code{collation_connection} system variables.

The @code{_@var{charset_name}} expression is formally called
an @emph{introducer}. It tells the parser,
``the string that is about to follow is in character set @code{X}.''
Because this has confused people in the past, we emphasize
that an introducer does not cause any conversion, it is strictly a
signal that does not change the string's value. An introducer is
also legal before standard hex literal and numeric hex literal notation
(@code{x'@var{literal}'} and @code{0x@var{nnnn}}), and before @code{?} (parameter
substitution when using prepared statements within a programming language
interface).

Examples:

@example
SELECT _latin1 x'AABBCC';
SELECT _latin1 0xAABBCC;
SELECT _latin1 ?;
@end example

MySQL determines a literal's character set and collation thus:

@itemize @bullet
@item If both @var{_X} and @code{COLLATE @var{Y}} were specified, then
character set @var{X} and collation @var{Y}
@item If @var{_X} is specified but @code{COLLATE} is not specified, then
character set @var{X} and its default collation
@item Otherwise, the character set and collation given by the
@code{character_set_connection} and @code{collation_connection} system
variables

@end itemize

Examples:

@itemize @bullet
@item
A string with @code{latin1} character set and @code{latin1_german1_ci}
collation:

@example
SELECT _latin1'M@"uller' COLLATE latin1_german1_ci;
@end example

@item
A string with @code{latin1} character set and its default collation (that is,
@code{latin1_swedish_ci}):

@example
SELECT _latin1'M@"uller';
@end example

@item
A string with the connection default character set and collation:

@example
SELECT 'M@"uller';
@end example

@end itemize

Character set introducers and the @code{COLLATE} clause are implemented
according to standard SQL specifications.

@node Charset-collate, Charset-collate-precedence, Charset-literal, Charset-defaults
@subsection Using @code{COLLATE} in SQL Statements

With the @code{COLLATE} clause, you can override whatever the default
collation is for a comparison. @code{COLLATE} may be used in
various parts of SQL statements.  Here are some examples:

@itemize @bullet

@item With @code{ORDER BY}:

@example
SELECT k
FROM t1
ORDER BY k COLLATE latin1_german2_ci;
@end example

@item With @code{AS}:

@example
SELECT k COLLATE latin1_german2_ci AS k1
FROM t1
ORDER BY k1;
@end example

@item With @code{GROUP BY}:

@example
SELECT k
FROM t1
GROUP BY k COLLATE latin1_german2_ci;
@end example

@item With aggregate functions:

@example
SELECT MAX(k COLLATE latin1_german2_ci)
FROM t1;
@end example

@item With @code{DISTINCT}:

@example
SELECT DISTINCT k COLLATE latin1_german2_ci
FROM t1;
@end example

@item With @code{WHERE}:

@example
SELECT *
FROM t1
WHERE _latin1 'M@"uller' COLLATE latin1_german2_ci = k;
@end example

@item With @code{HAVING}:

@example
SELECT k
FROM t1
GROUP BY k
HAVING k = _latin1 'M@"uller' COLLATE latin1_german2_ci;
@end example

@end itemize

@node Charset-collate-precedence, Charset-binary-op, Charset-collate, Charset-defaults
@subsection @code{COLLATE} Clause Precedence

The @code{COLLATE} clause has high precedence (higher than @code{||}),
so the following two expressions are equivalent:

@example
x || y COLLATE z
x || (y COLLATE z)
@end example


@node Charset-binary-op, Charset-collate-tricky, Charset-collate-precedence, Charset-defaults
@subsection @code{BINARY} Operator

The @code{BINARY} operator is a shorthand for a @code{COLLATE} clause.
@code{BINARY 'x'} is equivalent to @code{'x' COLLATE y}, where @code{y} is
the name of the binary collation for the character set of @code{'x'}.  Every
character set has a binary collation.  For example, the binary collation for
the @code{latin1} character set is @code{latin1_bin}, so if the column
@code{a} is of character set @code{latin1}, the following two statements have
the same effect:

@example
SELECT * FROM t1 ORDER BY BINARY a;
SELECT * FROM t1 ORDER BY a COLLATE latin1_bin;
@end example

@node Charset-collate-tricky, Charset-collation-charset, Charset-binary-op, Charset-defaults
@subsection Some Special Cases Where the Collation Determination Is Tricky

In the great majority of queries, it is obvious what collation
MySQL uses to resolve a comparison operation. For example, in the
following cases, it should be clear that the collation will be ``the
column collation of column @code{x}'':

@example
SELECT x FROM T ORDER BY x;
SELECT x FROM T WHERE x = x;
SELECT DISTINCT x FROM T;
@end example

However, when multiple operands are involved, there can be
ambiguity. For example:

@example
SELECT x FROM T WHERE x = 'Y';
@end example

Should this query use the collation of the column @code{x}, or of the
string literal @code{'Y'}?

Standard SQL resolves such questions using what used to be
called ``coercibility'' rules. The essence is: Because @code{x} and @code{'Y'}
both have collations, whose collation takes precedence? It's complex,
but the following rules take care of most situations:

@itemize @bullet

@item An explicit @code{COLLATE} clause has a coercibility of 0.
(Not coercible at all.)

@item A concatenation of two strings with different collations has
a coercibility of 1.

@item A column's collation has a coercibility of 2.

@item A literal's collation has a coercibility of 3.

@end itemize

Those rules resolve ambiguities thus:

@itemize @bullet

@item Use the collation with the lowest coercibility value.

@item If both sides have the same coercibility, then it is an error if
the collations aren't the same.

@end itemize

Examples:

@multitable @columnfractions .5 .5

@item @code{column1 = 'A'} @tab Use collation of @code{column1}
@item @code{column1 = 'A' COLLATE x} @tab Use collation of @code{'A'}
@item @code{column1 COLLATE x = 'A' COLLATE y} @tab Error

@end multitable

The @code{COERCIBILITY()} function can be used to determine the coercibility
of a string expression:

@example
mysql> SELECT COERCIBILITY('A' COLLATE latin1_swedish_ci);
        -> 0
mysql> SELECT COERCIBILITY('A');
        -> 3
@end example

@xref{Information functions}.


@node Charset-collation-charset, Charset-collation-effect, Charset-collate-tricky, Charset-defaults
@subsection Collations Must Be for the Right Character Set

Recall that each character set has one or more
collations, and each collation is associated with one and only one
character set. Therefore, the following statement
causes an error message because the @code{latin2_bin} collation is not
legal with the @code{latin1} character set:

@example
mysql> SELECT _latin1 'x' COLLATE latin2_bin;
ERROR 1251: COLLATION 'latin2_bin' is not valid
for CHARACTER SET 'latin1'
@end example

In some cases, expressions that worked before MySQL 4.1 fail as of MySQL 4.1
if you do not take character set and collation into account. For example,
before 4.1, this statement works as is:

@example
mysql> SELECT SUBSTRING_INDEX(USER(),'@@',1);
+-------------------------------+
| SUBSTRING_INDEX(USER(),'@@',1) |
+-------------------------------+
| root                          |
+-------------------------------+
@end example

After an upgrade to MySQL 4.1, the statement fails:

@example
mysql> SELECT SUBSTRING_INDEX(USER(),'@@',1);
ERROR 1267 (HY000): Illegal mix of collations
(utf8_general_ci,IMPLICIT) and (latin1_swedish_ci,COERCIBLE)
for operation 'substr_index'
@end example

The reason this occurs is that usernames are stored using UTF8
(@pxref{Charset-metadata}). As a result, the @code{USER()} function and
the literal string @code{'@@'} have different character sets (and thus
different collations):

@example
mysql> SELECT COLLATION(USER()), COLLATION('@@');
+-------------------+-------------------+
| COLLATION(USER()) | COLLATION('@@')    |
+-------------------+-------------------+
| utf8_general_ci   | latin1_swedish_ci |
+-------------------+-------------------+
@end example

One way to deal with this is to tell MySQL to interpret the literal
string as @code{utf8}:

@example
mysql> SELECT SUBSTRING_INDEX(USER(),_utf8'@@',1);
+------------------------------------+
| SUBSTRING_INDEX(USER(),_utf8'@@',1) |
+------------------------------------+
| root                               |
+------------------------------------+
@end example

Another way is to change the connection character set and collation to
@code{utf8}. You can do that with @code{SET NAMES 'utf8'} or by setting
the @code{character_set_connection} and @code{collation_connection} system
variables directly.


@node Charset-collation-effect,  , Charset-collation-charset, Charset-defaults
@subsection An Example of the Effect of Collation

Suppose that column @code{X} in table @code{T} has these @code{latin1} column values:

@example
Muffler
M@"uller
MX Systems
MySQL
@end example

And suppose that the column values are retrieved using the following
statement:

@example
SELECT X FROM T ORDER BY X COLLATE @var{collation_name};
@end example

The resulting order of the values for different collations is shown in this
table:

@multitable @columnfractions .30 .30 .30
@item @code{latin1_swedish_ci} @tab @code{latin1_german1_ci} @tab @code{latin1_german2_ci}
@item Muffler @tab Muffler @tab M@"uller
@item MX Systems @tab M@"uller @tab Muffler
@item M@"uller @tab MX Systems @tab MX Systems
@item MySQL @tab MySQL @tab MySQL
@end multitable

The table is an example that shows what the effect would
be if we used different collations in an @code{ORDER BY} clause. The
character that causes the different sort orders in this example is the U with
two dots over it, which the Germans call U-umlaut, but we'll call
it U-diaeresis.

@itemize @bullet

@item
The first column shows the result of the @code{SELECT} using the
Swedish/Finnish collating rule, which says that U-diaeresis sorts
with Y.

@item
The second column shows the result of the @code{SELECT} using the
German DIN-1 rule, which says that U-diaeresis sorts with U.

@item
The third column shows the result of the @code{SELECT} using the German
DIN-2 rule, which says that U-diaeresis sorts with UE.

@end itemize

Three different collations, three different results. That's what
MySQL is here to handle. By using the appropriate collation, you can choose
the sort order you want.


@node Charset-operations, Charset-Unicode, Charset-defaults, Charset
@section Operations Affected by Character Set Support

@menu
* Charset-result::              Result Strings
* Charset-CONVERT::             @code{CONVERT()}
* Charset-CAST::                @code{CAST()}
* Charset-SHOW::                @code{SHOW} Statements
@end menu

This section describes operations that take character set information
into account as of MySQL 4.1.

@node Charset-result, Charset-CONVERT, Charset-operations, Charset-operations
@subsection Result Strings

MySQL has many operators and functions that return a string.
This section answers the question: What is the character set
and collation of such a string?

For simple functions that take string input and return a string result as
output, the output's character set and collation are the same as those of
the principal input value. For example, @code{UPPER(@var{X})} returns a string
whose character string and collation are the same as that of @var{X}.
The same applies for
@code{INSTR()},
@code{LCASE()},
@code{LOWER()},
@code{LTRIM()},
@code{MID()},
@code{REPEAT()},
@code{REPLACE()},
@code{REVERSE()},
@code{RIGHT()},
@code{RPAD()},
@code{RTRIM()},
@code{SOUNDEX()},
@code{SUBSTRING()},
@code{TRIM()},
@code{UCASE()}, and
@code{UPPER()}.
(Also note: The @code{REPLACE()} function, unlike all other functions,
ignores the collation of the string input and performs a
case-insensitive comparison every time.)

For operations that combine multiple string inputs and return a
single string output, the ``aggregation rules'' of standard SQL apply:

@itemize @bullet
@item If an explicit @code{COLLATE X} occurs, then use @code{X}
@item If an explicit @code{COLLATE X} and @code{COLLATE Y} occur, then error
@item Otherwise, if all collations are @code{X}, then use @code{X}
@item Otherwise, the result has no collation

@end itemize

For example, with @code{CASE ... WHEN a THEN b WHEN b THEN c COLLATE X
END}, the resultant collation is @code{X}. The same applies for
@code{CASE},
@code{UNION},
@code{||},
@code{CONCAT()},
@code{ELT()},
@code{GREATEST()},
@code{IF()}, and
@code{LEAST()}.

For operations that convert to character data, the character set and
collation of the strings that result from the operations are defined by the
@code{character_set_connection} and @code{collation_connection} system
variables.  This applies for
@code{CAST()},
@code{CHAR()},
@code{CONV()},
@code{FORMAT()},
@code{HEX()}, and
@code{SPACE()}.

@node Charset-CONVERT, Charset-CAST, Charset-result, Charset-operations
@subsection @code{CONVERT()}

@code{CONVERT()} provides a way to convert data between different
character sets. The syntax is:

@example
CONVERT(@var{expr} USING @var{transcoding_name})
@end example

In MySQL, transcoding names are the same as the
corresponding character set names.

Examples:

@example
SELECT CONVERT(_latin1'M@"uller' USING utf8);
INSERT INTO utf8table (utf8column)
    SELECT CONVERT(latin1field USING utf8) FROM latin1table;
@end example

@code{CONVERT(... USING ...)} is implemented according to the standard SQL
specification.

@node Charset-CAST, Charset-SHOW, Charset-CONVERT, Charset-operations
@subsection @code{CAST()}

You may also use @code{CAST()} to convert a string to a different character
set. The syntax is:

@example
CAST(@var{character_string} AS @var{character_data_type} CHARACTER SET @var{charset_name})
@end example

Example:

@example
SELECT CAST(_latin1'test' AS CHAR CHARACTER SET utf8);
@end example

If you use @code{CAST()} without specifying @code{CHARACTER SET},
the resulting character set and collation are defined by the
@code{character_set_connection} and @code{collation_connection} system
variables.  If you use @code{CAST()} with @code{CHARACTER SET X}, then
the resulting character set and collation are @code{X} and the default
collation of @code{X}.

You may not use a @code{COLLATE} clause inside a @code{CAST()}, but you may use
it outside. That is, @code{CAST(... COLLATE ...)} is illegal, but
@code{CAST(...) COLLATE ...} is legal.

Example:

@example
SELECT CAST(_latin1'test' AS CHAR CHARACTER SET utf8) COLLATE utf8_bin;
@end example


@node Charset-SHOW,  , Charset-CAST, Charset-operations
@subsection @code{SHOW} Statements

Several @code{SHOW} statements are new or modified in MySQL 4.1 to provide
additional character set information.
@code{SHOW CHARACTER SET},
@code{SHOW COLLATION}, and
@code{SHOW CREATE DATABASE} are new.
@code{SHOW CREATE TABLE} and
@code{SHOW COLUMNS} are modified.

The @code{SHOW CHARACTER SET} command shows all available character sets.
It takes an optional @code{LIKE} clause that indicates which character set
names to match.  For example:

@example
mysql> SHOW CHARACTER SET LIKE 'latin%';
+---------+-----------------------------+-------------------+--------+
| Charset | Description                 | Default collation | Maxlen |
+---------+-----------------------------+-------------------+--------+
| latin1  | ISO 8859-1 West European    | latin1_swedish_ci |      1 |
| latin2  | ISO 8859-2 Central European | latin2_general_ci |      1 |
| latin5  | ISO 8859-9 Turkish          | latin5_turkish_ci |      1 |
| latin7  | ISO 8859-13 Baltic          | latin7_general_ci |      1 |
+---------+-----------------------------+-------------------+--------+
@end example

@xref{SHOW CHARACTER SET,  , @code{SHOW CHARACTER SET}}.

The output from @code{SHOW COLLATION} includes all available character
sets.
It takes an optional @code{LIKE} clause that indicates which collation
names to match.  For example:

@example
mysql> SHOW COLLATION LIKE 'latin1%';
+-------------------+---------+----+---------+----------+---------+
| Collation         | Charset | Id | Default | Compiled | Sortlen |
+-------------------+---------+----+---------+----------+---------+
| latin1_german1_ci | latin1  |  5 |         |          |       0 |
| latin1_swedish_ci | latin1  |  8 | Yes     | Yes      |       0 |
| latin1_danish_ci  | latin1  | 15 |         |          |       0 |
| latin1_german2_ci | latin1  | 31 |         | Yes      |       2 |
| latin1_bin        | latin1  | 47 |         | Yes      |       0 |
| latin1_general_ci | latin1  | 48 |         |          |       0 |
| latin1_general_cs | latin1  | 49 |         |          |       0 |
| latin1_spanish_ci | latin1  | 94 |         |          |       0 |
+-------------------+---------+----+---------+----------+---------+
@end example

@xref{SHOW COLLATION,  , @code{SHOW COLLATION}}.

@code{SHOW CREATE DATABASE} displays the @code{CREATE DATABASE} statement
that will create a given database. The result includes all database
options. @code{DEFAULT CHARACTER SET} and @code{COLLATE} are supported. All
database options are stored in a text file named @file{db.opt} that can
be found in the database directory.

@example
mysql> SHOW CREATE DATABASE a\G
*************************** 1. row ***************************
       Database: a
Create Database: CREATE DATABASE `a`
                 /*!40100 DEFAULT CHARACTER SET macce */
@end example

@xref{SHOW CREATE DATABASE,  , @code{SHOW CREATE DATABASE}}.

@code{SHOW CREATE TABLE} is similar, but displays the @code{CREATE TABLE}
statement to create a given table. The column definitions now indicate any
character set specifications, and the table options include character set
information.

@xref{SHOW CREATE TABLE,  , @code{SHOW CREATE TABLE}}.

The @code{SHOW COLUMNS} statement displays the collations of a table's
columns when invoked as @code{SHOW FULL COLUMNS}.
Columns with @code{CHAR}, @code{VARCHAR}, or @code{TEXT} data types have
non-@code{NULL} collations. Numeric and other non-character types have
@code{NULL} collations. For example:

@example
mysql> SHOW FULL COLUMNS FROM t;
+-------+---------+------------+------+-----+---------+-------+
| Field | Type    | Collation  | Null | Key | Default | Extra |
+-------+---------+------------+------+-----+---------+-------+
| a     | char(1) | latin1_bin | YES  |     | NULL    |       |
| b     | int(11) | NULL       | YES  |     | NULL    |       |
+-------+---------+------------+------+-----+---------+-------+
@end example

The character set is not part of the display. (The character set name is implied by
the collation name.)

@xref{SHOW COLUMNS,  , @code{SHOW COLUMNS}}.

@node Charset-Unicode, Charset-metadata, Charset-operations, Charset
@section Unicode Support

As of MySQL version 4.1, there are two new character sets for storing 
Unicode data:

@itemize @bullet
@item
@code{ucs2}, the UCS-2 Unicode character set.
@item
@code{utf8}, the UTF8 encoding of the Unicode character set.
@end itemize

In UCS-2 (binary Unicode representation), every character is
represented by a two-byte Unicode code with the most significant
byte first. For example: "LATIN CAPITAL LETTER A" has the code
0x0041 and it's stored as a two-byte sequence: 0x00 0x41. "CYRILLIC
SMALL LETTER YERU" (Unicode 0x044B) is stored as a two-byte
sequence: 0x04 0x4B. For Unicode characters and their codes, please
refer to the @uref{http://www.unicode.org/,Unicode Home Page}.

A temporary restriction is that UCS-2 cannot yet be used as a client
character set. That means that @code{SET NAMES 'ucs2'} will not work.

The UTF8 character set (transform Unicode representation) is an
alternative way to store Unicode data. It is implemented according
to RFC2279. The idea of the UTF8 character set is that various
Unicode characters fit into byte sequences of different
lengths:

@itemize @bullet
@item Basic Latin letters, digits, and punctuation signs use one
byte.
@item Most European and Middle East script letters fit into a two-byte
sequence: extended Latin letters (with tilde, macron, acute,
grave and other accents), Cyrillic, Greek, Armenian, Hebrew,
Arabic, Syriac, and others.
@item Korean, Chinese, and Japanese ideographs use three-byte
sequences.

@end itemize

Currently, MySQL UTF8 support does not include four-byte sequences.

Tip: To save space with UTF8, use @code{VARCHAR} instead of @code{CHAR}.
Otherwise, MySQL has to reserve 30 bytes for a @code{CHAR(10) CHARACTER
SET utf8} column, because that's the maximum possible length.


@node Charset-metadata, Charset-compatibility, Charset-Unicode, Charset
@section UTF8 for Metadata

The metadata is the data about the data. Anything that
describes the database, as opposed to being the contents of the
database, is metadata. Thus column names, database names,
usernames, version names, and most of the string results from @code{SHOW} are
metadata.

Representation of metadata must satisfy these requirements:

@itemize @bullet

@item
All metadata must be in the same character set. Otherwise, @code{SHOW}
wouldn't work properly because different rows in the same column would be
in different character sets.

@item
Metadata must include all characters in all languages. Otherwise, users
wouldn't be able to name columns and tables in their own languages.

@end itemize

In order to satisfy both requirements, MySQL stores metadata in a Unicode
character set, namely UTF8. This will not cause any disruption if you never
use accented characters. But if you do, you should be aware that metadata
is in UTF8.

This means that the @code{USER()}, @code{CURRENT_USER()}, and @code{VERSION()}
functions will have the UTF8 character set by default.  So will any
synonyms, such the @code{SESSION_USER()} and @code{SYSTEM_USER()} synonyms
for @code{USER()}.

The server sets the @code{character_set_system} system variable to the
name of the metadata character set:

@example
mysql> SHOW VARIABLES LIKE 'character_set_system';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| character_set_system | utf8  |
+----------------------+-------+
@end example

Storage of metadata using Unicode does @emph{not} mean that the headers
of columns and the results of @code{DESCRIBE} functions will be in the
@code{character_set_system} character set by default.  When you say
@code{SELECT column1 FROM t}, the name @code{column1} itself will be
returned from the server to the client in the character set as determined
by the @code{SET NAMES} statement. More specifically, the character
set used is determined by the value of the @code{character_set_results}
system variable. If this variable is set to @code{NULL}, no conversion is
performed and the server returns metadata using its original character set
(the set indicated by @code{character_set_system}).

If you want the server to pass metadata results back in a
non-UTF8 character set, then use @code{SET NAMES} to force the
server to perform character set conversion (@pxref{Charset-connection}),
or else set the client to do the conversion. It is
always more efficient to set the client to do the conversion, but
this option will not be available for many clients until late in
the MySQL 4.x product cycle.

If you are just using, for example, the @code{USER()} function for
comparison or assignment within a single statement, don't worry.
MySQL will do some automatic conversion for you.

@example
SELECT * FROM Table1 WHERE USER() = latin1_column;
@end example

This will work because the contents of @code{latin1_column} are
automatically converted to UTF8 before the comparison.

@example
INSERT INTO Table1 (latin1_column) SELECT USER();
@end example

This will work because the contents of @code{USER()} are automatically
converted to @code{latin1} before the assignment.
Automatic conversion is not fully implemented yet, but should work
correctly in a later version.


Although automatic conversion is not in the SQL standard, the
SQL standard document does say that every character set is (in
terms of supported characters) a ``subset'' of Unicode. Since it is a
well-known principle that ``what applies to a superset can apply to
a subset,'' we believe that a collation for Unicode can apply for
comparisons with non-Unicode strings.


@c VERSION 4.1.1 NOTE: The @file{errmsg.txt} files will all be in UTF8
@c after this point. Conversion to the client character set will be
@c automatic, as for metadata. Also: We may change the default
@c behavior for passing back result set metadata in the near
@c future.

@node Charset-compatibility, Charset-config-file, Charset-metadata, Charset
@section Compatibility with Other DBMSs

For MaxDB compatibility these two statements are the same:

@example
CREATE TABLE t1 (f1 CHAR(@var{n}) UNICODE);
CREATE TABLE t1 (f1 CHAR(@var{n}) CHARACTER SET ucs2);
@end example


@node Charset-config-file, Charset-national, Charset-compatibility, Charset
@section New Character Set Configuration File Format

In MySQL 4.1, character set configuration is stored in XML
files, one file per character set. In previous versions, this information
was stored in @file{.conf} files.

@node Charset-national, Charset-upgrading, Charset-config-file, Charset
@section National Character Set

Before MySQL 4.1, @code{NCHAR} and @code{CHAR} were synonymous. ANSI
defines @code{NCHAR} or @code{NATIONAL CHAR} as a way to indicate that a
@code{CHAR}
column should use some predefined character set. MySQL 4.1 and up uses @code{utf8} as
that predefined character set. For example, these column type declarations
are equivalent:

@example
CHAR(10) CHARACTER SET utf8
NATIONAL CHARACTER(10)
NCHAR(10)
@end example

As are these:

@example
VARCHAR(10) CHARACTER SET utf8
NATIONAL VARCHAR(10)
NCHAR VARCHAR(10)
NATIONAL CHARACTER VARYING(10)
NATIONAL CHAR VARYING(10)
@end example

You can use @code{N'@var{literal}'} to create a string in
the national character set.
These two statements are equivalent:

@example
SELECT N'some text';
SELECT _utf8'some text';
@end example


@node Charset-upgrading, Charset-charsets, Charset-national, Charset
@section Upgrading Character Sets from MySQL 4.0

@menu
* Charset-map::                 4.0 Character Sets and Corresponding 4.1 Character Set/Collation Pairs 
* Charset-conversion::          Converting 4.0 Character Columns to 4.1 Format
@end menu

Now, what about upgrading from older versions of MySQL? MySQL 4.1
is almost upward compatible with MySQL 4.0 and earlier for the
simple reason that almost all the features are new, so there's
nothing in earlier versions to conflict with. However, there are
some differences and a few things to be aware of.

Most important: The ``MySQL 4.0 character set'' has the properties
of both ``MySQL 4.1 character sets'' and ``MySQL 4.1 collations.'' You
will have to unlearn this. Henceforth, we will not bundle character
set/collation properties in the same conglomerate object.

There is a special treatment of national character sets in MySQL
4.1. @code{NCHAR} is not the same as @code{CHAR}, and @code{N'...'} literals
are not the same as @code{'...'} literals.

Finally, there is a different file format for storing information
about character sets and collations. Make sure that you have reinstalled the
@file{/share/mysql/charsets/} directory containing the new configuration files.

If you want to start @command{mysqld} from a 4.1.x distribution with data
created by MySQL 4.0, you should start the server with the same
character set and collation. In this case, you won't need to reindex
your data.

There are two ways to do so:

@example
shell> ./configure --with-charset=... --with-collation=...
shell> ./mysqld --default-character-set=... --default-collation=...
@end example

If you used @command{mysqld} with, for example, the MySQL 4.0 @code{danish}
character set, you should now use the @code{latin1} character set and
the @code{latin1_danish_ci} collation:

@example
shell> ./configure --with-charset=latin1 \
           --with-collation=latin1_danish_ci
shell> ./mysqld --default-character-set=latin1 \
           --default-collation=latin1_danish_ci
@end example

Use the table shown in @ref{Charset-map} to find old 4.0 character set
names and their 4.1 character set/collation pair equivalents.

If you have non-@code{latin1} data stored in a 4.0 @code{latin1} table
and want to convert the table column definitions to reflect the actual
character set of the data, use the instructions in @ref{Charset-conversion}.


@node Charset-map, Charset-conversion, Charset-upgrading, Charset-upgrading
@subsection 4.0 Character Sets and Corresponding 4.1 Character Set/Collation Pairs 

@multitable @columnfractions .10 .25 .25 .35
@item @strong{ID} @tab @strong{4.0 Character Set} @tab @strong{4.1 Character Set} @tab @strong{4.1 Collation}
@item 1 @tab @code{big5} @tab @code{big5} @tab @code{big5_chinese_ci}
@item 2 @tab @code{czech} @tab @code{latin2} @tab @code{latin2_czech_ci}
@item 3 @tab @code{dec8} @tab @code{dec8} @tab @code{dec8_swedish_ci}
@item 4 @tab @code{dos} @tab @code{cp850} @tab @code{cp850_general_ci}
@item 5 @tab @code{german1} @tab @code{latin1} @tab @code{latin1_german1_ci}
@item 6 @tab @code{hp8} @tab @code{hp8} @tab @code{hp8_english_ci}
@item 7 @tab @code{koi8_ru} @tab @code{koi8r} @tab @code{koi8r_general_ci}
@item 8 @tab @code{latin1} @tab @code{latin1} @tab @code{latin1_swedish_ci}
@item 9 @tab @code{latin2} @tab @code{latin2} @tab @code{latin2_general_ci}
@item 10 @tab @code{swe7} @tab @code{swe7} @tab @code{swe7_swedish_ci}
@item 11 @tab @code{usa7} @tab @code{ascii} @tab @code{ascii_general_ci}
@item 12 @tab @code{ujis} @tab @code{ujis} @tab @code{ujis_japanese_ci}
@item 13 @tab @code{sjis} @tab @code{sjis} @tab @code{sjis_japanese_ci}
@item 14 @tab @code{cp1251} @tab @code{cp1251} @tab @code{cp1251_bulgarian_ci}
@item 15 @tab @code{danish} @tab @code{latin1} @tab @code{latin1_danish_ci}
@item 16 @tab @code{hebrew} @tab @code{hebrew} @tab @code{hebrew_general_ci}
@item 17 @tab @code{win1251} @tab @code{(removed)} @tab @code{(removed)}
@item 18 @tab @code{tis620} @tab @code{tis620} @tab @code{tis620_thai_ci}
@item 19 @tab @code{euc_kr} @tab @code{euckr} @tab @code{euckr_korean_ci}
@item 20 @tab @code{estonia} @tab @code{latin7} @tab @code{latin7_estonian_ci}
@item 21 @tab @code{hungarian} @tab @code{latin2} @tab @code{latin2_hungarian_ci}
@item 22 @tab @code{koi8_ukr} @tab @code{koi8u} @tab @code{koi8u_ukrainian_ci}
@item 23 @tab @code{win1251ukr} @tab @code{cp1251} @tab @code{cp1251_ukrainian_ci}
@item 24 @tab @code{gb2312} @tab @code{gb2312} @tab @code{gb2312_chinese_ci}
@item 25 @tab @code{greek} @tab @code{greek} @tab @code{greek_general_ci}
@item 26 @tab @code{win1250} @tab @code{cp1250} @tab @code{cp1250_general_ci}
@item 27 @tab @code{croat} @tab @code{latin2} @tab @code{latin2_croatian_ci}
@item 28 @tab @code{gbk} @tab @code{gbk} @tab @code{gbk_chinese_ci}
@item 29 @tab @code{cp1257} @tab @code{cp1257} @tab @code{cp1257_lithuanian_ci}
@item 30 @tab @code{latin5} @tab @code{latin5} @tab @code{latin5_turkish_ci}
@item 31 @tab @code{latin1_de} @tab @code{latin1} @tab @code{latin1_german2_ci}
@end multitable


@node Charset-conversion,  , Charset-map, Charset-upgrading
@subsection Converting 4.0 Character Columns to 4.1 Format

Normally, the server runs using the @code{latin1} character set by default.
If you have been storing column data that actually is in some other
character set that the 4.1 server now supports directly, you can convert the
column.  However, you should avoid trying to convert directly from
@code{latin1} to the "real" character set. This may result in data loss.
Instead, convert the column to a binary column type, and then from the
binary type to a non-binary type with the desired character set.  Conversion
to and from binary involves no attempt at character value conversion and
preserves your data intact.  For example, suppose that you have a 4.0 table with
three columns that are used to store values represented in @code{latin1},
@code{latin2}, and @code{utf8}:

@example
CREATE TABLE t
(
    latin1_col CHAR(50),
    latin2_col CHAR(100),
    utf8_col CHAR(150)
);
@end example

After upgrading to MySQL 4.1, you want to convert this table to leave
@code{latin1_col} alone but change the @code{latin2_col} and @code{utf8_col}
columns to have character sets of @code{latin2} and @code{utf8}.  First,
back up your table, then convert the columns as follows:

@example
ALTER TABLE t MODIFY latin2_col BINARY(100);
ALTER TABLE t MODIFY utf8_col BINARY(150);
ALTER TABLE t MODIFY latin2_col CHAR(100) CHARACTER SET latin2;
ALTER TABLE t MODIFY utf8_col CHAR(150) CHARACTER SET utf8;
@end example

The first two statements ``remove'' the character set information from the
@code{latin2_col} and @code{utf8_col} columns.  The second two statements
assign the proper character sets to the two columns.

If you like, you can combine the to-binary conversions and from-binary
conversions into single statements:

@example
ALTER TABLE t
    MODIFY latin2_col BINARY(100),
    MODIFY utf8_col BINARY(150);
ALTER TABLE t
    MODIFY latin2_col CHAR(100) CHARACTER SET latin2,
    MODIFY utf8_col CHAR(150) CHARACTER SET utf8;
@end example


@node Charset-charsets,  , Charset-upgrading, Charset
@section Character Sets and Collations That MySQL Supports

@menu
* Charset-Unicode-sets::        Unicode Character Sets
* Charset-we-sets::             West European Character Sets
* Charset-ce-sets::             Central European Character Sets
* Charset-se-me-sets::          South European and Middle East Character Sets
* Charset-baltic-sets::         Baltic Character Sets
* Charset-cyrillic-sets::       Cyrillic Character Sets
* Charset-asian-sets::          Asian Character Sets
@end menu

Here is an annotated list of character sets and collations that
MySQL supports. Because options and installation settings differ,
some sites might not have all items listed, and some sites might
have items not listed.

MySQL supports 70+ collations for 30+ character sets. The character sets and
their default collations are displayed by the
@code{SHOW CHARACTER SET STATEMENT}.
(The output actually includes another column that is not shown so that the
example fits better on the page.)

@c NOTE: If you rerun the following command, trim off the Maxlen column.
@c Otherwise, the lines are too long to fit nicely on the page.


@example
mysql> SHOW CHARACTER SET;
+----------+-----------------------------+---------------------+
| Charset  | Description                 | Default collation   |
+----------+-----------------------------+---------------------+
| big5     | Big5 Traditional Chinese    | big5_chinese_ci     |
| dec8     | DEC West European           | dec8_swedish_ci     |
| cp850    | DOS West European           | cp850_general_ci    |
| hp8      | HP West European            | hp8_english_ci      |
| koi8r    | KOI8-R Relcom Russian       | koi8r_general_ci    |
| latin1   | ISO 8859-1 West European    | latin1_swedish_ci   |
| latin2   | ISO 8859-2 Central European | latin2_general_ci   |
| swe7     | 7bit Swedish                | swe7_swedish_ci     |
| ascii    | US ASCII                    | ascii_general_ci    |
| ujis     | EUC-JP Japanese             | ujis_japanese_ci    |
| sjis     | Shift-JIS Japanese          | sjis_japanese_ci    |
| cp1251   | Windows Cyrillic            | cp1251_bulgarian_ci |
| hebrew   | ISO 8859-8 Hebrew           | hebrew_general_ci   |
| tis620   | TIS620 Thai                 | tis620_thai_ci      |
| euckr    | EUC-KR Korean               | euckr_korean_ci     |
| koi8u    | KOI8-U Ukrainian            | koi8u_general_ci    |
| gb2312   | GB2312 Simplified Chinese   | gb2312_chinese_ci   |
| greek    | ISO 8859-7 Greek            | greek_general_ci    |
| cp1250   | Windows Central European    | cp1250_general_ci   |
| gbk      | GBK Simplified Chinese      | gbk_chinese_ci      |
| latin5   | ISO 8859-9 Turkish          | latin5_turkish_ci   |
| armscii8 | ARMSCII-8 Armenian          | armscii8_general_ci |
| utf8     | UTF-8 Unicode               | utf8_general_ci     |
| ucs2     | UCS-2 Unicode               | ucs2_general_ci     |
| cp866    | DOS Russian                 | cp866_general_ci    |
| keybcs2  | DOS Kamenicky Czech-Slovak  | keybcs2_general_ci  |
| macce    | Mac Central European        | macce_general_ci    |
| macroman | Mac West European           | macroman_general_ci |
| cp852    | DOS Central European        | cp852_general_ci    |
| latin7   | ISO 8859-13 Baltic          | latin7_general_ci   |
| cp1256   | Windows Arabic              | cp1256_general_ci   |
| cp1257   | Windows Baltic              | cp1257_general_ci   |
| binary   | Binary pseudo charset       | binary              |
| geostd8  | GEOSTD8 Georgian            | geostd8_general_ci  |
+----------+-----------------------------+---------------------+
@end example


@node Charset-Unicode-sets, Charset-we-sets, Charset-charsets, Charset-charsets
@subsection Unicode Character Sets

MySQL has two Unicode character sets. You can store
texts in about 650 languages using these character sets. We have
added several collations for these two new sets, with more to come.

@c Currently, the @code{ucs2_unicode_ci} collation has only partial support
@c for the Unicode Collation Algorithm. Some characters are not supported yet.

@itemize @bullet
@item @code{ucs2} (UCS-2 Unicode) collations:
@itemize
@item @code{ucs2_bin}
@item @code{ucs2_czech_ci}
@item @code{ucs2_danish_ci}
@item @code{ucs2_estonian_ci}
@item @code{ucs2_general_ci} (default)
@item @code{ucs2_icelandic_ci}
@item @code{ucs2_latvian_ci}
@item @code{ucs2_lithuanian_ci}
@item @code{ucs2_persian_ci}
@item @code{ucs2_polish_ci}
@item @code{ucs2_roman_ci}
@item @code{ucs2_romanian_ci}
@item @code{ucs2_slovak_ci}
@item @code{ucs2_slovenian_ci}
@item @code{ucs2_spanish2_ci}
@item @code{ucs2_spanish_ci}
@item @code{ucs2_swedish_ci}
@item @code{ucs2_turkish_ci}
@item @code{ucs2_unicode_ci}
@end itemize
@item @code{utf8} (UTF-8 Unicode) collations:
@itemize
@item @code{utf8_bin}
@item @code{utf8_czech_ci}
@item @code{utf8_danish_ci}
@item @code{utf8_estonian_ci}
@item @code{utf8_general_ci} (default)
@item @code{utf8_icelandic_ci}
@item @code{utf8_latvian_ci}
@item @code{utf8_lithuanian_ci}
@item @code{utf8_persian_ci}
@item @code{utf8_polish_ci}
@item @code{utf8_roman_ci}
@item @code{utf8_romanian_ci}
@item @code{utf8_slovak_ci}
@item @code{utf8_slovenian_ci}
@item @code{utf8_spanish2_ci}
@item @code{utf8_spanish_ci}
@item @code{utf8_swedish_ci}
@item @code{utf8_turkish_ci}
@item @code{utf8_unicode_ci}
@end itemize
@end itemize


@node Charset-we-sets, Charset-ce-sets, Charset-Unicode-sets, Charset-charsets
@subsection West European Character Sets

West European Character Sets cover most West European languages,
such as French, Spanish, Catalan, Basque, Portuguese, Italian,
Albanian, Dutch, German, Danish, Swedish, Norwegian, Finnish,
Faroese, Icelandic, Irish, Scottish, and English.

@itemize @bullet

@item @code{ascii} (US ASCII) collations:
@itemize
@item @code{ascii_bin}
@item @code{ascii_general_ci} (default)
@end itemize

@item @code{cp850} (DOS West European) collations:
@itemize
@item @code{cp850_bin}
@item @code{cp850_general_ci} (default)
@end itemize

@item @code{dec8} (DEC West European) collations:
@itemize
@item @code{dec8_bin}
@item @code{dec8_swedish_ci} (default)
@end itemize

@item @code{hp8} (HP West European) collations:
@itemize
@item @code{hp8_bin}
@item @code{hp8_english_ci} (default)
@end itemize

@item @code{latin1} (ISO 8859-1 West European) collations:
@itemize
@item @code{latin1_bin}
@item @code{latin1_danish_ci}
@item @code{latin1_general_ci}
@item @code{latin1_general_cs}
@item @code{latin1_german1_ci}
@item @code{latin1_german2_ci}
@item @code{latin1_spanish_ci}
@item @code{latin1_swedish_ci} (default)
@end itemize

The @code{latin1} is the default character set.
The @code{latin1_swedish_ci} collation is the default that probably is
used by the majority of MySQL customers. It is constantly stated
that this is based on the Swedish/Finnish collation rules, but you
will find Swedes and Finns who disagree with that statement.

The @code{latin1_german1_ci} and @code{latin1_german2_ci}
collations are based on the DIN-1 and DIN-2 standards,
where DIN stands for Deutsches Institut f@"ur Normung (that is,
the German answer to ANSI).
DIN-1 is called the dictionary collation and DIN-2 is called the
phone-book collation.

@itemize @bullet

@item @code{latin1_german1_ci} (dictionary) rules:

@example
@"A = A
@"O = O
@"U = U
@ss{} = s
@end example

@item @code{latin1_german2_ci} (phone-book) rules:

@example
@"A = AE
@"O = OE
@"U = UE
@ss{} = ss
@end example

@end itemize

In the @code{latin1_spanish_ci} collation, @samp{@~N} (N-tilde) is a
separate letter between @samp{N} and @samp{O}.

@item @code{macroman} (Mac West European) collations:
@itemize
@item @code{macroman_bin}
@item @code{macroman_general_ci} (default)
@end itemize

@item @code{swe7} (7bit Swedish) collations:
@itemize
@item @code{swe7_bin}
@item @code{swe7_swedish_ci} (default)
@end itemize

@end itemize


@node Charset-ce-sets, Charset-se-me-sets, Charset-we-sets, Charset-charsets
@subsection Central European Character Sets

We have some support for character sets used in the Czech Republic,
Slovakia, Hungary, Romania, Slovenia, Croatia, and Poland.

@itemize @bullet

@item @code{cp1250} (Windows Central European) collations:
@itemize
@item @code{cp1250_bin}
@item @code{cp1250_czech_ci}
@item @code{cp1250_general_ci} (default)
@end itemize

@item @code{cp852} (DOS Central European) collations:
@itemize
@item @code{cp852_bin}
@item @code{cp852_general_ci} (default)
@end itemize

@item @code{keybcs2} (DOS Kamenicky Czech-Slovak) collations:
@itemize
@item @code{keybcs2_bin}
@item @code{keybcs2_general_ci} (default)
@end itemize

@item @code{latin2} (ISO 8859-2 Central European) collations:
@itemize
@item @code{latin2_bin}
@item @code{latin2_croatian_ci}
@item @code{latin2_czech_ci}
@item @code{latin2_general_ci} (default)
@item @code{latin2_hungarian_ci}
@end itemize

@item @code{macce} (Mac Central European) collations:
@itemize
@item @code{macce_bin}
@item @code{macce_general_ci} (default)
@end itemize

@end itemize


@node Charset-se-me-sets, Charset-baltic-sets, Charset-ce-sets, Charset-charsets
@subsection South European and Middle East Character Sets

@itemize @bullet

@item @code{armscii8} (ARMSCII-8 Armenian) collations:
@itemize
@item @code{armscii8_bin}
@item @code{armscii8_general_ci} (default)
@end itemize

@item @code{cp1256} (Windows Arabic) collations:
@itemize
@item @code{cp1256_bin}
@item @code{cp1256_general_ci} (default)
@end itemize

@item @code{geostd8} (GEOSTD8 Georgian) collations:
@itemize
@item @code{geostd8_bin}
@item @code{geostd8_general_ci} (default)
@end itemize

@item @code{greek} (ISO 8859-7 Greek) collations:
@itemize
@item @code{greek_bin}
@item @code{greek_general_ci} (default)
@end itemize

@item @code{hebrew} (ISO 8859-8 Hebrew) collations:
@itemize
@item @code{hebrew_bin}
@item @code{hebrew_general_ci} (default)
@end itemize

@item @code{latin5} (ISO 8859-9 Turkish) collations:
@itemize
@item @code{latin5_bin}
@item @code{latin5_turkish_ci} (default)
@end itemize

@end itemize


@node Charset-baltic-sets, Charset-cyrillic-sets, Charset-se-me-sets, Charset-charsets
@subsection Baltic Character Sets

The Baltic character sets cover Estonian, Latvian, and Lithuanian
languages. There are two Baltic character sets currently supported:

@itemize @bullet

@item @code{cp1257} (Windows Baltic) collations:
@itemize
@item @code{cp1257_bin}
@item @code{cp1257_general_ci} (default)
@item @code{cp1257_lithuanian_ci}
@end itemize

@item @code{latin7} (ISO 8859-13 Baltic) collations:
@itemize
@item @code{latin7_bin}
@item @code{latin7_estonian_cs}
@item @code{latin7_general_ci} (default)
@item @code{latin7_general_cs}
@end itemize

@end itemize


@node Charset-cyrillic-sets, Charset-asian-sets, Charset-baltic-sets, Charset-charsets
@subsection Cyrillic Character Sets

Here are the Cyrillic character sets and collations for use with
Belarusian, Bulgarian, Russian, and Ukrainian languages.

@c -- It might seem
@c odd that we seem to have a general Cyrillic collation which is
@c supposed to fit all the Cyrillic alphabets except Ukrainian, and one
@c for Ukrainian. The difference only comes up for one character, the
@c soft sign.--

@itemize @bullet

@item @code{cp1251} (Windows Cyrillic) collations:
@itemize
@item @code{cp1251_bin}
@item @code{cp1251_bulgarian_ci}
@item @code{cp1251_general_ci} (default)
@item @code{cp1251_general_cs}
@item @code{cp1251_ukrainian_ci}
@end itemize

@item @code{cp866} (DOS Russian) collations:
@itemize
@item @code{cp866_bin}
@item @code{cp866_general_ci} (default)
@end itemize

@item @code{koi8r} (KOI8-R Relcom Russian) collations:
@itemize
@item @code{koi8r_bin}
@item @code{koi8r_general_ci} (default)
@end itemize

@item @code{koi8u} (KOI8-U Ukrainian) collations:
@itemize
@item @code{koi8u_bin}
@item @code{koi8u_general_ci} (default)
@end itemize

@end itemize


@node Charset-asian-sets,  , Charset-cyrillic-sets, Charset-charsets
@subsection Asian Character Sets

The Asian character sets that we support include Chinese, Japanese,
Korean, and Thai. These can be complicated. For example, the Chinese
sets must allow for thousands of different characters.

@itemize @bullet

@item @code{big5} (Big5 Traditional Chinese) collations:
@itemize
@item @code{big5_bin}
@item @code{big5_chinese_ci} (default)
@end itemize

@item @code{euckr} (EUC-KR Korean) collations:
@itemize
@item @code{euckr_bin}
@item @code{euckr_korean_ci} (default)
@end itemize

@item @code{gb2312} (GB2312 Simplified Chinese) collations:
@itemize
@item @code{gb2312_bin}
@item @code{gb2312_chinese_ci} (default)
@end itemize

@item @code{gbk} (GBK Simplified Chinese) collations:
@itemize
@item @code{gbk_bin}
@item @code{gbk_chinese_ci} (default)
@end itemize

@item @code{sjis} (Shift-JIS Japanese) collations:
@itemize
@item @code{sjis_bin}
@item @code{sjis_japanese_ci} (default)
@end itemize

@item @code{tis620} (TIS620 Thai) collations:
@itemize
@item @code{tis620_bin}
@item @code{tis620_thai_ci} (default)
@end itemize

@item @code{ujis} (EUC-JP Japanese) collations:
@itemize
@item @code{ujis_bin}
@item @code{ujis_japanese_ci} (default)
@end itemize

@end itemize


@node Column types, Functions, Charset, Top
@chapter Column Types

@c TODO: rename to Data types; values of these types can be used independently
@c of being stored in table columns.

@menu
* Column type overview::        Column Type Overview
* Numeric types::               Numeric Types
* Date and time types::         Date and Time Types
* String types::                String Types
* Storage requirements::        Column Type Storage Requirements
* Choosing types::              Choosing the Right Type for a Column
* Other-vendor column types::   Using Column Types from Other Database Engines
@end menu

@c help_category Column Types

MySQL supports a number of column types in several categories: numeric
types, date and time types, and string (character) types.  This chapter
first gives an overview of these column types, and then provides a more
detailed description of the properties of the types in each category, and a
summary of the column type storage requirements.  The overview is
intentionally brief.  The more detailed descriptions should be consulted for
additional information about particular column types, such as the allowable
formats in which you can specify values.

MySQL versions 4.1 and up support extensions for handing spatial
data.  Information about spatial types is provided in
@ref{Spatial extensions in MySQL}.

@cindex data types
@cindex types, data
@cindex columns, types
@cindex types, columns

Several of the column type descriptions use these conventions:

@table @code
@item @var{M}
@cindex display width
@cindex widths, display
@cindex display size
@cindex sizes, display
Indicates the maximum display width.  The maximum legal display width is 255.

@item @var{D}
@cindex digits
@cindex decimal point
Applies to floating-point and fixed-point types and indicates the number of
digits following the decimal point.  The maximum possible value is 30, but
should be no greater than @var{M}@minus{}2.

@item
@cindex brackets, square
@cindex square brackets
Square brackets (@samp{[} and @samp{]}) indicate parts of type specifiers
that are optional.

@end table

@tindex Types

@node Column type overview, Numeric types, Column types, Column types
@section Column Type Overview

@menu
* Numeric type overview::       Overview of Numeric Types
* Date and time type overview::  Overview of Date and Time Types
* String type overview::        Overview of String Types
@end menu

@node Numeric type overview, Date and time type overview, Column type overview, Column type overview
@subsection Overview of Numeric Types

@c The @w{-number} stuff keeps a linebreak from occurring between
@c the - and number.

A summary of the numeric column types follows. For additional information, see
@ref{Numeric types}.
Column storage requirements are given in @ref{Storage requirements}.

@var{M} indicates the maximum display width.  The maximum legal display
width is 255.  Display width is unrelated to the storage size or range of
values a type can contain, as described in @ref{Numeric types}.

If you specify @code{ZEROFILL} for a numeric column, MySQL
automatically adds the @code{UNSIGNED} attribute to the column.

@strong{Warning:} You should be aware that when you use subtraction
between integer values where one is of type @code{UNSIGNED}, the result
will be unsigned! @xref{Cast Functions}.

@table @code
@c description_for_help_topic TINYINT  BOOLEAN BOOL BIT ZEROFILL UNSIGNED INT1
@item TINYINT[(@var{M})] [UNSIGNED] [ZEROFILL]
@tindex TINYINT

A very small integer. The signed range is @code{-128} to @code{127}. The
unsigned range is @code{0} to @code{255}.

@item BIT
@itemx BOOL
@itemx BOOLEAN
@tindex BOOLEAN
@tindex BOOL
@tindex BIT
These are synonyms for @code{TINYINT(1)}.
The @code{BOOLEAN} synonym was added in MySQL 4.1.0.
A value of zero is considered false. Non-zero values are considered true.

In the future,
full boolean type handling will be introduced in accordance with standard SQL.
@c end_description_for_help_topic

@c description_for_help_topic SMALLINT  INT2
@item SMALLINT[(@var{M})] [UNSIGNED] [ZEROFILL]
@tindex SMALLINT

A small integer. The signed range is @code{-32768} to @code{32767}. The
unsigned range is @code{0} to @code{65535}.
@c end_description_for_help_topic

@c description_for_help_topic MEDIUMINT  INT3 MIDDLEINT
@item MEDIUMINT[(@var{M})] [UNSIGNED] [ZEROFILL]
@tindex MEDIUMINT

A medium-size integer. The signed range is @code{-8388608} to
@code{8388607}. The unsigned range is @code{0} to @code{16777215}.
@c end_description_for_help_topic

@c description_for_help_topic INT  INT4 UNSIGNED ZEROFILL INTEGER
@item INT[(@var{M})] [UNSIGNED] [ZEROFILL]
@tindex INT

A normal-size integer. The signed range is @code{-2147483648} to
@code{2147483647}.  The unsigned range is @code{0} to @code{4294967295}.

@item INTEGER[(@var{M})] [UNSIGNED] [ZEROFILL]
@tindex INTEGER

This is a synonym for @code{INT}.
@c end_description_for_help_topic

@c description_for_help_topic BIGINT  UNSIGNED ZEROFILL INT8
@item BIGINT[(@var{M})] [UNSIGNED] [ZEROFILL]
@tindex BIGINT
A large integer. The signed range is @code{-9223372036854775808} to
@code{9223372036854775807}. The unsigned range is @code{0} to
@code{18446744073709551615}.
@c end_description_for_help_topic
Some things you should be aware of with respect to @code{BIGINT} columns:

@itemize @bullet
@item
@cindex rounding errors
All arithmetic is done using signed @code{BIGINT} or @code{DOUBLE}
values, so you shouldn't use unsigned big integers larger than
@code{9223372036854775807} (63 bits) except with bit functions! If you
do that, some of the last digits in the result may be wrong because of
rounding errors when converting a @code{BIGINT} value to a @code{DOUBLE}.

MySQL 4.0 can handle @code{BIGINT} in the following cases:

@itemize @bullet
@item
When using integers to store big unsigned values in a @code{BIGINT} column.
@item
In @code{MIN(@var{col_name})} or @code{MAX(@var{col_name})}, where
@var{col_name} refers to a @code{BIGINT} column.
@item
When using operators (@code{+}, @code{-}, @code{*}, and so on) where
both operands are integers.
@end itemize

@item
You can always store an exact integer value in a @code{BIGINT} column by
storing it using a string.  In this case, MySQL performs a string-to-number
conversion that involves no intermediate double-precision representation.
@item
The @code{-}, @code{+}, and @code{*} operators will use @code{BIGINT}
arithmetic when both operands are integer values!  This means that if
you multiply two big integers (or results from functions that return
integers), you may get unexpected results when the result is larger than
@code{9223372036854775807}.
@end itemize

@c description_for_help_topic FLOAT  UNSIGNED ZEROFILL FLOAT4
@item FLOAT(@var{p}) [UNSIGNED] [ZEROFILL]
@cindex floating-point number
@tindex FLOAT
@tindex FLOAT(p)

A floating-point number.  @var{p} represents the precision. It can be from
0 to 24 for a single-precision floating-point number and from 25 to 53 for a
double-precision floating-point number. These types are like the @code{FLOAT}
and @code{DOUBLE} types described immediately following.  @code{FLOAT(p)}
has the same range as the corresponding @code{FLOAT} and @code{DOUBLE}
types, but the display width and number of decimals are undefined.

As of MySQL 3.23, this is a true floating-point value.  In
earlier MySQL versions, @code{FLOAT(@var{p})} always has two decimals.

@cindex ODBC compatibility
@cindex compatibility, with ODBC
This syntax is provided for ODBC compatibility.

Using @code{FLOAT} might give you some unexpected problems because
all calculations in MySQL are done with double precision.
@xref{No matching rows}.

@item FLOAT[(@var{M},@var{D})] [UNSIGNED] [ZEROFILL]
@tindex FLOAT
@tindex FLOAT(M,D)
@tindex FLOAT(p)

A small (single-precision) floating-point number.  Allowable values are
@code{@w{-3.402823466E+38}} to @code{@w{-1.175494351E-38}}, @code{0},
and @code{@w{1.175494351E-38}} to @code{3.402823466E+38}.  If
@code{UNSIGNED} is specified, negative values are disallowed.  @var{M}
is the display width and @var{D} is the number of decimals.  @code{FLOAT}
without arguments or @code{FLOAT(@var{p})} (where @var{p} is in the range from
0 to 24) stands for a single-precision floating-point number.
@c end_description_for_help_topic

@c description_for_help_topic DOUBLE  FLOAT8 UNSIGNED ZEROFILL PRECISION REAL
@item DOUBLE[(@var{M},@var{D})] [UNSIGNED] [ZEROFILL]
@tindex DOUBLE
@tindex DOUBLE(M,D)
@tindex FLOAT(p)

A normal-size (double-precision) floating-point number.
Allowable values are @code{@w{-1.7976931348623157E+308}} to
@code{@w{-2.2250738585072014E-308}}, @code{0}, and
@code{2.2250738585072014E-308} to @code{1.7976931348623157E+308}.  If
@code{UNSIGNED} is specified, negative values are disallowed.
@var{M} is the display width and @var{D} is the number of decimals.
@code{DOUBLE} without arguments or @code{FLOAT(@var{p})} (where
@var{p} is in the
range from 25 to 53) stands for a double-precision floating-point number.

@item DOUBLE PRECISION[(@var{M},@var{D})] [UNSIGNED] [ZEROFILL]
@itemx REAL[(@var{M},@var{D})] [UNSIGNED] [ZEROFILL]
@tindex DOUBLE PRECISION
@tindex REAL

These are synonyms for @code{DOUBLE}.
Exception: If the server SQL mode includes the @code{REAL_AS_FLOAT} option,
@code{REAL} is a synonym for @code{FLOAT} rather than @code{DOUBLE}.
@c end_description_for_help_topic

@c description_for_help_topic NUMERIC  ZEROFILL UNSIGNED DECIMAL DEC FIXED
@item DECIMAL[(@var{M}[,@var{D}])] [UNSIGNED] [ZEROFILL]
@tindex DECIMAL

An unpacked fixed-point number.  Behaves like a @code{CHAR} column;
``unpacked'' means the number is stored as a string, using one character for
each digit of the value.  @var{M} is the total number of digits and
@var{D} is the number of decimals.  The decimal point and (for negative
numbers) the @samp{-} sign are not counted in @var{M}, although space for
them is reserved. If @var{D} is 0, values have no decimal point or
fractional part.  The maximum range of @code{DECIMAL} values is the same as
for @code{DOUBLE}, but the actual range for a given @code{DECIMAL} column
may be constrained by the choice of @var{M} and @var{D}.  If
@code{UNSIGNED} is specified, negative values are disallowed.

If @var{D} is omitted, the default is 0.  If @var{M} is omitted, the
default is 10.

Prior to MySQL 3.23, the @var{M} argument must be large enough to
include the space needed for the sign and the decimal point.

@item DEC[(@var{M}[,@var{D}])] [UNSIGNED] [ZEROFILL]
@itemx NUMERIC[(@var{M}[,@var{D}])] [UNSIGNED] [ZEROFILL]
@itemx FIXED[(@var{M}[,@var{D}])] [UNSIGNED] [ZEROFILL]
@tindex DEC
@tindex NUMERIC
@tindex FIXED

These are synonyms for @code{DECIMAL}.

The @code{FIXED} synonym was added in MySQL 4.1.0 for compatibility
with other servers.
@c end_description_for_help_topic

@end table

@node Date and time type overview, String type overview, Numeric type overview, Column type overview
@subsection Overview of Date and Time Types

A summary of the temporal column types follows. For additional information, see
@ref{Date and time types}.
Column storage requirements are given in @ref{Storage requirements}.

@table @code

@item DATE
@tindex DATE

@c description_for_help_topic DATE  DATE
A date.  The supported range is @code{'1000-01-01'} to @code{'9999-12-31'}.
MySQL displays @code{DATE} values in @code{'YYYY-MM-DD'} format, but
allows you to assign values to @code{DATE} columns using either strings or
numbers.
@c end_description_for_help_topic

@item DATETIME
@tindex DATETIME

@c description_for_help_topic DATETIME
A date and time combination.  The supported range is @code{'1000-01-01
00:00:00'} to @code{'9999-12-31 23:59:59'}.  MySQL displays
@code{DATETIME} values in @code{'YYYY-MM-DD HH:MM:SS'} format, but allows you
to assign values to @code{DATETIME} columns using either strings or numbers.
@c end_description_for_help_topic

@c description_for_help_topic TIMESTAMP  TIMESTAMP
@item TIMESTAMP[(@var{M})]
@tindex TIMESTAMP

A timestamp.  The range is @code{'1970-01-01 00:00:00'} to partway through the
year @code{2037}.

A @code{TIMESTAMP} column is useful for recording the date and time of an
@code{INSERT} or @code{UPDATE} operation. The first @code{TIMESTAMP} column
in a table is automatically set to the date and time of the most recent
operation if you don't assign it a value yourself.  You can also set any
@code{TIMESTAMP} column to the current date and time by assigning it a
@code{NULL} value.

From MySQL 4.1 on, @code{TIMESTAMP} is returned as a string with the format
@code{'YYYY-MM-DD HH:MM:SS'}. If you want to obtain the value as a number,
you should add @code{+0} to the timestamp column. Different timestamp
display widths are not supported.

In MySQL 4.0 and earlier, @code{TIMESTAMP} values are displayed in
@code{YYYYMMDDHHMMSS}, @code{YYMMDDHHMMSS}, @code{YYYYMMDD}, or @code{YYMMDD}
format, depending on whether @var{M} is 14 (or missing), 12,
8, or 6, but allows you to assign values to @code{TIMESTAMP}
columns using either strings or numbers.
The @var{M} argument affects only how a @code{TIMESTAMP} column is displayed,
not storage.  Its values always are stored using four bytes each.
From MySQL 4.0.12, the @code{--new} option can be used
to make the server behave as in MySQL 4.1.

Note that @code{TIMESTAMP(@var{M})} columns where @var{M} is 8 or 14 are reported to
be numbers, whereas other @code{TIMESTAMP(@var{M})} columns are reported to be
strings.  This is just to ensure that you can reliably dump and restore
the table with these types.
@c end_description_for_help_topic

@c description_for_help_topic TIME  TIME
@item TIME
@tindex TIME

A time.  The range is @code{'-838:59:59'} to @code{'838:59:59'}.
MySQL displays @code{TIME} values in @code{'HH:MM:SS'} format, but
allows you to assign values to @code{TIME} columns using either strings or
numbers.
@c end_description_for_help_topic

@c description_for_help_topic YEAR type
@item YEAR[(2|4)]
@tindex YEAR

A year in two-digit or four-digit format. The default is four-digit format.
In four-digit format, the
allowable values are @code{1901} to @code{2155}, and @code{0000}.
In two-digit format, the allowable values are
@code{70} to @code{69}, representing years from
1970 to 2069.  MySQL displays @code{YEAR} values in
@code{YYYY} format, but allows you to assign values to @code{YEAR} columns
using either strings or numbers. The @code{YEAR} type is unavailable prior
to MySQL 3.22.
@c end_description_for_help_topic

@end table

@node String type overview,  , Date and time type overview, Column type overview
@subsection Overview of String Types

A summary of the string column types follows.
For additional information, see @ref{String types}.
Column storage requirements are given in @ref{Storage requirements}.

In some cases, MySQL may change a string column to a type different from
that given in a @code{CREATE TABLE} or @code{ALTER TABLE} statement.
@xref{Silent column changes}.

A change that affects many string column types is that, as of MySQL 4.1,
character column definitions can include a @code{CHARACTER SET} attribute to
specify the character set and, optionally, a collation. This
applies to @code{CHAR}, @code{VARCHAR}, the @code{TEXT} types, @code{ENUM},
and @code{SET}. For example:

@example
CREATE TABLE t
(
    c1 CHAR(20) CHARACTER SET utf8,
    c2 CHAR(20) CHARACTER SET latin1 COLLATE latin1_bin
);
@end example

This table definition creates a column named @code{c1} that has a character
set of @code{utf8} with the default collation for that character set, and a
column named @code{c2} that has a character set of @code{latin1} and the
binary collation for the character set. The binary collation is not case
sensitive.

Character column sorting and comparison are are based on the character set
assigned to the column. Before MySQL 4.1, sorting and comparison are based
on the collation of the server character set. For @code{CHAR} and
@code{VARCHAR} columns, you can declare the column with the @code{BINARY}
attribute to cause sorting and comparison to be case sensitive using the
underlying character code values rather then a lexical ordering.

For more details, see @ref{Charset}.

Also as of 4.1, MySQL interprets length specifications in character column
definitions in characters. (Earlier versions interpret them in bytes.)

@table @code

@c description_for_help_topic CHAR  NATIONAL CHARACTER NCHAR BINARY
@c UPDATE START
@item [NATIONAL] CHAR(@var{M}) [BINARY | ASCII | UNICODE]
@c UPDATE STOP
@tindex NATIONAL CHAR
@tindex NCHAR
@tindex CHAR
@tindex CHARACTER

A fixed-length string that is always right-padded with spaces to the
specified length when stored.  @var{M} represents the column length.  The
range of @var{M} is 0 to 255 characters (1 to 255 prior to MySQL 3.23).

@strong{Note}: Trailing spaces are removed when @code{CHAR} values are
retrieved.

From MySQL 4.1.0, a @code{CHAR} column with a length specification greater
than 255 is converted to the smallest @code{TEXT} type that can hold values
of the given length.  For example, @code{CHAR(500)} is converted to
@code{TEXT}, and @code{CHAR(200000)} is converted to @code{MEDIUMTEXT}.
This is a compatibility feature.  However, this conversion causes the
column to become a variable-length column, and also affects trailing-space
removal.

@code{CHAR} is shorthand for @code{CHARACTER}.
@code{NATIONAL CHAR} (or its equivalent short form, @code{NCHAR}) is the
standard SQL way to define that a @code{CHAR} column should use the default
character set.  This is the default in MySQL.

As of MySQL 4.1.2, the @code{BINARY} attribute is shorthand for specifying
the binary collation of the column character set. Before 4.1.2, @code{BINARY}
attribute causes the column to be treated as a binary string.  In either
case, sorting and comparisons become case sensitive.

From MySQL 4.1.0 on, the @code{ASCII} attribute can be specified. It
assigns the @code{latin1} character set to a @code{CHAR} column.

From MySQL 4.1.1 on, the @code{UNICODE} attribute can be specified. It
assigns the @code{ucs2} character set to a @code{CHAR} column.

MySQL allows you to create a column of type @code{CHAR(0)}. This is mainly
useful when you have to be compliant with some old applications that depend
on the existence of a column but that do not actually use the value.  This
is also quite nice when you need a column that can take only two values: A
@code{CHAR(0)} column that is not defined as @code{NOT NULL} occupies only
one bit and can take only the values @code{NULL} and @code{''} (the empty
string).

@item CHAR
This is a synonym for @code{CHAR(1)}.
@c end_description_for_help_topic

@c description_for_help_topic VARCHAR  BINARY NATIONAL VARYING CHARACTER VARCHARACTER
@item [NATIONAL] VARCHAR(@var{M}) [BINARY]
@tindex CHARACTER VARYING
@tindex CHAR VARYING
@tindex VARCHAR
@tindex VARCHARACTER

A variable-length string.  @var{M} represents the maximum column length.
The range of @var{M} is 0 to 255 characters (1 to 255 prior to MySQL 4.0.2).

@strong{Note}: Trailing spaces are removed when @code{VARCHAR} values are
stored, which differs from the standard SQL specification.

From MySQL 4.1.0 on, a @code{VARCHAR} column with a length specification
greater than 255 is converted to the smallest @code{TEXT} type that can hold
values of the given length.  For example, @code{VARCHAR(500)} is converted
to @code{TEXT}, and @code{VARCHAR(200000)} is converted to
@code{MEDIUMTEXT}.  This is a compatibility feature.
However, this conversion affects trailing-space removal.

@code{VARCHAR} is shorthand for @code{CHARACTER VARYING}.

As of MySQL 4.1.2, the @code{BINARY} attribute is shorthand for specifying
the binary collation of the column character set. Before 4.1.2, @code{BINARY}
attribute causes the column to be treated as a binary string.  In either
case, sorting and comparisons become case sensitive.
@c end_description_for_help_topic

@c description_for_help_topic BINARY
@item BINARY(@var{M})
@tindex BINARY

The @code{BINARY} type is similar to the @code{CHAR} type, but stores
binary strings rather than non-binary strings.

This type was added in MySQL 4.1.2.
@c end_description_for_help_topic

@c description_for_help_topic VARBINARY
@item VARBINARY(@var{M})
@tindex VARBINARY

The @code{VARBINARY} type is similar to the @code{VARCHAR} type, but stores
binary strings rather than non-binary strings.

This type was added in MySQL 4.1.2.
@c end_description_for_help_topic

@c description_for_help_topic TINYBLOB  TINYTEXT
@item TINYBLOB
@itemx TINYTEXT
@tindex TINYBLOB
@tindex TINYTEXT

A @code{BLOB} or @code{TEXT} column with a maximum length of 255 (2^8
@minus{} 1)
characters.
@c end_description_for_help_topic

@c description_for_help_topic BLOB type TEXT BLOB
@item BLOB
@itemx TEXT
@tindex BLOB
@tindex TEXT

A @code{BLOB} or @code{TEXT} column with a maximum length of 65,535 (2^16
@minus{}1)
characters.
@c end_description_for_help_topic

@c description_for_help_topic MEDIUMBLOB  MEDIUMTEXT
@item MEDIUMBLOB
@itemx MEDIUMTEXT
@tindex MEDIUMBLOB
@tindex MEDIUMTEXT

A @code{BLOB} or @code{TEXT} column with a maximum length of 16,777,215
(2^24 @minus{} 1) characters.
@c end_description_for_help_topic

@c description_for_help_topic LONGBLOB  LONGTEXT LONG LONGBINARY
@item LONGBLOB
@itemx LONGTEXT
@tindex LONGBLOB
@tindex LONGTEXT

A @code{BLOB} or @code{TEXT} column with a maximum length of 4,294,967,295 or
4GB (2^32 @minus{} 1) characters.  Up to MySQL
3.23, the client/server protocol and @code{MyISAM} tables had a limit
of 16MB per communication packet / table row. From MySQL 4.0, the maximum
allowed length of @code{LONGBLOB} or @code{LONGTEXT} columns depends on the
configured maximum packet size in the client/server protocol and available
memory.
@c end_description_for_help_topic

@c description_for_help_topic ENUM
@item ENUM('@var{value1}','@var{value2}',...)
@tindex ENUM

An enumeration.  A string object that can have only one value, chosen
from the list of values @code{'@var{value1}'}, @code{'@var{value2}'}, @code{...},
@code{NULL} or the special @code{''} error value.  An @code{ENUM} column can
have a maximum of 65,535 distinct values.
@code{ENUM} values are represented internally as integers.
@c end_description_for_help_topic

@c description_for_help_topic type SET
@item SET('@var{value1}','@var{value2}',...)
@tindex SET

A set.  A string object that can have zero or more values, each of which must
be chosen from the list of values @code{'@var{value1}'}, @code{'@var{value2}'},
@code{...} A @code{SET} column can have a maximum of 64 members.
@code{SET} values are represented internally as integers.
@end table
@c end_description_for_help_topic


@node Numeric types, Date and time types, Column type overview, Column types
@section Numeric Types

MySQL supports all of the standard SQL numeric data types.  These
types include the exact numeric data types (@code{INTEGER},
@code{SMALLINT}, @code{DECIMAL}, and @code{NUMERIC}), as well as the
approximate numeric data types (@code{FLOAT}, @code{REAL}, and
@code{DOUBLE PRECISION}). The keyword @code{INT} is a synonym for
@code{INTEGER}, and the keyword @code{DEC} is a synonym for
@code{DECIMAL}.

As an extension to the SQL standard, MySQL also supports the integer
types @code{TINYINT}, @code{MEDIUMINT}, and @code{BIGINT} as listed in
the following table.

@c FIX arjen 2002-08-07 New table, not yet measured for DocBook
@c FIX also need to shuffle into proper position and adjust text.
@multitable @columnfractions .15 .15 .35 .35
@item @strong{Type}    @tab @strong{Bytes} @tab @strong{Minimum Value}     @tab @strong{Maximum Value}
@item                  @tab                @tab @strong{(Signed/Unsigned)} @tab @strong{(Signed/Unsigned)}
@item @code{TINYINT}   @tab              1 @tab                @code{-128} @tab                  @code{127}
@item                  @tab                @tab                   @code{0} @tab                  @code{255}
@item @code{SMALLINT}  @tab              2 @tab              @code{-32768} @tab                @code{32767}
@item                  @tab                @tab                   @code{0} @tab                  @code{65535}
@item @code{MEDIUMINT} @tab              3 @tab            @code{-8388608} @tab              @code{8388607}
@item                  @tab                @tab                   @code{0} @tab             @code{16777215}
@item @code{INT}       @tab              4 @tab         @code{-2147483648} @tab           @code{2147483647}
@item                  @tab                @tab                   @code{0} @tab           @code{4294967295}
@item @code{BIGINT}    @tab              8 @tab @code{-9223372036854775808} @tab  @code{9223372036854775807}
@item                  @tab                @tab                   @code{0} @tab @code{18446744073709551615}
@end multitable

Another extension is supported by MySQL for optionally
specifying the display width of an integer value in parentheses following
the base keyword for the type (for example, @code{INT(4)}).  This optional
display width specification is used to left-pad the display of values
having a width less than the width specified for the column.

The display width does not constrain the range of values that can be stored
in the column, nor the number of digits that will be displayed for values
having a width exceeding that specified for the column.

When used in conjunction with the optional extension attribute
@code{ZEROFILL}, the default padding of spaces is replaced with zeros.
For example, for a column declared as @code{INT(5) ZEROFILL}, a value
of @code{4} is retrieved as @code{00004}.  Note that if you store larger
values than the display width in an integer column, you may experience
problems when MySQL generates temporary tables for some
complicated joins, because in these cases MySQL trusts that the
data did fit into the original column width.

All integer types can have an optional (non-standard) attribute
@code{UNSIGNED}.  Unsigned values can be used when you want to allow only
non-negative numbers in a column and you need a bigger upper numeric
range for the column.

As of MySQL 4.0.2, floating-point and fixed-point types also can be
@code{UNSIGNED}.  As with integer types, this attribute prevents negative
values from being stored in the column.  However, unlike the integer types,
the upper range of column values remains the same.

If you specify @code{ZEROFILL} for a numeric column, MySQL
automatically adds the @code{UNSIGNED} attribute to the column.

The @code{DECIMAL} and @code{NUMERIC} types are implemented as the same
type by MySQL.  They are
used to store values for which it is important to preserve exact precision,
for example with monetary data.  When declaring a column of one of these
types, the precision and scale can be (and usually is) specified; for
example:

@example
salary DECIMAL(5,2)
@end example

In this example, @code{5} is the precision and @code{2} is the scale.  The
precision represents the number of significant decimal digits that will be
stored for values, and the scale represents the number of digits that will
be stored following the decimal point.

MySQL stores @code{DECIMAL} and @code{NUMERIC} values as strings, rather
than as binary floating-point numbers, in order to preserve the decimal
precision of those values.  One character is used for each digit of the
value, the decimal point (if the scale is greater than 0), and the @samp{-} sign
(for negative numbers).  If the scale is 0, @code{DECIMAL} and
@code{NUMERIC} values contain no decimal point or fractional part.

Standard SQL requires that the @code{salary} column
be able to store any value with five digits and two decimals. In this case,
therefore, the range of values that can be stored in the @code{salary}
column is from @code{-999.99} to @code{999.99}.  MySQL varies from this in
two ways:

@itemize @bullet

@item
On the positive end of the range, the column actually can store numbers up to
@code{9999.99}. For positive numbers, MySQL uses the
byte reserved for the sign to extend the upper end of the range.

@item
@code{DECIMAL} columns in MySQL before 3.23 are stored differently and
cannot represent all the values required by standard SQL. This is because
for a type of @code{DECIMAL(@var{M},@var{D})}, the value of @var{M} includes the bytes
for the sign and the decimal point.  The range of the @code{salary} column
before MySQL 3.23 would be @code{-9.99} to @code{99.99}.

@end itemize

In standard SQL, the syntax @code{DECIMAL(@var{M})} is equivalent to
@code{DECIMAL(@var{M},0)}.  Similarly, the syntax @code{DECIMAL} is equivalent
to @code{DECIMAL(@var{M},0)}, where the implementation is allowed to decide the
value of @var{M}.  As of MySQL 3.23.6, both of these variant forms of the
@code{DECIMAL} and @code{NUMERIC} data types are supported.  The default value
of @var{M} is 10. Before 3.23.6,
@var{M} and @var{D} both must be specified explicitly.

The maximum range of @code{DECIMAL} and @code{NUMERIC} values is the
same as for @code{DOUBLE}, but the actual range for a given
@code{DECIMAL} or @code{NUMERIC} column can be constrained by the
precision or scale for a given column.  When such a column
is assigned a value with more digits following the decimal point than
are allowed by the specified scale, the value is converted to that
scale.  (The precise behavior is operating system-specific, but
generally the effect is truncation to the allowable number of digits.)
When a @code{DECIMAL} or @code{NUMERIC} column is
assigned a value that exceeds the range implied by the
specified (or default) precision and scale,
MySQL stores the value representing the corresponding end
point of that range.

For floating-point column types, MySQL uses four bytes for single-precision
values and eight bytes for double-precision values.

The @code{FLOAT} type is used to represent approximate numeric data types.
The SQL standard allows an optional specification of the precision
(but not the range of the exponent) in bits following the keyword
@code{FLOAT} in parentheses.  The MySQL implementation also supports this
optional precision specification, but the precision value is used only to
determine storage size.  A precision from 0 to 23 results in four-byte
single-precision @code{FLOAT} column. A precision from 24 to 53 results
in eight-byte double-precision @code{DOUBLE} column.

When the keyword
@code{FLOAT} is used for a column type without a precision specification,
MySQL uses four bytes to store the values.  MySQL also supports variant
syntax with two numbers given in parentheses following the @code{FLOAT}
keyword.  The first number represents the display width
and the second number specifies the number of digits to be stored and
displayed following the decimal point (as with @code{DECIMAL} and
@code{NUMERIC}).  When MySQL is asked to store a number for
such a column with more decimal digits following the decimal point than
specified for the column, the value is rounded to eliminate the extra
digits when the value is stored.

In standard SQL, the @code{REAL} and @code{DOUBLE PRECISION} types do not accept
precision specifications.  MySQL supports a variant syntax with two numbers
given in parentheses following the type name.  The first number represents
the display width and the second number specifies the number of digits to
be stored and displayed following the decimal point.
As an extension to the SQL standard, MySQL recognizes @code{DOUBLE}
as a synonym for the @code{DOUBLE PRECISION} type.  In contrast with the
standard's requirement that the precision for @code{REAL} be smaller than
that used for @code{DOUBLE PRECISION}, MySQL implements both as eight-byte
double-precision floating-point values (unless the server SQL mode
includes the @code{REAL_AS_FLOAT} option).

For maximum portability, code requiring storage of approximate numeric
data values should use @code{FLOAT} or @code{DOUBLE PRECISION} with no
specification of precision or number of decimal points.

When asked to store a value in a numeric column that is outside the column
type's allowable range, MySQL clips the value to the appropriate
endpoint of the range and stores the resulting value instead.

For example, the range of an @code{INT} column is @code{-2147483648}
to @code{2147483647}.  If you try to insert @code{-9999999999} into an
@code{INT} column, MySQL clips the value to the lower endpoint of the
range and stores @code{-2147483648} instead. Similarly, if you try to
insert @code{9999999999}, MySQL clips the value to the upper endpoint of
the range and stores @code{2147483647} instead.

If the @code{INT} column is @code{UNSIGNED}, the size of the column's
range is the same but its endpoints shift up to @code{0} and @code{4294967295}.
If you try to store @code{-9999999999} and @code{9999999999},
the values stored in the column are @code{0} and @code{4294967296}.

Conversions that occur due to clipping are reported as ``warnings'' for
@code{ALTER TABLE}, @code{LOAD DATA INFILE}, @code{UPDATE}, and
multiple-row @code{INSERT} statements.


@node Date and time types, String types, Numeric types, Column types
@section Date and Time Types

@c TODO: this doesn't have any storage size table, unlike the numeric
@c and string types section.

@cindex types, Date and Time
@cindex Date and Time types

@menu
* DATETIME::                    The @code{DATETIME}, @code{DATE}, and @code{TIMESTAMP} Types
* TIME::                        The @code{TIME} Type
* YEAR::                        The @code{YEAR} Type
* Y2K issues::                  Y2K Issues and Date Types
@end menu


The date and time types for representing temporal values are @code{DATETIME}, @code{DATE},
@code{TIMESTAMP}, @code{TIME}, and @code{YEAR}.  Each temporal type has a
range of legal values, as well as a ``zero'' value that is used when you
specify an illegal value that MySQL cannot represent. The @code{TIMESTAMP}
type has special automatic updating behavior, described later on.

Starting from MySQL 5.0.2, MySQL will give warnings/errors if you try to insert
an illegal date. You can get MySQL to accept certain dates, such as
@code{'1999-11-31'}, by using the @code{ALLOW_INVALID_DATES} SQL mode.
(Before 5.0.2, this mode was the default behavior for MySQL).
This is useful when you want to store the ``possibly wrong'' value the user has
specified (for example, in a web form) in the database for future processing.
Under this mode, MySQL verifies only that the month is in the range from 0
to 12 and that the day is in the range from 0 to 31. These ranges
are defined to include zero because MySQL allows you to store dates where the
day or month and day are zero in a @code{DATE} or @code{DATETIME} column.
This is extremely useful for applications that need to store a birthdate for
which you don't know the exact date.  In this case, you simply store the date
as @code{'1999-00-00'} or @code{'1999-01-00'}.  If you store dates such as
these, you should not expect to get correct results for functions such as
@code{DATE_SUB()} or @code{DATE_ADD} that require complete dates.  (If you
don't want to allow zero in dates, you can use the @code{NO_ZERO_IN_DATE}
SQL mode).

MySQL also allows you to store @code{'0000-00-00'} as a ``dummy date''
(if you are not using the @code{NO_ZERO_DATE} SQL mode).  This is in some
cases is more convenient than using @code{NULL} values.

By setting the @code{sql_mode} system variable to the appropriate mode
values, You can more exactly what kind of dates you want MySQL to support.
@xref{Server SQL mode}.

Here are some general considerations to keep in mind when working
with date and time types:

@itemize @bullet
@item
MySQL retrieves values for a given date or time type in a standard output
format, but it attempts to interpret a variety of formats for input values
that you supply (for example, when you specify a value to be assigned to
or compared to a date or time type).  Only the formats described in the
following sections are supported.  It is expected that you will supply
legal values, and unpredictable results may occur if you use values in
other formats.

@item
Dates containing two-digit year values are ambiguous because the century is
unknown.  MySQL interprets two-digit year values using the following
rules:

@itemize @minus
@item
Year values in the range @code{00-69} are converted to @code{2000-2069}.

@item
Year values in the range @code{70-99} are converted to @code{1970-1999}.
@end itemize

@item
Although MySQL tries to interpret values in several formats, 
dates always must be
given in year-month-day order (for example, @code{'98-09-04'}), rather than
in the month-day-year or day-month-year orders commonly used elsewhere (for
example, @code{'09-04-98'}, @code{'04-09-98'}).

@item
MySQL automatically converts a date or time type value to a number
if the value is used in a numeric context and vice versa.

@item
When MySQL encounters a value for a date or time type that is out of
range or otherwise illegal for the type (as described at the beginning of
this section), it converts the value to the ``zero'' value for that type.
The exception is that out-of-range @code{TIME} values are clipped to the
appropriate endpoint of the @code{TIME} range.

The following table shows the format of the ``zero'' value for each
type.  Note that the use of these values produces warnings if the
@code{NO_ZERO_DATE} SQL mode is enabled.

@multitable @columnfractions .30 .40
@item @strong{Column Type} @tab @strong{``Zero'' Value}
@item @code{DATETIME}      @tab @code{'0000-00-00 00:00:00'}
@item @code{DATE}          @tab @code{'0000-00-00'}
@item @code{TIMESTAMP}     @tab @code{00000000000000}
@item @code{TIME}          @tab @code{'00:00:00'}
@item @code{YEAR}          @tab @code{0000}
@end multitable

@item
The ``zero'' values are special, but you can store or refer to them
explicitly using the values shown in the table.  You can also do this
using the values @code{'0'} or @code{0}, which are easier to write.

@item
``Zero'' date or time values used through MyODBC are converted
automatically to @code{NULL} in MyODBC 2.50.12 and above,
because ODBC can't handle such values.
@end itemize


@node DATETIME, TIME, Date and time types, Date and time types
@subsection The @code{DATETIME}, @code{DATE}, and @code{TIMESTAMP} Types

@tindex DATETIME
@tindex DATE
@tindex TIMESTAMP

@menu
* TIMESTAMP pre-4.1::           @code{TIMESTAMP} Properties Prior to MySQL 4.1
* TIMESTAMP 4.1::               @code{TIMESTAMP} Properties as of MySQL 4.1
@end menu

The @code{DATETIME}, @code{DATE}, and @code{TIMESTAMP} types are related.
This section describes their characteristics, how they are similar, and how
they differ.

The @code{DATETIME} type is used when you need values that contain both date
and time information.  MySQL retrieves and displays @code{DATETIME}
values in @code{'YYYY-MM-DD HH:MM:SS'} format.  The supported range is
@code{'1000-01-01 00:00:00'} to @code{'9999-12-31 23:59:59'}.  (``Supported''
means that although earlier values might work, there is no guarantee that
they will.)

The @code{DATE} type is used when you need only a date value, without a time
part.  MySQL retrieves and displays @code{DATE} values in
@code{'YYYY-MM-DD'} format.  The supported range is @code{'1000-01-01'} to
@code{'9999-12-31'}.

@c INSERT START
The @code{TIMESTAMP} column type has varying properties,
depending on the MySQL version and the SQL mode the server is running in.
These properties are described later in this section.

You can specify @code{DATETIME}, @code{DATE}, and @code{TIMESTAMP} values using
any of a common set of formats:

@itemize @bullet
@item
As a string in either @code{'YYYY-MM-DD HH:MM:SS'} or @code{'YY-MM-DD
HH:MM:SS'} format.  A ``relaxed'' syntax is allowed: Any punctuation
character may be used as the delimiter between date parts or time parts.
For example, @code{'98-12-31 11:30:45'}, @code{'98.12.31 11+30+45'},
@code{'98/12/31 11*30*45'}, and @code{'98@@12@@31 11^30^45'} are
equivalent.

@item
As a string in either @code{'YYYY-MM-DD'} or @code{'YY-MM-DD'} format.
A ``relaxed'' syntax is allowed here, too.  For example, @code{'98-12-31'},
@code{'98.12.31'}, @code{'98/12/31'}, and @code{'98@@12@@31'} are
equivalent.

@item
As a string with no delimiters in either @code{'YYYYMMDDHHMMSS'} or
@code{'YYMMDDHHMMSS'} format, provided that the string makes sense as a
date.  For example, @code{'19970523091528'} and @code{'970523091528'} are
interpreted as @code{'1997-05-23 09:15:28'}, but @code{'971122129015'} is
illegal (it has a nonsensical minute part) and becomes @code{'0000-00-00
00:00:00'}.

@item
As a string with no delimiters in either @code{'YYYYMMDD'} or @code{'YYMMDD'}
format, provided that the string makes sense as a date.  For example,
@code{'19970523'} and @code{'970523'} are interpreted as
@code{'1997-05-23'}, but @code{'971332'} is illegal (it has nonsensical month
and day parts) and becomes @code{'0000-00-00'}.

@item
As a number in either @code{YYYYMMDDHHMMSS} or @code{YYMMDDHHMMSS}
format, provided that the number makes sense as a date.  For example,
@code{19830905132800} and @code{830905132800} are interpreted as
@code{'1983-09-05 13:28:00'}.

@item
As a number in either @code{YYYYMMDD} or @code{YYMMDD}
format, provided that the number makes sense as a date.  For example,
@code{19830905} and @code{830905} are interpreted as @code{'1983-09-05'}.

@item
As the result of a function that returns a value that is acceptable
in a @code{DATETIME}, @code{DATE}, or @code{TIMESTAMP} context, such as
@code{NOW()} or @code{CURRENT_DATE}.
@end itemize

Illegal @code{DATETIME}, @code{DATE}, or @code{TIMESTAMP} values are converted
to the ``zero'' value of the appropriate type (@code{'0000-00-00 00:00:00'},
@code{'0000-00-00'}, or @code{00000000000000}).

For values specified as strings that include date part delimiters, it is not
necessary to specify two digits for month or day values that are less than
@code{10}.  @code{'1979-6-9'} is the same as @code{'1979-06-09'}.  Similarly,
for values specified as strings that include time part delimiters, it is not
necessary to specify two digits for hour, minute, or second values that are
less than @code{10}.  @code{'1979-10-30 1:2:3'} is the same as
@code{'1979-10-30 01:02:03'}.

Values specified as numbers should be 6, 8, 12, or 14 digits long.  If a
number is 8 or 14 digits long, it is assumed to be in @code{YYYYMMDD} or
@code{YYYYMMDDHHMMSS} format and that the year is given by the first 4
digits.  If the number is 6 or 12 digits long, it is assumed to be in
@code{YYMMDD} or @code{YYMMDDHHMMSS} format and that the year is given by the
first 2 digits.  Numbers that are not one of these lengths are interpreted
as though padded with leading zeros to the closest length.

@cindex non-delimited strings
@cindex strings, non-delimited
Values specified as non-delimited strings are interpreted using their length
as given.  If the string is 8 or 14 characters long, the year is assumed to
be given by the first 4 characters.  Otherwise, the year is assumed to be
given by the first 2 characters.  The string is interpreted from left to
right to find year, month, day, hour, minute, and second values, for as many
parts as are present in the string.  This means you should not use strings
that have fewer than 6 characters.  For example, if you specify @code{'9903'},
thinking that will represent March, 1999, you will find that MySQL
inserts a ``zero'' date into your table.  This is because the year and month
values are @code{99} and @code{03}, but the day part is completely missing, so
the value is not a legal date.  However, as of MySQL 3.23, you can explicitly
specify a value of zero to represent missing month or day parts.  For example,
you can use @code{'990300'} to insert the value @code{'1999-03-00'}.

You can to some extent assign values of one date type to an object
of a different date type.  However, there may be some alteration
of the value or loss of information:

@itemize @bullet
@item
If you assign a @code{DATE} value to a @code{DATETIME} or @code{TIMESTAMP}
object, the time part of the resulting value is set to @code{'00:00:00'}
because the @code{DATE} value contains no time information.

@item
If you assign a @code{DATETIME} or @code{TIMESTAMP} value to a @code{DATE}
object, the time part of the resulting value is deleted because the
@code{DATE} type stores no time information.

@item
Remember that although @code{DATETIME}, @code{DATE}, and @code{TIMESTAMP}
values all can be specified using the same set of formats, the types do not
all have the same range of values.  For example, @code{TIMESTAMP} values
cannot be earlier than @code{1970} or later than @code{2037}.  This means
that a date such as @code{'1968-01-01'}, while legal as a @code{DATETIME} or
@code{DATE} value, is not a valid @code{TIMESTAMP} value and will be
converted to @code{0} if assigned to such an object.
@end itemize

@cindex problems, date values
@cindex date values, problems
Be aware of certain pitfalls when specifying date values:

@itemize @bullet
@item
The relaxed format allowed for values specified as strings can be deceiving.
For example, a value such as @code{'10:11:12'} might look like a time value
because of the @samp{:} delimiter, but if used in a date context will be
interpreted as the year @code{'2010-11-12'}.  The value @code{'10:45:15'}
will be converted to @code{'0000-00-00'} because @code{'45'} is not a legal
month.

@c TODO: change next para when STRICT mode is implemented

@item
The MySQL server performs only basic checking on the validity of a date:
The ranges for year, month, and day are 1000 to 9999, 00 to 12, and 00
to 31, respectively.  Any date containing parts not within these ranges is subject to
conversion
to @code{'0000-00-00'}.  Please note that this still allows you to store
invalid dates such as @code{'2002-04-31'}.  To ensure that a date is valid,
perform a check in your application.

@item
Dates containing two-digit year values are ambiguous because the century is
unknown.  MySQL interprets two-digit year values using the following
rules:

@itemize @minus
@item
Year values in the range @code{00-69} are converted to @code{2000-2069}.

@item
Year values in the range @code{70-99} are converted to @code{1970-1999}.
@end itemize
@end itemize


@node TIMESTAMP pre-4.1, TIMESTAMP 4.1, DATETIME, DATETIME
@subsubsection @code{TIMESTAMP} Properties Prior to MySQL 4.1

The @code{TIMESTAMP} column type provides a type that you can use to
automatically mark @code{INSERT} or @code{UPDATE} operations with the current
date and time.  If you have multiple @code{TIMESTAMP} columns in a table,
only the first one is updated automatically. (From MySQL 4.1.2 on, you can
specify which @code{TIMESTAMP} column updates;
@pxref{TIMESTAMP 4.1,  , @code{TIMESTAMP} 4.1}.)

Automatic updating of the first @code{TIMESTAMP} column in a table occurs
under any of the following conditions:

@itemize @bullet

@item
You explicitly set the column to @code{NULL}.

@item
The column is not specified explicitly in an @code{INSERT} or
@code{LOAD DATA INFILE} statement.

@item
The column is not specified explicitly in an @code{UPDATE} statement and some
other column changes value.  An @code{UPDATE} that sets a column
to the value it already has does not cause the @code{TIMESTAMP} column to be
updated; if you set a column to its current value, MySQL
ignores the update for efficiency.

@end itemize

@code{TIMESTAMP} columns other than the first can also be set to the current
date and time.  Just set the column to @code{NULL} or to any function that
produces the current date and time (@code{NOW()}, @code{CURRENT_TIMESTAMP}).

You can set any @code{TIMESTAMP} column to a value different from the current
date and time by setting it explicitly to the desired value.  This is true
even for the first @code{TIMESTAMP} column.  You can use this property if,
for example, you want a @code{TIMESTAMP} to be set to the current date and
time when you create a row, but not to be changed whenever the row is updated
later:

@itemize @bullet
@item
Let MySQL set the column when the row is created.
This initializes it to the current date and time.

@item
When you perform subsequent updates to other columns in the row, set
the @code{TIMESTAMP} column explicitly to its current value:

@example
UPDATE @var{tbl_name}
    SET @var{timestamp_col} = @var{timestamp_col},
        @var{other_col1} = @var{new_value1},
        @var{other_col2} = @var{new_value2}, ...
@end example

@end itemize

Another way to maintain a column that records row-creation time is to use
a @code{DATETIME} column that you initialize to @code{NOW()} when the row
is created and leave alone for subsequent updates.

@code{TIMESTAMP} values may range from the beginning of 1970 to partway
through the year 2037, with a resolution of one second.  Values are displayed
as numbers.  When you store a value in a @code{TIMESTAMP} column, it is
assumed to be represented in the current time zone, and is converted to
UTC for storage. When you retrieve the value, it is converted from UTC
back to the local time zone for display.  Before MySQL 4.1.3, the server
has a single time zone. As of 4.1.3, clients can set their time zone on
a per-connection basis, as described in @code{Time zone support}.

The format in which MySQL retrieves and displays @code{TIMESTAMP}
values depends on the display size, as illustrated by the following table.  The
``full'' @code{TIMESTAMP} format is 14 digits, but @code{TIMESTAMP} columns may
be created with shorter display sizes:

@multitable @columnfractions .30 .30
@item @strong{Column Type}  @tab @strong{Display Format}
@item @code{TIMESTAMP(14)}  @tab @code{YYYYMMDDHHMMSS}
@item @code{TIMESTAMP(12)}  @tab @code{YYMMDDHHMMSS}
@item @code{TIMESTAMP(10)}  @tab @code{YYMMDDHHMM}
@item @code{TIMESTAMP(8)}   @tab @code{YYYYMMDD}
@item @code{TIMESTAMP(6)}   @tab @code{YYMMDD}
@item @code{TIMESTAMP(4)}   @tab @code{YYMM}
@item @code{TIMESTAMP(2)}   @tab @code{YY}
@end multitable

All @code{TIMESTAMP} columns have the same storage size, regardless of
display size.  The most common display sizes are 6, 8, 12, and 14.  You can
specify an arbitrary display size at table creation time, but values of 0 or
greater than 14 are coerced to 14.  Odd-valued sizes in the range from 1 to
13 are coerced to the next higher even number.

@code{TIMESTAMP} columns store legal values using the full precision with
which the value was specified, regardless of the display size.  This has
several implications:

@itemize @bullet
@item
Always specify year, month, and day, even if your column types are
@code{TIMESTAMP(4)} or @code{TIMESTAMP(2)}.  Otherwise, the value is not
a legal date and @code{0} will be stored.

@item
If you use @code{ALTER TABLE} to widen a narrow @code{TIMESTAMP} column,
information will be displayed that previously was ``hidden.''

@item
Similarly, narrowing a @code{TIMESTAMP} column does not cause information to
be lost, except in the sense that less information is shown when the values
are displayed.

@item
Although @code{TIMESTAMP} values are stored to full precision, the only
function that operates directly on the underlying stored value is
@code{UNIX_TIMESTAMP()}.  Other functions operate on the formatted retrieved
value.  This means you cannot use a function such as @code{HOUR()} or
@code{SECOND()} unless the relevant part of the @code{TIMESTAMP} value is
included in the formatted value.  For example, the @code{HH} part of a
@code{TIMESTAMP} column is not displayed unless the display size is at least
10, so trying to use @code{HOUR()} on shorter @code{TIMESTAMP} values
produces a meaningless result.
@end itemize

@node TIMESTAMP 4.1,  , TIMESTAMP pre-4.1, DATETIME
@subsubsection @code{TIMESTAMP} Properties as of MySQL 4.1

In MySQL 4.1 and up, the properties of the @code{TIMESTAMP} column type change
in the ways described in this section.

From MySQL 4.1.0 on, @code{TIMESTAMP} display format differs from that of
earlier MySQL releases:

@itemize @bullet

@item
@code{TIMESTAMP} columns are displayed in the same format as @code{DATETIME}
columns.

@item
Display widths (used as described in the preceding section) are no longer
supported. In other words, for declarations such as @code{TIMESTAMP(2)},
@code{TIMESTAMP(4)}, and so on, the display width is ignored.

@end itemize

Beginning with MySQL 4.1.1, the MySQL server can be run in @code{MAXDB}
mode.  When the server runs in this mode, @code{TIMESTAMP} is identical
with @code{DATETIME}. That is, if the server is running in @code{MAXDB}
mode at the time that a table is created, @code{TIMESTAMP} columns
are created as @code{DATETIME} columns.  As a result, such columns use
@code{DATETIME} display format, have the same range of values, and there is
no automatic initialization or updating to the current date and time.

To enable @code{MAXDB} mode,
set the server SQL mode to @code{MAXDB} at startup using the
@code{--sql-mode=MAXDB} server option or by setting the global
@code{sql_mode} variable at runtime:

@example
mysql> SET GLOBAL sql_mode=MAXDB;
@end example

A client can cause the server to run in @code{MAXDB} mode for its own
connection as follows:

@example
mysql> SET SESSION sql_mode=MAXDB;
@end example

As of MySQL 5.0.2, MySQL will not accept timestamp values that includes
a zero in the day or month column or values that are not a valid date.
(The execption is the special value '0000-00-00 00:00:00'.)

Beginning with MySQL 4.1.2, you have more flexible control over when
automatic @code{TIMESTAMP} initialization and updating occur and which
column should have those behaviors:

@itemize @bullet

@item
You can assign the current timestamp as the default value and the
auto-update value, as before. But now it is possible to have just one
automatic behavior or the other, or neither of them.

@item
You can specify which @code{TIMESTAMP} column to automatically initialize
or update to the current date and time. This no longer need be the first
@code{TIMESTAMP} column.

@end itemize

The following discussion describes the revised syntax and behavior.
Note that this information applies only to @code{TIMESTAMP} columns for
tables not created with @code{MAXDB} mode enabled. As noted earlier in
this section, @code{MAXDB} mode causes columns to be created as
@code{DATETIME} columns.

The following items summarize the pre-4.1.2 properties for @code{TIMESTAMP}
initialization and updating:

The first @code{TIMESTAMP} column in table row automatically is set to
the current timestamp when the record is created if the column is set to
@code{NULL} or is not specified at all.

The first @code{TIMESTAMP} column in table row automatically is updated
to the current timestamp when the value of any other column in the row
is changed, unless the @code{TIMESTAMP} column explicitly is assigned a
value other than @code{NULL}.

If a @code{DEFAULT} value is specified for the first @code{TIMESTAMP}
column when the table is created, it is silently ignored.

Other @code{TIMESTAMP} columns in the table can be set to the current
@code{TIMESTAMP} by assigning @code{NULL} to them, but they do not update
automatically.

As of 4.1.2, you have more flexibility in deciding which @code{TIMESTAMP}
column automatically is initialized and updated to the current timestamp.
The rules are as follows:

If a @code{DEFAULT} value is specified for the first @code{TIMESTAMP} column
in a table, it is not ignored.  The default can be @code{CURRENT_TIMESTAMP}
or a constant date and time value.

@code{DEFAULT NULL} is the same as @code{DEFAULT CURRENT_TIMESTAMP} for
the @emph{first} @code{TIMESTAMP} column.  For any other @code{TIMESTAMP}
column, @code{DEFAULT NULL} is treated as @code{DEFAULT 0}.

Any single @code{TIMESTAMP} column in a table can be set to be the one that
is initialized to the current timestamp and/or updated automatically.

In a @code{CREATE TABLE} statement, the first @code{TIMESTAMP} column can
be declared in any of the following ways:

@itemize @bullet

@item
With both @code{DEFAULT CURRENT_TIMESTAMP} and @code{ON UPDATE
CURRENT_TIMESTAMP} clauses, the column has the current timestamp for its
default value, and is automatically updated.

@item
With neither @code{DEFAULT} nor @code{ON UPDATE} clauses, it is the same
as @code{DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP}.

@item
With a @code{DEFAULT CURRENT_TIMESTAMP} clause and no @code{ON UPDATE}
clause, the column has the current timestamp for its default value but is
not automatically updated.

@item
With no @code{DEFAULT} clause and with an @code{ON UPDATE CURRENT_TIMESTAMP}
clause, the column has a default of 0 and is automatically updated.

@item
With a constant @code{DEFAULT} value and with @code{ON UPDATE
CURRENT_TIMESTAMP} clause, the column has the given default and is
automatically updated.

@end itemize

In other words, you can use the current timestamp for both the initial
value and the auto-update value, or either one, or neither.  (For example,
you can specify @code{ON UPDATE} to get auto-update without also having
the column auto-initialized.)

Any of @code{CURRENT_TIMESTAMP}, @code{CURRENT_TIMESTAMP()}, or @code{NOW()}
can be used in the @code{DEFAULT} and @code{ON UPDATE} clauses. They
all have the same effect.

The order of the two attributes does not matter.  If both @code{DEFAULT}
and @code{ON UPDATE} are specified for a @code{TIMESTAMP} column, either
can precede the other.

Example.  These statements are equivalent:

@example
CREATE TABLE t (ts TIMESTAMP);
CREATE TABLE t (ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                             ON UPDATE CURRENT_TIMESTAMP);
CREATE TABLE t (ts TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
                             DEFAULT CURRENT_TIMESTAMP);
@end example

To specify automatic default or updating for a @code{TIMESTAMP} column other
than the first one, you must suppress the automatic initialization and update behaviors
for the first @code{TIMESTAMP} column by explicitly assigning it a constant
@code{DEFAULT} value (for example, @code{DEFAULT 0} or @code{DEFAULT
'2003-01-01 00:00:00'}). Then for the other @code{TIMESTAMP} column, the
rules are the same as for the first @code{TIMESTAMP} column, except that
you cannot omit both of the @code{DEFAULT} and @code{ON UPDATE} clauses.
If you do that, no automatic initialization or updating occurs.

Example.  These statements are equivalent:

@example
CREATE TABLE t (
    ts1 TIMESTAMP DEFAULT 0,
    ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                  ON UPDATE CURRENT_TIMESTAMP);
CREATE TABLE t (
    ts1 TIMESTAMP DEFAULT 0,
    ts2 TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
                  DEFAULT CURRENT_TIMESTAMP);
@end example

Beginning with MySQL 4.1.3, you can set the current time zone on a
per-connection basis, as described in @code{Time zone support}.
@code{TIMESTAMP} values still are stored in UTC, but are converted
from the current time zone for storage, and converted back to the
current time zone for retrieval.  As long as the time zone setting
remains the same, you will get back the same value you store.  If you
store a @code{TIMESTAMP} value, then change the time zone and
retrieve the value, it will be different than the value you stored.
This occurs because the same time zone is not used for conversion in
both directions.  The current time zone is available as the value of
the @code{time_zone} system variable.


@node TIME, YEAR, DATETIME, Date and time types
@subsection The @code{TIME} Type

@tindex TIME

MySQL retrieves and displays @code{TIME} values in @code{'HH:MM:SS'}
format (or @code{'HHH:MM:SS'} format for large hours values).  @code{TIME}
values may range from @code{'-838:59:59'} to @code{'838:59:59'}.  The reason
the hours part may be so large is that the @code{TIME} type may be used not
only to represent a time of day (which must be less than 24 hours), but also
elapsed time or a time interval between two events (which may be much greater
than 24 hours, or even negative).

You can specify @code{TIME} values in a variety of formats:

@itemize @bullet
@item
As a string in @code{'D HH:MM:SS.fraction'} format.
You can also use one of the following ``relaxed'' syntaxes:
@code{'HH:MM:SS.fraction'}, @code{'HH:MM:SS'}, @code{'HH:MM'}, @code{'D
HH:MM:SS'}, @code{'D HH:MM'}, @code{'D HH'}, or @code{'SS'}.  Here @code{D}
represents days and can have a value from 0 to 34.
Note that MySQL doesn't yet store the fraction part.

@item
As a string with no delimiters in @code{'HHMMSS'} format, provided that
it makes sense as a time.  For example, @code{'101112'} is understood as
@code{'10:11:12'}, but @code{'109712'} is illegal (it has a nonsensical
minute part) and becomes @code{'00:00:00'}.

@item
As a number in @code{HHMMSS} format, provided that it makes sense as a time.
For example, @code{101112} is understood as @code{'10:11:12'}.  The following
alternative formats are also understood: @code{SS}, @code{MMSS}, @code{HHMMSS},
@code{HHMMSS.fraction}.  Note that MySQL doesn't yet store the
fraction part.

@item
As the result of a function that returns a value that is acceptable
in a @code{TIME} context, such as @code{CURRENT_TIME}.
@end itemize

For @code{TIME} values specified as strings that include a time part
delimiter, it is not necessary to specify two digits for hours, minutes, or
seconds values that are less than @code{10}.  @code{'8:3:2'} is the same as
@code{'08:03:02'}.

Be careful about assigning ``short'' @code{TIME} values to a @code{TIME}
column. Without colons, MySQL interprets values using the
assumption that the rightmost digits represent seconds. (MySQL
interprets @code{TIME} values as elapsed time rather than as time of
day.) For example, you might think of @code{'1112'} and @code{1112} as
meaning @code{'11:12:00'} (12 minutes after 11 o'clock), but
MySQL interprets them as @code{'00:11:12'} (11 minutes, 12 seconds).
Similarly, @code{'12'} and @code{12} are interpreted as @code{'00:00:12'}.
@code{TIME} values with colons, by contrast, are always treated as
time of the day. That is @code{'11:12'} will mean @code{'11:12:00'},
not @code{'00:11:12'}.

Values that lie outside the @code{TIME} range
but are otherwise legal are clipped to the closest
endpoint of the range.  For example, @code{'-850:00:00'} and
@code{'850:00:00'} are converted to @code{'-838:59:59'} and
@code{'838:59:59'}.

Illegal @code{TIME} values are converted to @code{'00:00:00'}.  Note that
because @code{'00:00:00'} is itself a legal @code{TIME} value, there is no way
to tell, from a value of @code{'00:00:00'} stored in a table, whether the
original value was specified as @code{'00:00:00'} or whether it was illegal.


@node YEAR, Y2K issues, TIME, Date and time types
@subsection The @code{YEAR} Type

@c TODO: This really applies to YEAR(4). It could be more precise for YEAR(2).

@tindex YEAR

The @code{YEAR} type is a one-byte type used for representing years.

@c TODO: fix to account for YEAR(2), which is different

MySQL retrieves and displays @code{YEAR} values in @code{YYYY}
format.  The range is @code{1901} to @code{2155}.

You can specify @code{YEAR} values in a variety of formats:

@itemize @bullet
@item
As a four-digit string in the range @code{'1901'} to @code{'2155'}.

@item
As a four-digit number in the range @code{1901} to @code{2155}.

@item
As a two-digit string in the range @code{'00'} to @code{'99'}.  Values in the
ranges @code{'00'} to @code{'69'} and @code{'70'} to @code{'99'} are
converted to @code{YEAR} values in the ranges @code{2000} to @code{2069} and
@code{1970} to @code{1999}.

@item
As a two-digit number in the range @code{1} to @code{99}.  Values in the
ranges @code{1} to @code{69} and @code{70} to @code{99} are converted to
@code{YEAR} values in the ranges @code{2001} to @code{2069} and @code{1970}
to @code{1999}.  Note that the range for two-digit numbers is slightly
different from the range for two-digit strings, because you cannot specify zero
directly as a number and have it be interpreted as @code{2000}.  You
must specify it as a string @code{'0'} or @code{'00'} or it will be
interpreted as @code{0000}.

@item
As the result of a function that returns a value that is acceptable
in a @code{YEAR} context, such as @code{NOW()}.
@end itemize

Illegal @code{YEAR} values are converted to @code{0000}.


@node Y2K issues,  , YEAR, Date and time types
@subsection Y2K Issues and Date Types

@cindex Year 2000 issues
@cindex date types, Y2K issues

MySQL itself is year 2000 (Y2K) safe (@pxref{Year 2000 compliance}),
but input values presented to MySQL may not be.  Any input
containing two-digit year values is ambiguous, because the century is unknown.
Such values must be interpreted into four-digit form because MySQL stores
years internally using four digits.

For @code{DATETIME}, @code{DATE}, @code{TIMESTAMP}, and @code{YEAR} types,
MySQL interprets dates with ambiguous year values using the
following rules:

@itemize @bullet
@item
Year values in the range @code{00-69} are converted to @code{2000-2069}.

@item
Year values in the range @code{70-99} are converted to @code{1970-1999}.
@end itemize

Remember that these rules provide only reasonable guesses as to what your
data values mean.  If the heuristics used by MySQL do not produce the
correct values, you should provide unambiguous input containing four-digit
year values.

@code{ORDER BY} properly sorts @code{TIMESTAMP} or @code{YEAR} values that
have two-digit years.

Some functions like @code{MIN()} and @code{MAX()} will convert a
@code{TIMESTAMP} or @code{YEAR} to a number. This means that a value with a
two-digit year will not work properly with these functions.  The fix in this
case is to convert the @code{TIMESTAMP} or @code{YEAR} to four-digit year
format or use something like @code{MIN(DATE_ADD(timestamp,INTERVAL 0
DAYS))}.


@node String types, Storage requirements, Date and time types, Column types
@section String Types

@cindex types, strings
@cindex string types

@tindex CHAR
@tindex VARCHAR

@menu
* CHAR::                        The @code{CHAR} and @code{VARCHAR} Types
* BINARY VARBINARY::            The @code{BINARY} and @code{VARBINARY} Types
* BLOB::                        The @code{BLOB} and @code{TEXT} Types
* ENUM::                        The @code{ENUM} Type
* SET::                         The @code{SET} Type
@end menu


The string types are @code{CHAR}, @code{VARCHAR}, @code{BINARY},
@code{VARBINARY}, @code{BLOB}, @code{TEXT}, @code{ENUM}, and @code{SET}.
This section describes how these types work and how to use them in your
queries.


@node CHAR, BINARY VARBINARY, String types, String types
@subsection The @code{CHAR} and @code{VARCHAR} Types

The @code{CHAR} and @code{VARCHAR} types are similar, but differ in the
way they are stored and retrieved.

The length of a @code{CHAR} column is fixed to the length that you declare
when you create the table.  The length can be any value from 0 to 255.
(Before MySQL 3.23, the length of @code{CHAR} may be from 1 to 255.)
When @code{CHAR} values are stored, they are right-padded with spaces to the
specified length.  When @code{CHAR} values are retrieved, trailing spaces are
removed.

Values in @code{VARCHAR} columns are variable-length strings.  You can
declare a @code{VARCHAR} column to be any length from 0 to 255, just as
for @code{CHAR} columns.  (Before MySQL 4.0.2, the length of @code{VARCHAR}
may be from 1 to 255.) However, in contrast to @code{CHAR}, @code{VARCHAR}
values are stored using only as many characters as are needed, plus one byte
to record the length.  Values are not padded; instead, trailing spaces are
removed when values are stored.  This space removal differs from the
standard SQL specification.

No lettercase conversion takes place during storage or retrieval.

If you assign a value to a @code{CHAR} or @code{VARCHAR} column that
exceeds the column's maximum length, the value is truncated to fit.

If you need a column for which trailing spaces are not removed, consider using
a @code{BLOB} or @code{TEXT} type.
If you want to store binary values such as results from an encryption
or compression function that might contain arbitrary byte values, use a
@code{BLOB} column rather than a @code{CHAR} or @code{VARCHAR} column, to
avoid potential problems with trailing space removal that would change
data values.

The following table illustrates the differences between the two types of columns
by showing the result of storing various string values into @code{CHAR(4)}
and @code{VARCHAR(4)} columns:

@c Need to use @(space) to make sure second column values retain spacing
@c in output for table below.

@multitable @columnfractions .15 .15 .20 .15 .20
@item @strong{Value}  @tab @code{CHAR(4)}     @tab @strong{Storage Required} @tab @code{VARCHAR(4)} @tab @strong{Storage Required}
@item @code{''}       @tab @code{'@ @ @ @ '} @tab 4 bytes @tab @code{''} @tab 1 byte
@item @code{'ab'}     @tab @code{'ab@ @ '}   @tab 4 bytes @tab @code{'ab'} @tab 3 bytes
@item @code{'abcd'}   @tab @code{'abcd'}     @tab 4 bytes @tab @code{'abcd'} @tab 5 bytes
@item @code{'abcdefgh'} @tab @code{'abcd'}     @tab 4 bytes @tab @code{'abcd'} @tab 5 bytes
@end multitable

The values retrieved from the @code{CHAR(4)} and @code{VARCHAR(4)} columns
are the same in each case, because trailing spaces are removed from
@code{CHAR} columns upon retrieval.

As of MySQL 4.1, values in @code{CHAR} and @code{VARCHAR} columns are sorted
and compared according to the collation of the character set assigned to
the column.  Before MySQL 4.1, sorting and comparison are based on
the collation of the server character set; you can declare the column
with the @code{BINARY} attribute to cause sorting and comparison to be
case sensitive using the underlying character code values rather then a
lexical ordering.  @code{BINARY} doesn't affect how the column is stored
or retrieved.

From MySQL 4.1.0 on, column type @code{CHAR BYTE} is an alias for
@code{CHAR BINARY}. This is a compatibility feature.

The @code{BINARY} attribute is sticky.  This means that if a column marked
@code{BINARY} is used in an expression, the whole expression is treated as a
@code{BINARY} value.

From MySQL 4.1.0 on, the @code{ASCII} attribute can be specified for
@code{CHAR}. It assigns the @code{latin1} character set.

From MySQL 4.1.1 on, the @code{UNICODE} attribute can be specified for
@code{CHAR}. It assigns the @code{ucs2} character set.

MySQL may silently change the type of a @code{CHAR} or @code{VARCHAR}
column at table creation time.
@xref{Silent column changes}.


@node BINARY VARBINARY, BLOB, CHAR, String types
@subsection The @code{BINARY} and @code{VARBINARY} Types

The @code{BINARY} and @code{VARBINARY} types are like @code{CHAR} and
@code{VARCHAR}, except that they contain binary strings rather than
non-binary strings. That is, they contain byte strings rather than character
strings. This means they have no character set and compare in case sensitive
fashion.

Before MySQL 4.1.2, @code{BINARY(@var{M})} and @code{VARBINARY(@var{M})} are
treated as @code{CHAR(@var{M}) BINARY} and @code{VARCHAR(@var{M}) BINARY}.
As of MySQL 4.1.2, @code{BINARY} and @code{VARBINARY} are available as distinct
data types, and for @code{CHAR(@var{M}) BINARY} and @code{VARCHAR(@var{M})
BINARY}, the @code{BINARY} attribute does not cause the column to be treated
as a binary string column. Instead, it causes the binary collation for the
column character set to be used, but the column itself contains non-binary
character strings rather than binary byte strings. For example, in 4.1
and up, @code{CHAR(5) BINARY} is treated as @code{CHAR(5) CHARACTER SET
latin1 COLLATE latin1_bin}, assuming that the default character set is
@code{latin1}.


@node BLOB, ENUM, BINARY VARBINARY, String types
@subsection The @code{BLOB} and @code{TEXT} Types

@tindex BLOB
@tindex TEXT
@tindex LONG

@c description_for_help_topic BLOB
A @code{BLOB} is a binary large object that can hold a variable amount of
data.  The four @code{BLOB} types, @code{TINYBLOB}, @code{BLOB},
@code{MEDIUMBLOB}, and @code{LONGBLOB}, differ only in the maximum length of
the values they can hold.
@c end_description_for_help_topic
@xref{Storage requirements}.

The four @code{TEXT} types, @code{TINYTEXT}, @code{TEXT}, @code{MEDIUMTEXT},
and @code{LONGTEXT}, correspond to the four @code{BLOB} types and have
the same maximum lengths and storage requirements.

@code{BLOB} columns are treated as binary strings, whereas @code{TEXT}
columns are treated according to their character set.  For @code{BLOB}
columns, sorting and comparison is case sensitive.  For @code{TEXT} columns,
values are sorted and compared based on the collation of the character set
assigned to the column as of MySQL 4.1.  Before 4.1, @code{TEXT} sorting and
comparison are based on the collation of the server character set.

No lettercase conversion takes place during storage or retrieval.

If you assign a value to a @code{BLOB} or @code{TEXT} column that exceeds
the column type's maximum length, the value is truncated to fit.

In most respects, you can regard a @code{TEXT} column as a @code{VARCHAR}
column that can be as big as you like.  Similarly, you can regard a
@code{BLOB} column as a @code{VARCHAR BINARY} column.  The ways in which
@code{BLOB} and @code{TEXT} differ from @code{CHAR} and @code{VARCHAR} are:

@itemize @bullet

@item
There is no trailing-space removal for @code{BLOB} and @code{TEXT}
columns when values are stored or retrieved. This differs from @code{CHAR}
columns (trailing spaces are removed when values are retrieved) and from
@code{VARCHAR} columns (trailing spaces are removed when values are stored).

@item
You can have indexes on @code{BLOB} and @code{TEXT} columns only as of MySQL
3.23.2 for @code{MyISAM} tables or MySQL 4.0.14 for @code{InnoDB} tables.
Older versions of MySQL did not support indexing these column types.

@item
For indexes on @code{BLOB} and @code{TEXT} columns, you must specify an index
prefix length. For @code{CHAR} and @code{VARCHAR}, a prefix length is
optional.

@item
@cindex default values, @code{BLOB} and @code{TEXT} columns
@cindex @code{BLOB} columns, default values
@cindex @code{TEXT} columns, default values
@code{BLOB} and @code{TEXT} columns cannot have @code{DEFAULT} values.
@end itemize

From MySQL 4.1.0 on, @code{LONG} and @code{LONG VARCHAR} map to the
@code{MEDIUMTEXT} data type. This is a compatibility feature.

MySQL Connector/ODBC defines @code{BLOB} values as @code{LONGVARBINARY} and
@code{TEXT} values as @code{LONGVARCHAR}.

Because @code{BLOB} and @code{TEXT} values may be extremely long, you
may encounter some constraints in using them:

@itemize @bullet
@item
Only the first @code{max_sort_length} bytes of the
column are used when sorting.  The default value of @code{max_sort_length}
is 1024; this value can be changed using the @code{--max_sort_length}
option when starting the @command{mysqld} server.
@xref{Server system variables}.

As of MySQL 4.0.3, you can make more bytes signficant in sorting or grouping
by increasing the value of @code{max_sort_length} at runtime. Any client
can change the value of its session @code{max_sort_length} variable:

@example
mysql> SET max_sort_length = 2000;
mysql> SELECT id, comment FROM @var{tbl_name}
    -> ORDER BY comment;
@end example

Another way to use @code{GROUP BY} or @code{ORDER BY} on a @code{BLOB} or
@code{TEXT} column containing long values when you want more than
@code{max_sort_length} bytes to be significant is to convert the column
value into a fixed-length object. The standard way to do this is with the
@code{SUBSTRING} function.  For example, the following statement causes
2000 bytes of the @code{comment} column to be taken into account for sorting:

@example
mysql> SELECT id, SUBSTRING(comment,1,2000) FROM @var{tbl_name}
    -> ORDER BY SUBSTRING(comment,1,2000);
@end example

Before MySQL 3.23.2, you can group on an expression involving @code{BLOB} or
@code{TEXT} values by using a column alias or by specifying the column
position:

@example
mysql> SELECT id, SUBSTRING(comment,1,2000) AS b
    -> FROM @var{tbl_name} GROUP BY b;
mysql> SELECT id, SUBSTRING(comment,1,2000)
    -> FROM @var{tbl_name} GROUP BY 2;
@end example

@item
The maximum size of a @code{BLOB} or @code{TEXT} object is determined by its
type, but the largest value you actually can transmit between the client and
server is determined by the amount of available memory and the size of the
communications buffers.  You can change the message buffer size by changing
the value of the
@code{max_allowed_packet} variable, but you must
do so for both the server and your client program.
For example, both @command{mysql} and @command{mysqldump} allow you to change the
client-side
@code{max_allowed_packet} value.
See
@ref{Server parameters},
@ref{mysql,  , @command{mysql}},
and
@ref{mysqldump,  , @command{mysqldump}}.
@end itemize

Each @code{BLOB} or @code{TEXT} value is represented
internally by a separately allocated object. This is in contrast to all
other column types, for which storage is allocated once per column when
the table is opened.


@node ENUM, SET, BLOB, String types
@subsection The @code{ENUM} Type

@tindex ENUM

An @code{ENUM} is a string object with a value chosen from a list
of allowed values that are enumerated explicitly in the column specification
at table creation time.

The value may also be the empty string (@code{''}) or @code{NULL} under
certain circumstances:

@itemize @bullet
@item
If you insert an invalid value into an @code{ENUM} (that is, a string not
present in the list of allowed values), the empty string is inserted
instead as a special error value. This string can be distinguished from a
``normal'' empty string by the fact that this string has the numerical value
0. More about this later.

@item
If an @code{ENUM} column is declared to allow @code{NULL}, the @code{NULL}
value is a legal value for the column, and the default value is @code{NULL}.
If an @code{ENUM} column is declared @code{NOT NULL}, its default value
is the first element of the list of allowed values.
@end itemize

Each enumeration value has an index:

@itemize @bullet
@item
Values from the list of allowable elements in the column specification are
numbered beginning with 1.

@item
The index value of the empty string error value is 0.  This means that you
can use the following @code{SELECT} statement to find rows into which invalid
@code{ENUM} values were assigned:

@example
mysql> SELECT * FROM @var{tbl_name} WHERE @var{enum_col}=0;
@end example

@item
The index of the @code{NULL} value is @code{NULL}.
@end itemize

For example, a column specified as @code{ENUM('one', 'two', 'three')} can
have any of the values shown here.  The index of each value is also shown:

@multitable @columnfractions .15 .15
@item @strong{Value} @tab @strong{Index}
@item @code{NULL}    @tab @code{NULL}
@item @code{''}      @tab 0
@item @code{'one'}   @tab 1
@item @code{'two'}   @tab 2
@item @code{'three'} @tab 3
@end multitable

An enumeration can have a maximum of 65,535 elements.

Starting from MySQL 3.23.51, trailing spaces are automatically deleted from
@code{ENUM} member values when the table is created.

Lettercase is irrelevant when you assign values to an @code{ENUM} column.
However, values retrieved from the column later are displayed using the
lettercase that was used in the column definition.

If you retrieve an @code{ENUM} value in a numeric context, the column value's
index is returned.  For example, you can retrieve numeric values from
an @code{ENUM} column like this:

@example
mysql> SELECT @var{enum_col}+0 FROM @var{tbl_name};
@end example

If you store a number into an @code{ENUM} column, the number is treated as an
index, and the value stored is the enumeration member with that index.
(However, this will not work with @code{LOAD DATA}, which treats all
input as strings.)
It's not advisable to define an @code{ENUM} column with enumeration values
that look like numbers, because this can easily become confusing. For example,
the following column has enumeration members with string values of
@code{'0'}, @code{'1'}, and @code{'2'},
but numeric index values of
@code{1}, @code{2}, and @code{3}:

@example
numbers ENUM('0','1','2')
@end example

@code{ENUM} values are sorted according to the order in which the enumeration
members were listed in the column specification.  (In other words,
@code{ENUM} values are sorted according to their index numbers.)  For
example, @code{'a'} sorts before @code{'b'} for @code{ENUM('a', 'b')}, but
@code{'b'} sorts before @code{'a'} for @code{ENUM('b', 'a')}.  The empty
string sorts before non-empty strings, and @code{NULL} values sort before
all other enumeration values.
To prevent unexpected results, specify the @code{ENUM} list in alphabetical
order. You can also use @code{GROUP BY CAST(col AS VARCHAR)} or
@code{GROUP BY CONCAT(col)} to make sure that the column
is sorted lexically rather than by index number.

If you want to determine all possible values for an @code{ENUM} column,
use @code{SHOW COLUMNS FROM @var{tbl_name} LIKE @var{enum_col}} and parse
the @code{ENUM} definition in the second column of the output.


@node SET,  , ENUM, String types
@subsection The @code{SET} Type

@tindex SET

A @code{SET} is a string object that can have zero or more values, each of
which must be chosen from a list of allowed values specified when the table
is created.  @code{SET} column values that consist of multiple set members
are specified with members separated by commas (@samp{,}).  A consequence of
this is that @code{SET} member values cannot themselves contain commas.

For example, a column specified as @code{SET('one', 'two') NOT NULL} can have
any of these values:

@example
''
'one'
'two'
'one,two'
@end example


A @code{SET} can have a maximum of 64 different members.

Starting from MySQL 3.23.51, trailing spaces are automatically deleted from
@code{SET} member values when the table is created.

MySQL stores @code{SET} values numerically, with the low-order bit
of the stored value corresponding to the first set member.  If you retrieve a
@code{SET} value in a numeric context, the value retrieved has bits set
corresponding to the set members that make up the column value.  For example,
you can retrieve numeric values from a @code{SET} column like this:

@example
mysql> SELECT @var{set_col}+0 FROM @var{tbl_name};
@end example

If a number is stored into a @code{SET} column, the bits that
are set in the binary representation of the number determine the
set members in the column value.  For a column specified as
@code{SET('a','b','c','d')}, the members have the following decimal and
binary values:

@multitable @columnfractions .15 .20 .20
@item @code{SET} @strong{Member} @tab @strong{Decimal Value} @tab @strong{Binary Value}
@item @code{'a'} @tab @code{1} @tab @code{0001}
@item @code{'b'} @tab @code{2} @tab @code{0010}
@item @code{'c'} @tab @code{4} @tab @code{0100}
@item @code{'d'} @tab @code{8} @tab @code{1000}
@end multitable

If you assign a value of @code{9} to this column, that is @code{1001} in
binary, so the first and fourth @code{SET} value members @code{'a'} and
@code{'d'} are selected and the resulting value is @code{'a,d'}.

For a value containing more than one @code{SET} element, it does not matter
what order the elements are listed in when you insert the value.  It also
does not matter how many times a given element is listed in the value.
When the value is retrieved later, each element in the value will appear
once, with elements listed according to the order in which they were
specified at table creation time.  If a column is specified as
@code{SET('a','b','c','d')}, then @code{'a,d'}, @code{'d,a'}, and
@code{'d,a,a,d,d'} all will appear as @code{'a,d'} when retrieved.

If you set a @code{SET} column to an unsupported value, the value will
be ignored.

@code{SET} values are sorted numerically.  @code{NULL} values sort before
non-@code{NULL} @code{SET} values.

Normally, you search for @code{SET} values using
the @code{FIND_IN_SET()} function or the @code{LIKE} operator:

@example
mysql> SELECT * FROM @var{tbl_name} WHERE FIND_IN_SET('@var{value}',@var{set_col})>0;
mysql> SELECT * FROM @var{tbl_name} WHERE @var{set_col} LIKE '%@var{value}%';
@end example

The first statement finds rows where @var{set_col} contains the
@var{value} set member. The second is similar, but not the same:
It finds rows where @var{set_col} contains @var{value} anywhere, even as a
substring of another set member.

The following statements also are legal:

@example
mysql> SELECT * FROM @var{tbl_name} WHERE @var{set_col} & 1;
mysql> SELECT * FROM @var{tbl_name} WHERE @var{set_col} = '@var{val1},@var{val2}';
@end example

The first of these statements looks for values containing the first set
member.  The second looks for an exact match. Be careful with comparisons
of the second type. Comparing set values to @code{'@var{val1},@var{val2}'} will
return different results than comparing values to @code{'@var{val2},@var{val1}'}.
You should specify the values in the same order they are listed in the
column definition.

If you want to determine all possible values for a @code{SET} column,
use @code{SHOW COLUMNS FROM @var{tbl_name} LIKE @var{set_col}} and parse
the @code{SET} definition in the second column of the output.


@node Storage requirements, Choosing types, String types, Column types
@section Column Type Storage Requirements

@cindex storage requirements, column type
@cindex columns, storage requirements

The storage requirements for each of the column types supported by
MySQL are listed by category.

@cindex MyISAM, size
The maximum size of a row in a @code{MyISAM} table is 65,534 bytes. Each 
@code{BLOB} and @code{TEXT} column accounts for only five to nine bytes 
toward this size.

If a @code{MyISAM} or @code{ISAM} table includes any variable-length column
types, the record format will also be variable length.  When a table
is created, MySQL may, under certain conditions, change a column from a
variable-length type to a fixed-length type or vice versa.  @xref{Silent
column changes}.

@cindex numeric types
@cindex types, numeric

@subheading Storage Requirements for Numeric Types

@multitable @columnfractions .40 .60
@item @strong{Column Type} @tab @strong{Storage Required}
@item @code{TINYINT}       @tab 1 byte
@item @code{SMALLINT}      @tab 2 bytes
@item @code{MEDIUMINT}     @tab 3 bytes
@item @code{INT}, @code{INTEGER}       @tab 4 bytes
@item @code{BIGINT}        @tab 8 bytes
@item @code{FLOAT(@var{p})}      @tab 4 bytes if 0 <= @var{p} <= 24, 8 bytes if 25 <= @var{p} <= 53
@item @code{FLOAT}         @tab 4 bytes
@item @code{DOUBLE [PRECISION]}, item @code{REAL}         @tab 8 bytes
@item @code{DECIMAL(@var{M},@var{D})}, @code{NUMERIC(@var{M},@var{D})} @tab @var{M}+2 bytes if @var{D} > 0, @code{@var{M}+1} bytes if @var{D} = 0 (@var{D}+2, if @code{@var{M} < @var{D}})
@end multitable

@cindex date types
@cindex time types
@cindex types, date
@cindex types, time

@subheading Storage Requirements for Date and Time Types

@multitable @columnfractions .40 .60
@item @strong{Column Type} @tab @strong{Storage Required}
@item @code{DATE}          @tab 3 bytes
@item @code{DATETIME}      @tab 8 bytes
@item @code{TIMESTAMP}     @tab 4 bytes
@item @code{TIME}          @tab 3 bytes
@item @code{YEAR}          @tab 1 byte
@end multitable

@subheading Storage Requirements for String Types

@multitable @columnfractions .40 .60
@item @strong{Column Type} @tab @strong{Storage Required}
@item @code{CHAR(@var{M})} @tab @code{@var{M}} bytes, 0 @code{<= @var{M} <=} 255
@item @code{VARCHAR(@var{M})} @tab @var{L}+1 bytes, where @code{@var{L} <= @var{M}} and 0 @code{<= @var{M} <=} 255
@item @code{TINYBLOB}, @code{TINYTEXT} @tab @var{L}+1 bytes,
where @var{L} < 2^8
@item @code{BLOB}, @code{TEXT} @tab @var{L}+2 bytes,
where @var{L} < 2^16
@item @code{MEDIUMBLOB}, @code{MEDIUMTEXT} @tab @var{L}+3 bytes,
where @var{L} < 2^24
@item @code{LONGBLOB}, @code{LONGTEXT} @tab @var{L}+4 bytes,
where @var{L} < 2^32
@item @code{ENUM('@var{value1}','@var{value2}',...)} @tab 1 or 2 bytes, depending on
the number of enumeration values (65,535 values maximum)
@item @code{SET('@var{value1}','@var{value2}',...)} @tab 1, 2, 3, 4, or 8 bytes, depending
on the number of set members (64 members maximum)
@end multitable

@cindex @code{BLOB}, size
@cindex @code{TEXT}, size
@cindex @code{VARCHAR}, size

@code{VARCHAR} and the @code{BLOB} and @code{TEXT} types are variable-length
types. For each, the storage requirements depend on the actual length of
column values (represented by @var{L} in the preceding table), rather than
on the type's maximum possible size.  For example, a @code{VARCHAR(10)}
column can hold a string with a maximum length of 10 characters.  The actual
storage required is the length of the string (@var{L}), plus 1 byte to
record the length of the string.  For the string @code{'abcd'}, @var{L} is 4
and the storage requirement is 5 bytes.

The @code{BLOB} and @code{TEXT} types require 1, 2, 3, or 4 bytes to record
the length of the column value, depending on the maximum possible length of
the type.  @xref{BLOB,  , @code{BLOB}}.

@cindex ENUM, size
The size of an @code{ENUM} object is determined by the number of
different enumeration values.  One byte is used for enumerations with up
to 255 possible values.  Two bytes are used for enumerations with up to
65,535 values. @xref{ENUM,  , @code{ENUM}}.

@cindex SET, size
The size of a @code{SET} object is determined by the number of different
set members.  If the set size is @var{N}, the object occupies @code{(@var{N}+7)/8}
bytes, rounded up to 1, 2, 3, 4, or 8 bytes.  A @code{SET} can have a maximum
of 64 members. @xref{SET,  , @code{SET}}.



@node Choosing types, Other-vendor column types, Storage requirements, Column types
@section Choosing the Right Type for a Column

@cindex types, columns
@cindex choosing types

For the most efficient use of storage, try to use the most precise type in
all cases. For example, if an integer column will be used for values in the
range from @code{1} to @code{99999}, @code{MEDIUMINT UNSIGNED} is the
best type.  Of the types that represent all the required values, it uses
the least amount of storage.

Accurate representation of monetary values is a common problem. In MySQL,
you should use the @code{DECIMAL} type. This is stored as a string, so no
loss of accuracy should occur.  (Calculations on @code{DECIMAL} values may
still be done using double-precision operations, however.)  If accuracy
is not too important, the @code{DOUBLE} type may also be good enough.

For high precision, you can always convert to a fixed-point type stored
in a @code{BIGINT}. This allows you to do all calculations with integers
and convert results back to floating-point values only when necessary.


@node Other-vendor column types,  , Choosing types, Column types
@section Using Column Types from Other Database Engines

@cindex types, portability
@cindex portability, types
@cindex columns, other types

To make it easier to use code written for SQL implementations from other
vendors, MySQL maps column types as shown in the following table.  These
mappings make it easier to import table definitions from other database engines
into MySQL:

@multitable @columnfractions .35 .35
@item @strong{Other Vendor Type}        @tab @strong{MySQL Type}
@item @code{BINARY(@var{M})}            @tab @code{CHAR(@var{M}) BINARY}
@item @code{CHAR VARYING(@var{M})}      @tab @code{VARCHAR(@var{M})}
@item @code{FLOAT4}                     @tab @code{FLOAT}
@item @code{FLOAT8}                     @tab @code{DOUBLE}
@item @code{INT1}                       @tab @code{TINYINT}
@item @code{INT2}                       @tab @code{SMALLINT}
@item @code{INT3}                       @tab @code{MEDIUMINT}
@item @code{INT4}                       @tab @code{INT}
@item @code{INT8}                       @tab @code{BIGINT}
@item @code{LONG VARBINARY}             @tab @code{MEDIUMBLOB}
@item @code{LONG VARCHAR}               @tab @code{MEDIUMTEXT}
@item @code{LONG}                       @tab @code{MEDIUMTEXT} (MySQL 4.1.0 on)
@item @code{MIDDLEINT}                  @tab @code{MEDIUMINT}
@item @code{VARBINARY(@var{M})}         @tab @code{VARCHAR(@var{M}) BINARY}
@end multitable

Column type mapping occurs at table creation time, after which the original
type specifications are discarded.  If you create a table with types used
by other vendors and then issue a @code{DESCRIBE @var{tbl_name}} statement,
MySQL reports the table structure using the equivalent MySQL types.


@node Functions, SQL Syntax, Column types, Top
@chapter Functions and Operators

@cindex functions for @code{SELECT} and @code{WHERE} clauses
@cindex functions
@cindex operators

@c help_category Functions

Expressions can be used at several points in SQL statements, such as in the
@code{ORDER BY} or @code{HAVING} clauses of @code{SELECT} statements, in the
@code{WHERE} clause of a @code{SELECT}, @code{DELETE}, or @code{UPDATE}
statement, or in @code{SET} statements.  Expressions can be written using
literal values, column values, @code{NULL}, functions, and operators.
This chapter describes the functions and operators that are allowed for
writing expressions in MySQL.

An expression that contains @code{NULL} always produces a @code{NULL} value
unless otherwise indicated in the documentation for a particular function or
operator.

@strong{Note}: By default, there must be no whitespace between a function
name and the parenthesis following it. This helps the MySQL parser
distinguish between function calls and references to tables or columns that
happen to have the same name as a function.  Spaces around function
arguments are permitted, though.

You can tell the MySQL server to accept spaces after function names by
starting it with the @code{--sql-mode=IGNORE_SPACE} option. Individual client
programs can request this behavior by using the
@code{CLIENT_IGNORE_SPACE} option for @code{mysql_real_connect()}.
In either case, all function names will become reserved words.
@xref{Server SQL mode}.

@need 2000
For the sake of brevity, most examples in this chapter display the output
from the @command{mysql} program in abbreviated form.  Instead of showing
examples in this format:

@example
mysql> SELECT MOD(29,9);
+-----------+
| mod(29,9) |
+-----------+
|         2 |
+-----------+
1 rows in set (0.00 sec)
@end example

This format is used instead:

@example
mysql> SELECT MOD(29,9);
        -> 2
@end example

@menu
* Non-typed Operators::         Operators
* Control flow functions::      Control Flow Functions
* String functions::            String Functions
* Numeric Functions::           Numeric Functions
* Date and time functions::     Date and Time Functions
* Fulltext Search::             Full-Text Search Functions
* Cast Functions::              Cast Functions and Operators
* Other Functions::             Other Functions
* Group by functions and modifiers::  Functions and Modifiers for Use with @code{GROUP BY} Clauses
@end menu

@c TODO: rename node to Operators

@node Non-typed Operators, Control flow functions, Functions, Functions
@section Operators

@menu
* Operator Precedence::         Operator Precedence
* Parentheses::                 Parentheses
* Comparison Operators::        Comparison Functions and Operators
* Logical Operators::           Logical Operators
@end menu


@node Operator Precedence, Parentheses, Non-typed Operators, Non-typed Operators
@subsection Operator Precedence

Operator precedences are shown in the following list, from lowest precedence
to the highest. Operators that are shown together on a line have the same
precedence.

@example
:=
||, OR, XOR
&&, AND
NOT
BETWEEN, CASE, WHEN, THEN, ELSE
=, <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN
|
&
<<, >>
-, +
*, /, DIV, %, MOD
^
- (unary minus), ~ (unary bit inversion)
!
BINARY, COLLATE
@end example

The precedence shown for @code{NOT} is as of MySQL 5.0.2.  For earlier
versions, or from 5.0.2 on if the @code{HIGH_NOT_PRECEDENCE} SQL mode is
enabled, the precedence of @code{NOT} is the same as that of the @code{!}
operator.
@xref{Server SQL mode}.


@node Parentheses, Comparison Operators, Operator Precedence, Non-typed Operators
@subsection Parentheses

@findex () (parentheses)
@findex parentheses ( and )

@cindex functions, grouping
@cindex grouping, expressions

@table @code
@item ( ... )

Use parentheses to force the order of evaluation in an expression.  For
example:

@example
mysql> SELECT 1+2*3;
        -> 7
mysql> SELECT (1+2)*3;
        -> 9
@end example

@end table

@node Comparison Operators, Logical Operators, Parentheses, Non-typed Operators
@subsection Comparison Functions and Operators

@findex comparison operators
@c help_category Comparison operators@Functions

@cindex casts
@cindex type conversions

Comparison operations result in a value of @code{1} (TRUE), @code{0} (FALSE),
or @code{NULL}. These operations work for both numbers and strings.  Strings
are automatically converted to numbers and numbers to strings as necessary.

Some of the functions in this section (such as @code{LEAST()} and
@code{GREATEST()})  return values other than @code{1} (TRUE), @code{0}
(FALSE), or @code{NULL}. However, the value they return is based on
comparison operations performed as described by the following rules.

MySQL compares values using the following rules:

@itemize @bullet
@item
If one or both arguments are @code{NULL}, the result of the comparison is
@code{NULL}, except for the @code{NULL}-safe @code{<=>} equality comparison
operator.

@item
If both arguments in a comparison operation are strings, they are compared as
strings.

@item
If both arguments are integers, they are compared as integers.

@item
Hexadecimal values are treated as binary strings if not compared to a number.

@item
@cindex ODBC compatibility
@cindex compatibility, with ODBC
If one of the arguments is a @code{TIMESTAMP} or @code{DATETIME} column and
the other argument is a constant, the constant is converted
to a timestamp before the comparison is performed. This is done to be more
ODBC-friendly. Note that this is not done for arguments in @code{IN()}!
To be safe, always use complete datetime/date/time strings when doing
comparisons.

@item
In all other cases, the arguments are compared as floating-point (real)
numbers.
@end itemize

By default, string comparisons are not case sensitive and use the
current character set (ISO-8859-1 Latin1 by default, which also works
excellently for English).

To convert a value to a specific type for comparison purposes, you can
use the @code{CAST()} function.  String values can be converted to a
different character set using @code{CONVERT()}.
@xref{Cast Functions}.

The following examples illustrate conversion of strings to numbers for
comparison operations:

@example
mysql> SELECT 1 > '6x';
        -> 0
mysql> SELECT 7 > '6x';
        -> 1
mysql> SELECT 0 > 'x6';
        -> 0
mysql> SELECT 0 = 'x6';
        -> 1
@end example

Note that when you are comparing a string column with a number, MySQL can't
use an index on the column to quickly look up the value.  If @var{str_col}
is an indexed string column, the index cannot be used when performing the
lookup in the following statement:

@example
SELECT * FROM @var{tbl_name} WHERE @var{str_col}=1;
@end example

The reason for this is that there are many different strings that may
convert to the value @code{1}:  @code{'1'}, @code{'@ 1'}, @code{'1a'}, ...

@table @code

@c description_for_help_topic =
@item =
@findex = (equal)
@findex equal (=)
Equal:
@c end_description_for_help_topic

@c example_for_help_topic =
@example
mysql> SELECT 1 = 0;
        -> 0
mysql> SELECT '0' = 0;
        -> 1
mysql> SELECT '0.0' = 0;
        -> 1
mysql> SELECT '0.01' = 0;
        -> 0
mysql> SELECT '.01' = 0.01;
        -> 1
@end example

@c description_for_help_topic <=>
@item <=>
@cindex @code{NULL}, testing for null
@findex <=> (equal to)
@code{NULL}-safe equal.
This operator performs an equality comparison like the @code{=} operator, but
returns @code{1} rather than @code{NULL} if both operands are @code{NULL},
and @code{0} rather than @code{NULL} if one operand is @code{NULL}.
@c end_description_for_help_topic

@c example_for_help_topic <=>
@example
mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
        -> 1, 1, 0
mysql> SELECT 1 = 1, NULL = NULL, 1 = NULL;
        -> 1, NULL, NULL
@end example

@code{<=>} was added in MySQL 3.23.0.

@c description_for_help_topic !=  <>
@item <>
@itemx !=
@findex <> (not equal)
@findex not equal (<>)
@findex != (not equal)
@findex not equal (!=)
Not equal:
@c end_description_for_help_topic

@c example_for_help_topic !=
@example
mysql> SELECT '.01' <> '0.01';
        -> 1
mysql> SELECT .01 <> '0.01';
        -> 0
mysql> SELECT 'zapp' <> 'zappp';
        -> 1
@end example

@c description_for_help_topic <=
@item <=
@findex <= (less than or equal)
@findex less than or equal (<=)
Less than or equal:
@c end_description_for_help_topic

@c example_for_help_topic <=
@example
mysql> SELECT 0.1 <= 2;
        -> 1
@end example

@c description_for_help_topic <
@item <
@findex < (less than)
@findex less than (<)
Less than:
@c end_description_for_help_topic

@c example_for_help_topic <
@example
mysql> SELECT 2 < 2;
        -> 0
@end example

@c description_for_help_topic >=
@item >=
@findex >= (greater than or equal)
@findex greater than or equal (>=)
Greater than or equal:
@c end_description_for_help_topic

@c example_for_help_topic >=
@example
mysql> SELECT 2 >= 2;
        -> 1
@end example

@c description_for_help_topic >
@item >
@findex > (greater than)
@findex greater than (>)
Greater than:
@c end_description_for_help_topic

@c example_for_help_topic >
@example
mysql> SELECT 2 > 2;
        -> 0
@end example

@c description_for_help_topic IS
@item IS @var{boolean_value}
@itemx IS NOT @var{boolean_value}
@cindex @code{TRUE}, testing for
@cindex @code{FALSE}, testing for
@cindex @code{UNKNOWN}, testing for
@findex IS boolean_value
@findex IS NOT boolean_value
Tests whether a value against a boolean value, where @var{boolean_value} can
be @code{TRUE}, @code{FALSE}, or @code{UNKNOWN}.
@c end_description_for_help_topic

@c example_for_help_topic IS
@example
mysql> SELECT 1 IS TRUE, 0 IS FALSE, NULL IS UNKNOWN;
        -> 1, 1, 1
mysql> SELECT 1 IS NOT UNKNOWN, 0 IS NOT UNKNOWN, NULL IS NOT UNKNOWN;
        -> 1, 1, 0
@end example

@code{IS [NOT] @var{boolean_value}} syntax was added in MySQL 5.0.2.

@c description_for_help_topic IS NULL  NULL IS
@item IS NULL
@itemx IS NOT NULL
@cindex @code{NULL}, testing for null
@findex IS NULL
@findex IS NOT NULL
Tests whether a value is or is not @code{NULL}.
@c end_description_for_help_topic

@c example_for_help_topic IS NULL
@example
mysql> SELECT 1 IS NULL, 0 IS NULL, NULL IS NULL;
        -> 0, 0, 1
mysql> SELECT 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
        -> 1, 1, 0
@end example

@cindex ODBC compatibility
@cindex compatibility, with ODBC
To be able to work well with ODBC programs, MySQL supports the following
extra features when using @code{IS NULL}:

@itemize @bullet
@item
You can find the row that contains the most recent @code{AUTO_INCREMENT} value
by issuing a statement of the following form immediately after generating the
value:

@example
SELECT * FROM @var{tbl_name} WHERE @var{auto_col} IS NULL
@end example

This behavior can be disabled by setting @code{SQL_AUTO_IS_NULL=0}.
@xref{SET OPTION, , @code{SET OPTION}}.

@item
For @code{DATE} and @code{DATETIME} columns that are declared as @code{NOT
NULL}, you can find the special date @code{'0000-00-00'} by using a statement
like this:

@example
SELECT * FROM @var{tbl_name} WHERE @var{date_column} IS NULL
@end example

This is needed to get some ODBC applications to work because ODBC doesn't
support a @code{'0000-00-00'} date value.

@end itemize

@c description_for_help_topic BETWEEN AND  BETWEEN AND
@item @var{expr} BETWEEN @var{min} AND @var{max}
@findex BETWEEN ... AND
If @var{expr} is greater than or equal to @var{min} and @var{expr} is
less than or equal to @var{max}, @code{BETWEEN} returns @code{1},
otherwise it returns @code{0}.  This is equivalent to the expression
@code{(@var{min} <= @var{expr} AND @var{expr} <= @var{max})} if all the arguments are of the
same type. Otherwise type conversion takes place according to the rules
described at the beginning of this section, but applied to all the three
arguments. @strong{Note}: Before MySQL
4.0.5, arguments were converted to the type of @var{expr} instead.

@c end_description_for_help_topic

@c example_for_help_topic BETWEEN AND
@example
mysql> SELECT 1 BETWEEN 2 AND 3;
        -> 0
mysql> SELECT 'b' BETWEEN 'a' AND 'c';
        -> 1
mysql> SELECT 2 BETWEEN 2 AND '3';
        -> 1
mysql> SELECT 2 BETWEEN 2 AND 'x-3';
        -> 0
@end example

@c description_for_help_topic NOT BETWEEN
@item @var{expr} NOT BETWEEN @var{min} AND @var{max}
@findex NOT BETWEEN
This is the same as @code{NOT (@var{expr} BETWEEN @var{min} AND @var{max})}.
@c end_description_for_help_topic

@c description_for_help_topic COALESCE
@item COALESCE(@var{value},...)
@cindex @code{NULL}, testing for null
@findex COALESCE()
Returns the first non-@code{NULL} value in the list.
@c end_description_for_help_topic

@c example_for_help_topic COALESCE
@example
mysql> SELECT COALESCE(NULL,1);
        -> 1
mysql> SELECT COALESCE(NULL,NULL,NULL);
        -> NULL
@end example

@code{COALESCE()} was added in MySQL 3.23.3.


@c description_for_help_topic GREATEST
@item GREATEST(@var{value1},@var{value2},...)
@findex GREATEST()
With two or more arguments, returns the largest (maximum-valued) argument.
The arguments are compared using the same rules as for @code{LEAST()}.
@c end_description_for_help_topic

@c example_for_help_topic GREATEST
@example
mysql> SELECT GREATEST(2,0);
        -> 2
mysql> SELECT GREATEST(34.0,3.0,5.0,767.0);
        -> 767.0
mysql> SELECT GREATEST('B','A','C');
        -> 'C'
@end example
Before MySQL 3.22.5, you can use @code{MAX()}
instead of @code{GREATEST()}.

@c description_for_help_topic IN
@item @var{expr} IN (@var{value},...)
@findex IN
Returns @code{1} if @var{expr} is any of the values in the @code{IN} list,
else returns @code{0}.  If all values are constants, they are
evaluated according to the type of @var{expr} and sorted. The search for the
item then is done using a binary search. This means @code{IN} is very quick
if the @code{IN} value list consists entirely of constants.  If @var{expr}
is a case-sensitive string expression, the string comparison is performed in
case-sensitive fashion.
@c end_description_for_help_topic

@c example_for_help_topic IN
@example
mysql> SELECT 2 IN (0,3,5,'wefwf');
        -> 0
mysql> SELECT 'wefwf' IN (0,3,5,'wefwf');
        -> 1
@end example

The number of values in the @code{IN} list is only limited by the
@code{max_allowed_packet} value.

To comply with the SQL standard,
from MySQL 4.1 on
@code{IN} returns @code{NULL} 
not only if the expression on the left hand side is @code{NULL}, but also if
no match is found in the list and one of the expressions in the list is 
@code{NULL}.

From MySQL 4.1 on, @code{IN()} syntax also is used to write certain types of
subqueries.
@xref{ANY IN SOME subqueries,  , @code{ANY IN SOME} subqueries}.

@c description_for_help_topic NOT IN
@item @var{expr} NOT IN (@var{value},...)
@findex NOT IN
This is the same as @code{NOT (@var{expr} IN (@var{value},...))}.
@c end_description_for_help_topic

@c description_for_help_topic ISNULL
@item ISNULL(@var{expr})
@findex ISNULL()
If @var{expr} is @code{NULL}, @code{ISNULL()} returns @code{1}, otherwise
it returns @code{0}.
@c end_description_for_help_topic

@c example_for_help_topic ISNULL
@example
mysql> SELECT ISNULL(1+1);
        -> 0
mysql> SELECT ISNULL(1/0);
        -> 1
@end example

Note that a comparison of @code{NULL} values using @code{=} will always be
false!

@c description_for_help_topic INTERVAL
@item INTERVAL(@var{N},@var{N1},@var{N2},@var{N3},...)
@findex INTERVAL()
Returns @code{0} if @var{N} < @var{N1}, @code{1} if @var{N} < @var{N2}
and so on or @code{-1} if @var{N} is @code{NULL}. All arguments are treated
as integers.  It is required that @var{N1} < @var{N2} < @var{N3} < 
@code{...} < @var{Nn} for this function to work correctly. This is because
a binary search is used (very fast).
@c end_description_for_help_topic

@c example_for_help_topic INTERVAL
@example
mysql> SELECT INTERVAL(23, 1, 15, 17, 30, 44, 200);
        -> 3
mysql> SELECT INTERVAL(10, 1, 10, 100, 1000);
        -> 2
mysql> SELECT INTERVAL(22, 23, 30, 44, 200);
        -> 0
@end example


@c description_for_help_topic LEAST
@item LEAST(@var{value1},@var{value2},...)
@findex LEAST()
With two or more arguments, returns the smallest (minimum-valued) argument.
The arguments are compared using the following rules.

@itemize @bullet
@item
If the return value is used in an @code{INTEGER} context or all arguments
are integer-valued, they are compared as integers.

@item
If the return value is used in a @code{REAL} context or all arguments are
real-valued, they are compared as reals.

@item
If any argument is a case-sensitive string, the arguments are compared
as case-sensitive strings.

@item
In other cases, the arguments are compared as case-insensitive strings.
@end itemize
@c end_description_for_help_topic

@c example_for_help_topic LEAST
@example
mysql> SELECT LEAST(2,0);
        -> 0
mysql> SELECT LEAST(34.0,3.0,5.0,767.0);
        -> 3.0
mysql> SELECT LEAST('B','A','C');
        -> 'A'
@end example
Before MySQL 3.22.5, you can use @code{MIN()}
instead of @code{LEAST()}.

Note that the preceding conversion rules can produce strange results in some
borderline cases:

@example
mysql> SELECT CAST(LEAST(3600, 9223372036854775808.0) as SIGNED);
        -> -9223372036854775808
@end example

This happens because MySQL reads @code{9223372036854775808.0} in an
integer context. The integer representation is not good enough to
hold the value, so it wraps to a signed integer.

@end table

@node Logical Operators,  , Comparison Operators, Non-typed Operators
@subsection Logical Operators

@findex logical operators
@findex operators, logical
@c help_category Logical operators@Functions

In SQL, all logical operators evaluate to TRUE, FALSE, or @code{NULL} (UNKNOWN).
In MySQL, these are implemented as @code{1} (TRUE), @code{0} (FALSE),
and @code{NULL}. Most of this is common to different SQL database servers,
although some servers may return any non-zero value for TRUE.

@table @code

@c description_for_help_topic !  NOT
@item NOT
@itemx !
@findex NOT, logical
@findex ! (logical NOT)
Logical NOT.
Evaluates to @code{1} if the operand is @code{0},
to @code{0} if the operand is non-zero,
and @code{NOT NULL} returns @code{NULL}.
@c end_description_for_help_topic

@c example_for_help_topic !
@example
mysql> SELECT NOT 10;
        -> 0
mysql> SELECT NOT 0;
        -> 1
mysql> SELECT NOT NULL;
        -> NULL
mysql> SELECT ! (1+1);
        -> 0
mysql> SELECT ! 1+1;
        -> 1
@end example
The last example produces @code{1} because the expression evaluates
the same way as @code{(!1)+1}.

@c description_for_help_topic &&  AND
@item AND
@itemx &&
@findex AND, logical
@findex && (logical AND)
Logical AND.
Evaluates to @code{1} if all operands are non-zero and not @code{NULL},
to @code{0} if one or more operands are @code{0},
otherwise @code{NULL} is returned.
@c end_description_for_help_topic

@c example_for_help_topic &&
@example
mysql> SELECT 1 && 1;
        -> 1
mysql> SELECT 1 && 0;
        -> 0
mysql> SELECT 1 && NULL;
        -> NULL
mysql> SELECT 0 && NULL;
        -> 0
mysql> SELECT NULL && 0;
        -> 0
@end example

Please note that MySQL versions prior to 4.0.5 stop evaluation when
a @code{NULL} is encountered, rather than continuing the process to
check for possible @code{0} values. This means that in these versions,
@code{SELECT (NULL AND 0)} returns @code{NULL} instead of @code{0}.
As of MySQL 4.0.5, the code has been re-engineered so that the result is
always as prescribed by the SQL standards while still using the
optimization wherever possible.

@c description_for_help_topic ||  OR
@item OR
@itemx ||
@findex OR, logical
@findex || (logical OR)
Logical OR.
When both operands are non-@code{NULL}, the result is @code{1} if any
operand is non-zero, and @code{0} otherwise.  With a @code{NULL} operand,
the result is @code{1} if the other operand is non-zero, and @code{NULL}
otherwise.  If both operands are @code{NULL}, the result is @code{NULL}.
@c end_description_for_help_topic

@c example_for_help_topic ||
@example
mysql> SELECT 1 || 1;
        -> 1
mysql> SELECT 1 || 0;
        -> 1
mysql> SELECT 0 || 0;
        -> 0
mysql> SELECT 0 || NULL;
        -> NULL
mysql> SELECT 1 || NULL;
        -> 1
@end example

@c description_for_help_topic XOR
@item XOR
@findex XOR, logical
Logical XOR.
Returns @code{NULL} if either operand is @code{NULL}.
For non-@code{NULL} operands, evaluates to @code{1} if an odd number
of operands is non-zero,
otherwise @code{0} is returned.
@c end_description_for_help_topic

@c example_for_help_topic XOR
@example
mysql> SELECT 1 XOR 1;
        -> 0
mysql> SELECT 1 XOR 0;
        -> 1
mysql> SELECT 1 XOR NULL;
        -> NULL
mysql> SELECT 1 XOR 1 XOR 1;
        -> 1
@end example

@code{a XOR b} is mathematically equal to
@code{(a AND (NOT b)) OR ((NOT a) and b)}.

@code{XOR} was added in MySQL 4.0.2.
@end table


@node Control flow functions, String functions, Non-typed Operators, Functions
@section Control Flow Functions

@findex control flow functions
@findex functions, control flow
@c help_category Control flow functions@Functions

@table @code

@c description_for_help_topic CASE  WHEN THEN ELSE END
@item CASE @var{value} WHEN [@var{compare-value}] THEN @var{result} [WHEN [@var{compare-value}] THEN @var{result} ...] [ELSE @var{result}] END
@item CASE WHEN [@var{condition}] THEN @var{result} [WHEN [@var{condition}] THEN @var{result} ...] [ELSE @var{result}] END
@findex CASE

The first version returns the @var{result} where
@code{@var{value}=@var{compare-value}}. The second version returns the result for
the first condition that is true. If there was no matching result
value, the result after @code{ELSE} is returned, or @code{NULL} if there is no
@code{ELSE} part.
@c end_description_for_help_topic

@c example_for_help_topic CASE
@example
mysql> SELECT CASE 1 WHEN 1 THEN 'one'
    ->     WHEN 2 THEN 'two' ELSE 'more' END;
        -> 'one'
mysql> SELECT CASE WHEN 1>0 THEN 'true' ELSE 'false' END;
        -> 'true'
mysql> SELECT CASE BINARY 'B'
    ->     WHEN 'a' THEN 1 WHEN 'b' THEN 2 END;
        -> NULL
@end example

The type of the return value (@code{INTEGER}, @code{DOUBLE}, or
@code{STRING}) is the same as the type of the first returned value (the
expression after the first @code{THEN}).

@code{CASE} was added in MySQL 3.23.3.

@c description_for_help_topic IF
@item IF(@var{expr1},@var{expr2},@var{expr3})
@findex IF()
If @var{expr1} is TRUE (@code{@var{expr1} <> 0} and @code{@var{expr1} <> NULL}) then
@code{IF()} returns @var{expr2}, else it returns @var{expr3}.
@code{IF()} returns a numeric or string value, depending on the context
in which it is used.
@c end_description_for_help_topic

@c example_for_help_topic IF
@example
mysql> SELECT IF(1>2,2,3);
        -> 3
mysql> SELECT IF(1<2,'yes','no');
        -> 'yes'
mysql> SELECT IF(STRCMP('test','test1'),'no','yes');
        -> 'no'
@end example

If only one of @code{expr2} or @code{expr3} is explicitly @code{NULL}, the
result type of the @code{IF()} function is the type of non-@code{NULL}
expression.  (This behavior is new in MySQL 4.0.3.)

@code{expr1} is evaluated as an integer value, which means that if you are
testing floating-point or string values, you should do so using a comparison
operation.

@example
mysql> SELECT IF(0.1,1,0);
        -> 0
mysql> SELECT IF(0.1<>0,1,0);
        -> 1
@end example

In the first case shown, @code{IF(0.1)} returns @code{0} because @code{0.1}
is converted to an integer value, resulting in a test of @code{IF(0)}.  This
may not be what you expect.  In the second case, the comparison tests the
original floating-point value to see whether it is non-zero.  The result
of the comparison is used as an integer.

The default return type of @code{IF()} (which may matter when it is
stored into a temporary table) is calculated in MySQL
3.23 as follows:

@multitable @columnfractions .50 .20
@item @strong{Expression} @tab @strong{Return Value}
@item @code{expr2} or @code{expr3} returns a string @tab string
@item @code{expr2} or @code{expr3} returns a floating-point value @tab floating-point
@item @code{expr2} or @code{expr3} returns an integer @tab integer
@end multitable

If @code{expr2} and @code{expr3} are strings, the result is case
sensitive if either string is case sensitive (starting from MySQL
3.23.51).

@c description_for_help_topic IFNULL
@item IFNULL(@var{expr1},@var{expr2})
@cindex @code{NULL}, testing for null
@findex IFNULL()
If @var{expr1} is not @code{NULL}, @code{IFNULL()} returns @var{expr1},
else it returns @var{expr2}.  @code{IFNULL()} returns a numeric or string
value, depending on the context in which it is used.
@c end_description_for_help_topic

@c example_for_help_topic IFNULL
@example
mysql> SELECT IFNULL(1,0);
        -> 1
mysql> SELECT IFNULL(NULL,10);
        -> 10
mysql> SELECT IFNULL(1/0,10);
        -> 10
mysql> SELECT IFNULL(1/0,'yes');
        -> 'yes'
@end example

In MySQL 4.0.6 and above, the default result value of
@code{IFNULL(@var{expr1},@var{expr2})} is the more ``general'' of the two expressions,
in the order @code{STRING}, @code{REAL}, or @code{INTEGER}. The difference
from earlier MySQL versions is mostly notable when you create a table
based on expressions or MySQL has to internally store a value from
@code{IFNULL()} in a temporary table.

@example
CREATE TABLE tmp SELECT IFNULL(1,'test') AS test;
@end example

As of MySQL 4.0.6, the type for the @code{test} column is @code{CHAR(4)},
whereas in earlier versions the type would be @code{BIGINT}.

@c description_for_help_topic NULLIF
@item NULLIF(@var{expr1},@var{expr2})
@findex NULLIF()
Returns @code{NULL} if @code{@var{expr1} = @var{expr2}} is true, else returns @var{expr1}.
This is the same as @code{CASE WHEN @var{expr1} = @var{expr2} THEN NULL ELSE @var{expr1} END}.
@c end_description_for_help_topic

@c example_for_help_topic NULLIF
@example
mysql> SELECT NULLIF(1,1);
        -> NULL
mysql> SELECT NULLIF(1,2);
        -> 1
@end example

Note that MySQL evaluates @code{expr1} twice if the arguments are not equal.

@code{NULLIF()} was added in MySQL 3.23.15.

@end table

@node String functions, Numeric Functions, Control flow functions, Functions
@section String Functions

@c TODO: general 4.1 remarks about: lettercase and binary; collations

@findex string functions
@findex functions, string
@c help_category String Functions@Functions

String-valued functions return @code{NULL} if the length of the result would
be greater than the value of the @code{max_allowed_packet} system variable.
@xref{Server parameters}.

For functions that operate on string positions,
the first position is numbered 1.

@table @code

@c description_for_help_topic ASCII
@item ASCII(@var{str})
@findex ASCII()
Returns the numeric value of the leftmost character of the string
@var{str}. Returns @code{0} if @var{str} is the empty string.  Returns
@code{NULL} if @var{str} is @code{NULL}.
@code{ASCII()} works for characters with numeric values from @code{0} to
@code{255}.
@c end_description_for_help_topic

@c example_for_help_topic ASCII
@example
mysql> SELECT ASCII('2');
        -> 50
mysql> SELECT ASCII(2);
        -> 50
mysql> SELECT ASCII('dx');
        -> 100
@end example

See also the @code{ORD()} function.

@c description_for_help_topic BIN
@item BIN(@var{N})
@findex BIN()
Returns a string representation of the binary value of @var{N}, where
@var{N} is a longlong (@code{BIGINT}) number.  This is equivalent to
@code{CONV(@var{N},10,2)}.  Returns @code{NULL} if @var{N} is @code{NULL}.
@c end_description_for_help_topic

@c example_for_help_topic BIN
@example
mysql> SELECT BIN(12);
        -> '1100'
@end example

@c description_for_help_topic BIT_LENGTH
@item BIT_LENGTH(@var{str})
@findex BIT_LENGTH()
Returns the length of the string @var{str} in bits.
@c end_description_for_help_topic

@c example_for_help_topic BIT_LENGTH
@example
mysql> SELECT BIT_LENGTH('text');
        -> 32
@end example

@code{BIT_LENGTH()} was added in MySQL 4.0.2.

@c description_for_help_topic CHAR function
@item CHAR(@var{N},...)
@findex CHAR()
@code{CHAR()} interprets the arguments as integers and returns a string
consisting of the characters given by the code values of those
integers. @code{NULL} values are skipped.
@c end_description_for_help_topic

@c example_for_help_topic CHAR function
@example
mysql> SELECT CHAR(77,121,83,81,'76');
        -> 'MySQL'
mysql> SELECT CHAR(77,77.3,'77.3');
        -> 'MMM'
@end example

@c description_for_help_topic CHAR_LENGTH
@item CHAR_LENGTH(@var{str})
@findex CHAR_LENGTH()

Returns the length of the string @var{str}, measured in characters.
A multi-byte character counts as a single character.
This means that for a string containing five two-byte characters,
@code{LENGTH()} returns @code{10}, whereas @code{CHAR_LENGTH()} returns
@code{5}.
@c end_description_for_help_topic

@c description_for_help_topic CHARACTER_LENGTH
@item CHARACTER_LENGTH(@var{str})
@findex CHARACTER_LENGTH()

@code{CHARACTER_LENGTH()} is a synonym for @code{CHAR_LENGTH()}.
@c end_description_for_help_topic

@c description_for_help_topic COMPRESS
@item COMPRESS(@var{string_to_compress})
@findex COMPRESS()
Compresses a string. This function requires MySQL to have been compiled
with a compression library such as @code{zlib}. Otherwise, the return
value is always @code{NULL}. The compressed string can be uncompressed with
@code{UNCOMPRESS()}.
@c end_description_for_help_topic

@c example_for_help_topic COMPRESS
@example
mysql> SELECT LENGTH(COMPRESS(REPEAT('a',1000)));
        -> 21
mysql> SELECT LENGTH(COMPRESS(''));
        -> 0
mysql> SELECT LENGTH(COMPRESS('a'));
        -> 13
mysql> SELECT LENGTH(COMPRESS(REPEAT('a',16)));
        -> 15
@end example

The compressed string contents are stored the following way:
@itemize @bullet
@item
Empty strings are stored as empty strings.
@item
Non-empty strings are stored as a four-byte length of the uncompressed string
(low byte first), followed by the compressed string.  If the
string ends with space, an extra @samp{.} character is added to avoid
problems with endspace trimming should the result be stored in a @code{CHAR}
or @code{VARCHAR} column.  (Use of @code{CHAR} or @code{VARCHAR} to store
compressed strings is not recommended. It is better to use a @code{BLOB}
column instead.)
@end itemize

@code{COMPRESS()} was added in MySQL 4.1.1.


@c description_for_help_topic CONCAT
@item CONCAT(@var{str1},@var{str2},...)
@findex CONCAT()
Returns the string that results from concatenating the arguments.  Returns
@code{NULL} if any argument is @code{NULL}.  May have one or more arguments.
A numeric argument is converted to its equivalent string form.
@c end_description_for_help_topic

@c example_for_help_topic CONCAT
@example
mysql> SELECT CONCAT('My', 'S', 'QL');
        -> 'MySQL'
mysql> SELECT CONCAT('My', NULL, 'QL');
        -> NULL
mysql> SELECT CONCAT(14.3);
        -> '14.3'
@end example

@c description_for_help_topic CONCAT_WS
@item CONCAT_WS(@var{separator},@var{str1},@var{str2},...)
@findex CONCAT_WS()

@code{CONCAT_WS()} stands for CONCAT With Separator and is a special form of
@code{CONCAT()}.  The first argument is the separator for the rest of the
arguments.
The separator is added between the strings to be concatenated.
The separator can be a string as can the rest of the
arguments. If the separator is @code{NULL}, the result is @code{NULL}.
The function skips any @code{NULL} values after the
separator argument.
@c end_description_for_help_topic

@c example_for_help_topic CONCAT_WS
@example
mysql> SELECT CONCAT_WS(',','First name','Second name','Last Name');
        -> 'First name,Second name,Last Name'
mysql> SELECT CONCAT_WS(',','First name',NULL,'Last Name');
        -> 'First name,Last Name'
@end example

Before MySQL 4.0.14, @code{CONCAT_WS()} skips empty strings as well as
@code{NULL} values.

@c description_for_help_topic CONV
@item CONV(@var{N},@var{from_base},@var{to_base})
@findex CONV()
Converts numbers between different number bases.  Returns a string
representation of the number @var{N}, converted from base @var{from_base}
to base @var{to_base}.  Returns @code{NULL} if any argument is @code{NULL}.
The argument @var{N} is interpreted as an integer, but may be specified as
an integer or a string.  The minimum base is @code{2} and the maximum base is
@code{36}.  If @var{to_base} is a negative number, @var{N} is regarded as a
signed number.  Otherwise, @var{N} is treated as unsigned.  @code{CONV()} works
with 64-bit precision.
@c end_description_for_help_topic

@c example_for_help_topic CONV
@example
mysql> SELECT CONV('a',16,2);
        -> '1010'
mysql> SELECT CONV('6E',18,8);
        -> '172'
mysql> SELECT CONV(-17,10,-18);
        -> '-H'
mysql> SELECT CONV(10+'10'+'10'+0xa,10,10);
        -> '40'
@end example

@c description_for_help_topic ELT
@item ELT(@var{N},@var{str1},@var{str2},@var{str3},...)
@findex ELT()
Returns @var{str1} if @var{N} = @code{1}, @var{str2} if @var{N} =
@code{2}, and so on.  Returns @code{NULL} if @var{N} is less than @code{1}
or greater than the number of arguments.  @code{ELT()} is the complement of
@code{FIELD()}.
@c end_description_for_help_topic

@c example_for_help_topic ELT
@example
mysql> SELECT ELT(1, 'ej', 'Heja', 'hej', 'foo');
        -> 'ej'
mysql> SELECT ELT(4, 'ej', 'Heja', 'hej', 'foo');
        -> 'foo'
@end example

@c description_for_help_topic EXPORT_SET
@item EXPORT_SET(@var{bits},@var{on},@var{off}[,@var{separator}[,@var{number_of_bits}]])
@findex EXPORT_SET()
Returns a string in which for every bit set in the value @var{bits}, you
get an @var{on} string and for every reset bit you get an @var{off}
string.  Bits in @var{bits} are examined from right to left (from low-order
to high-order bits). Strings are added to the result from left to right,
separated by the @var{separator} string (default @samp{,}). The number of
bits examined is given by @var{number_of_bits} (default 64).
@c end_description_for_help_topic

@c example_for_help_topic EXPORT_SET
@example
mysql> SELECT EXPORT_SET(5,'Y','N',',',4);
        -> 'Y,N,Y,N'
mysql> SELECT EXPORT_SET(6,'1','0',',',10);
        -> '0,1,1,0,0,0,0,0,0,0'
@end example

@c description_for_help_topic FIELD
@item FIELD(@var{str},@var{str1},@var{str2},@var{str3},...)
@findex FIELD()
Returns the index of @var{str} in the @var{str1}, @var{str2},
@var{str3}, @code{...} list.
Returns @code{0} if @var{str} is not found.
If @var{str} is @code{NULL}, the return value is @code{0} because
@code{NULL} fails equality comparison with any value.
@code{FIELD()} is the complement of @code{ELT()}.
@c end_description_for_help_topic

@c example_for_help_topic FIELD
@example
mysql> SELECT FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo');
        -> 2
mysql> SELECT FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo');
        -> 0
@end example

@c description_for_help_topic FIND_IN_SET
@item FIND_IN_SET(@var{str},@var{strlist})
@findex FIND_IN_SET()
Returns a value @code{1} to @var{N} if the string @var{str} is in the string list
@var{strlist} consisting of @var{N} substrings. A string list is a string
composed of substrings separated by @samp{,} characters. If the first
argument is a constant string and the second is a column of type @code{SET},
the @code{FIND_IN_SET()} function is optimized to use bit arithmetic.
Returns @code{0} if @var{str} is not in @var{strlist} or if @var{strlist}
is the empty string.  Returns @code{NULL} if either argument is @code{NULL}.
This function will not work properly if the first argument contains a comma
(@samp{,}) character.
@c end_description_for_help_topic

@c example_for_help_topic FIND_IN_SET
@example
mysql> SELECT FIND_IN_SET('b','a,b,c,d');
        -> 2
@end example

@c description_for_help_topic HEX
@item HEX(@var{N_or_S})
@findex HEX()

If @var{N_OR_S} is a number, returns a string representation of the hexadecimal
value of @var{N}, where @var{N} is a longlong (@code{BIGINT}) number.
This is equivalent to @code{CONV(N,10,16)}.

From MySQL 4.0.1 and up,
if @var{N_OR_S} is a string, returns a hexadecimal string of @var{N_OR_S}
where each character in @var{N_OR_S} is converted to two hexadecimal digits.
@c end_description_for_help_topic

@c example_for_help_topic HEX
@example
mysql> SELECT HEX(255);
        -> 'FF'
mysql> SELECT 0x616263;
        -> 'abc'
mysql> SELECT HEX('abc');
        -> 616263
@end example

@c description_for_help_topic INSERT
@item INSERT(@var{str},@var{pos},@var{len},@var{newstr})
@findex INSERT()
Returns the string @var{str}, with the substring beginning at position
@var{pos} and @var{len} characters long replaced by the string
@var{newstr}.  Returns the original string if @var{pos} is not within
the length of the string.  Replaces the rest of the string from position
@var{pos} is @var{len} is not within the length of the rest of the string.
Returns @code{NULL} if any argument is null.
@c end_description_for_help_topic

@c example_for_help_topic INSERT
@example
mysql> SELECT INSERT('Quadratic', 3, 4, 'What');
        -> 'QuWhattic'
mysql> SELECT INSERT('Quadratic', -1, 4, 'What');
        -> 'Quadratic'
mysql> SELECT INSERT('Quadratic', 3, 100, 'What');
        -> 'QuWhat'
@end example

This function is multi-byte safe.

@c description_for_help_topic INSTR
@item INSTR(@var{str},@var{substr})
@findex INSTR()
Returns the position of the first occurrence of substring @var{substr} in
string @var{str}. This is the same as the two-argument form of
@code{LOCATE()}, except that the arguments are swapped.
@c end_description_for_help_topic

@c example_for_help_topic INSTR
@example
mysql> SELECT INSTR('foobarbar', 'bar');
        -> 4
mysql> SELECT INSTR('xbar', 'foobar');
        -> 0
@end example

This function is multi-byte safe.  In MySQL 3.23, this function is case
sensitive. For 4.0 on, it is case sensitive only if either argument is a
binary string.

@c description_for_help_topic LCASE
@item LCASE(@var{str})
@findex LCASE()

@code{LCASE()} is a synonym for @code{LOWER()}.
@c end_description_for_help_topic

@c description_for_help_topic LEFT
@item LEFT(@var{str},@var{len})
@findex LEFT()
Returns the leftmost @var{len} characters from the string @var{str}.
@c end_description_for_help_topic

@c example_for_help_topic LEFT
@example
mysql> SELECT LEFT('foobarbar', 5);
        -> 'fooba'
@end example

@c description_for_help_topic LENGTH
@item LENGTH(@var{str})
@findex LENGTH()
Returns the length of the string @var{str}, measured in bytes.
A multi-byte character counts as multiple bytes.
This means that for a string containing five two-byte characters,
@code{LENGTH()} returns @code{10}, whereas @code{CHAR_LENGTH()} returns
@code{5}.
@c end_description_for_help_topic

@c example_for_help_topic LENGTH
@example
mysql> SELECT LENGTH('text');
        -> 4
@end example

@c description_for_help_topic LOAD_FILE
@item LOAD_FILE(@var{file_name})
@findex FILE
@findex LOAD_FILE()
Reads the file and returns the file contents as a string.  The file
must be located on the server, you must specify the full pathname to the
file, and you must have the @code{FILE} privilege.  The file must
be readable by all and be smaller than @code{max_allowed_packet} bytes.

If the file doesn't exist or cannot be read because one of the preceding
conditions is not satisfied, the function returns @code{NULL}.
@c end_description_for_help_topic

@c example_for_help_topic LOAD_FILE
@example
mysql> UPDATE @var{tbl_name}
           SET @var{blob_column}=LOAD_FILE('/tmp/picture')
           WHERE id=1;
@end example

Before MySQL 3.23, you must read the file inside your application and create
an @code{INSERT} statement to update the database with the file contents.
If you are using the MySQL++ library, one way to do this can be found in the
MySQL++ manual, available at
@uref{http://dev.mysql.com/doc/}.

@c description_for_help_topic LOCATE
@item LOCATE(@var{substr},@var{str})
@itemx LOCATE(@var{substr},@var{str},@var{pos})
@findex LOCATE()

The first syntax
returns the position of the first occurrence of substring @var{substr}
in string @var{str}.
The second syntax
returns the position of the first occurrence of substring @var{substr} in
string @var{str}, starting at position @var{pos}.
Returns @code{0} if @var{substr} is not in @var{str}.
@c end_description_for_help_topic

@c example_for_help_topic POSITION
@example
mysql> SELECT LOCATE('bar', 'foobarbar');
        -> 4
mysql> SELECT LOCATE('xbar', 'foobar');
        -> 0
mysql> SELECT LOCATE('bar', 'foobarbar',5);
        -> 7
@end example

This function is multi-byte safe.  In MySQL 3.23, this function is case
sensitive. For 4.0 on, it is case sensitive only if either argument is a
binary string.

@c description_for_help_topic LOWER
@item LOWER(@var{str})
@findex LOWER()
Returns the string @var{str} with all characters changed to lowercase
according to the current character set mapping (the default is ISO-8859-1
Latin1).
@c end_description_for_help_topic

@c example_for_help_topic LOWER
@example
mysql> SELECT LOWER('QUADRATICALLY');
        -> 'quadratically'
@end example

This function is multi-byte safe.

@c description_for_help_topic LPAD
@item LPAD(@var{str},@var{len},@var{padstr})
@findex LPAD()
Returns the string @var{str}, left-padded with the string @var{padstr}
to a length of @var{len} characters. If @var{str} is longer
than @var{len}, the return value is shortened to @var{len} characters.
@c end_description_for_help_topic

@c example_for_help_topic LPAD
@example
mysql> SELECT LPAD('hi',4,'??');
        -> '??hi'
mysql> SELECT LPAD('hi',1,'??');
        -> 'h'
@end example

@c description_for_help_topic LTRIM
@item LTRIM(@var{str})
@findex LTRIM()
Returns the string @var{str} with leading space characters removed.
@c end_description_for_help_topic

@c example_for_help_topic LTRIM
@example
mysql> SELECT LTRIM('  barbar');
        -> 'barbar'
@end example

This function is multi-byte safe.

@c description_for_help_topic MAKE_SET
@item MAKE_SET(@var{bits},@var{str1},@var{str2},...)
@findex MAKE_SET()
Returns a set value (a string containing substrings separated by @samp{,}
characters) consisting of the strings that have the corresponding bit in
@var{bits} set.  @var{str1} corresponds to bit 0, @var{str2} to bit 1,
and so on.  @code{NULL} values in @var{str1}, @var{str2}, @code{...}
are not appended to the result.
@c end_description_for_help_topic

@c example_for_help_topic MAKE_SET
@example
mysql> SELECT MAKE_SET(1,'a','b','c');
        -> 'a'
mysql> SELECT MAKE_SET(1 | 4,'hello','nice','world');
        -> 'hello,world'
mysql> SELECT MAKE_SET(1 | 4,'hello','nice',NULL,'world');
        -> 'hello'
mysql> SELECT MAKE_SET(0,'a','b','c');
        -> ''
@end example

@c description_for_help_topic MID
@item MID(@var{str},@var{pos},@var{len})
@findex MID()

@code{MID(@var{str},@var{pos},@var{len})} is a synonym for
@code{SUBSTRING(@var{str},@var{pos},@var{len})}.
@c end_description_for_help_topic

@c description_for_help_topic OCT
@item OCT(@var{N})
@findex OCT()
Returns a string representation of the octal value of @var{N}, where
@var{N} is a longlong (@code{BIGINT})number.  This is equivalent to
@code{CONV(N,10,8)}.
Returns @code{NULL} if @var{N} is @code{NULL}.
@c end_description_for_help_topic

@c example_for_help_topic OCT
@example
mysql> SELECT OCT(12);
        -> '14'
@end example

@c description_for_help_topic OCTETLENGTH
@item OCTET_LENGTH(@var{str})
@findex OCTET_LENGTH()

@code{OCTET_LENGTH()} is a synonym for @code{LENGTH()}.
@c end_description_for_help_topic

@c description_for_help_topic ORD
@item ORD(@var{str})
@findex ORD()
If the leftmost character of the string @var{str} is a multi-byte character,
returns the code for that character, calculated from the numeric values
of its constituent bytes using this formula:

@example
  (1st byte code)
+ (2nd byte code * 256)
+ (3rd byte code * 256^2) ...
@end example

If the leftmost character is not a multi-byte character, @code{ORD()}
returns the same value as the @code{ASCII()} function.
@c end_description_for_help_topic

@c example_for_help_topic ORD
@example
mysql> SELECT ORD('2');
        -> 50
@end example

@c description_for_help_topic POSITION
@item POSITION(@var{substr} IN @var{str})
@findex POSITION()

@code{POSITION(@var{substr} IN @var{str})} is a synonym for @code{LOCATE(@var{substr},@var{str})}.
@c end_description_for_help_topic

@c description_for_help_topic QUOTE
@item QUOTE(@var{str})
@findex QUOTE()
Quotes a string to produce a result that can be used as a properly escaped
data value in an SQL statement.  The string is returned surrounded by single
quotes and with each instance of single quote (@samp{'}), backslash (@samp{\}),
ASCII NUL, and Control-Z preceded by a backslash.  If the argument is
@code{NULL}, the return value is the word ``NULL'' without surrounding
single quotes.
The @code{QUOTE()} function was added in MySQL 4.0.3.
@c end_description_for_help_topic

@c example_for_help_topic QUOTE
@example
mysql> SELECT QUOTE('Don\'t!');
        -> 'Don\'t!'
mysql> SELECT QUOTE(NULL);
        -> NULL
@end example

@c description_for_help_topic REPEAT
@item REPEAT(@var{str},@var{count})
@findex REPEAT()
Returns a string consisting of the string @var{str} repeated @var{count}
times. If @code{@var{count} <= 0}, returns an empty string. Returns @code{NULL} if
@var{str} or @var{count} are @code{NULL}.
@c end_description_for_help_topic

@c example_for_help_topic REPEAT
@example
mysql> SELECT REPEAT('MySQL', 3);
        -> 'MySQLMySQLMySQL'
@end example

@c description_for_help_topic REPLACE
@item REPLACE(@var{str},@var{from_str},@var{to_str})
@findex REPLACE()
Returns the string @var{str} with all occurrences of the string
@var{from_str} replaced by the string @var{to_str}.
@c end_description_for_help_topic

@c example_for_help_topic REPLACE
@example
mysql> SELECT REPLACE('www.mysql.com', 'w', 'Ww');
        -> 'WwWwWw.mysql.com'
@end example

This function is multi-byte safe.

@c description_for_help_topic REVERSE
@item REVERSE(@var{str})
@findex REVERSE()
Returns the string @var{str} with the order of the characters reversed.
@c end_description_for_help_topic

@c example_for_help_topic REVERSE
@example
mysql> SELECT REVERSE('abc');
        -> 'cba'
@end example

This function is multi-byte safe.

@c description_for_help_topic RIGHT
@item RIGHT(@var{str},@var{len})
@findex RIGHT()
Returns the rightmost @var{len} characters from the string @var{str}.
@c end_description_for_help_topic

@c example_for_help_topic RIGHT
@example
mysql> SELECT RIGHT('foobarbar', 4);
        -> 'rbar'
@end example

This function is multi-byte safe.

@c description_for_help_topic RPAD
@item RPAD(@var{str},@var{len},@var{padstr})
@findex RPAD()
Returns the string @var{str}, right-padded with the string @var{padstr}
to a length of @var{len} characters. If @var{str} is longer
than @var{len}, the return value is shortened to @var{len} characters.
@c end_description_for_help_topic

@c example_for_help_topic RPAD
@example
mysql> SELECT RPAD('hi',5,'?');
        -> 'hi???'
mysql> SELECT RPAD('hi',1,'?');
        -> 'h'
@end example

This function is multi-byte safe.

@c description_for_help_topic RTRIM
@item RTRIM(@var{str})
@findex RTRIM()
Returns the string @var{str} with trailing space characters removed.
@c end_description_for_help_topic

@c example_for_help_topic RTRIM
@example
mysql> SELECT RTRIM('barbar   ');
        -> 'barbar'
@end example

This function is multi-byte safe.

@c description_for_help_topic SOUNDEX
@item SOUNDEX(@var{str})
@findex SOUNDEX()
Returns a soundex string from @var{str}. Two strings that sound almost the
same should have identical soundex strings. A standard soundex string
is four characters long, but the @code{SOUNDEX()} function returns an
arbitrarily long string. You can use @code{SUBSTRING()} on the result to get
a standard soundex string.  All non-alphabetic characters are ignored in the
given string. All international alphabetic characters outside the A-Z range
are treated as vowels.
@c end_description_for_help_topic

@c example_for_help_topic SOUNDEX
@example
mysql> SELECT SOUNDEX('Hello');
        -> 'H400'
mysql> SELECT SOUNDEX('Quadratically');
        -> 'Q36324'
@end example

@strong{Note}: This function implements the original Soundex algorithm,
not the more popular enhanced version (also described by D. Knuth).
The difference is that original version discards vowels first and then
duplicates, whereas the enhanced version discards duplicates first and
then vowels.

@c description_for_help_topic SOUNDS LIKE  SOUNDS LIKE
@item @var{expr1} SOUNDS LIKE @var{expr2}
@findex SOUNDS LIKE

This is the same as @code{SOUNDEX(@var{expr1}) = SOUNDEX(@var{expr2})}. It is
available only in MySQL 4.1 or later. 
@c end_description_for_help_topic

@c description_for_help_topic SPACE
@item SPACE(@var{N})
@findex SPACE()
Returns a string consisting of @var{N} space characters.
@c end_description_for_help_topic

@c example_for_help_topic SPACE
@example
mysql> SELECT SPACE(6);
        -> '      '
@end example

@c description_for_help_topic SUBSTRING
@item SUBSTRING(@var{str},@var{pos})
@itemx SUBSTRING(@var{str} FROM @var{pos})
@itemx SUBSTRING(@var{str},@var{pos},@var{len})
@itemx SUBSTRING(@var{str} FROM @var{pos} FOR @var{len})
@findex SUBSTRING()

The forms without a @var{len} argument
return a substring from string @var{str} starting at position @var{pos}.
The forms with a @var{len} argument
return a substring @var{len} characters long from string @var{str},
starting at position @var{pos}.
The forms that use @code{FROM} are standard SQL syntax.
@c end_description_for_help_topic

@c example_for_help_topic SUBSTRING
@example
mysql> SELECT SUBSTRING('Quadratically',5);
        -> 'ratically'
mysql> SELECT SUBSTRING('foobarbar' FROM 4);
        -> 'barbar'
mysql> SELECT SUBSTRING('Quadratically',5,6);
        -> 'ratica'
@end example

This function is multi-byte safe.

@c description_for_help_topic SUBSTRING_INDEX
@item SUBSTRING_INDEX(@var{str},@var{delim},@var{count})
@findex SUBSTRING_INDEX()
Returns the substring from string @var{str} before @var{count}
occurrences of the delimiter @var{delim}.
If @var{count} is positive, everything to the left of the final delimiter
(counting from the left) is returned.
If @var{count} is negative, everything to the right of the final delimiter
(counting from the right) is returned.
@c end_description_for_help_topic

@c example_for_help_topic SUBSTRING_INDEX
@example
mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2);
        -> 'www.mysql'
mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2);
        -> 'mysql.com'
@end example

This function is multi-byte safe.

@c description_for_help_topic TRIM  BOTH LEADING TRAILING FROM
@item TRIM([@{BOTH | LEADING | TRAILING@} [@var{remstr}] FROM] @var{str})
@itemx TRIM(@var{remstr} FROM] @var{str})
@findex TRIM()
Returns the string @var{str} with all @var{remstr} prefixes and/or suffixes
removed. If none of the specifiers @code{BOTH}, @code{LEADING}, or
@code{TRAILING} is given, @code{BOTH} is assumed. If @var{remstr} is optional
and not specified, spaces are removed.
@c end_description_for_help_topic

@c example_for_help_topic TRIM
@example
mysql> SELECT TRIM('  bar   ');
        -> 'bar'
mysql> SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx');
        -> 'barxxx'
mysql> SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx');
        -> 'bar'
mysql> SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz');
        -> 'barx'
@end example

This function is multi-byte safe.

@c description_for_help_topic UCASE
@item UCASE(@var{str})
@findex UCASE()

@code{UCASE()} is a synonym for @code{UPPER()}.
@c end_description_for_help_topic

@c description_for_help_topic UNCOMPRESS
@item UNCOMPRESS(@var{string_to_uncompress})
@findex UNCOMPRESS()
Uncompresses a string compressed by the @code{COMPRESS()} function.
If the argument is not a compressed value, the result is @code{NULL}.
This function requires MySQL to have been compiled with a compression library
such as @code{zlib}. Otherwise, the return value is always @code{NULL}.
@c end_description_for_help_topic

@c example_for_help_topic UNCOMPRESS
@example
mysql> SELECT UNCOMPRESS(COMPRESS('any string'));
        -> 'any string'
mysql> SELECT UNCOMPRESS('any string');
        -> NULL
@end example

@code{UNCOMPRESS()} was added in MySQL 4.1.1.

@c description_for_help_topic UNCOMPRESSED_LENGTH
@item UNCOMPRESSED_LENGTH(@var{compressed_string})
@findex UNCOMPRESSED_LENGTH()
Returns the length of a compressed string before compression.
@c end_description_for_help_topic

@c example_for_help_topic UNCOMPRESSED_LENGTH
@example
mysql> SELECT UNCOMPRESSED_LENGTH(COMPRESS(REPEAT('a',30)));
        -> 30
@end example

@code{UNCOMPRESSED_LENGTH()} was added in MySQL 4.1.1.

@c description_for_help_topic UNHEX
@item UNHEX(@var{str})
@findex UNHEX()

Does the opposite of @code{HEX(@var{str})}. That is, it interprets each pair of
hexadecimal digits in the argument as a number and converts it to the
character represented by the number. The resulting characters are returned as
a binary string.
@c end_description_for_help_topic

@c example_for_help_topic UNHEX
@example
mysql> SELECT UNHEX('4D7953514C');
        -> 'MySQL'
mysql> SELECT 0x4D7953514C;
        -> 'MySQL'
mysql> SELECT UNHEX(HEX('string'));
        -> 'string'
mysql> SELECT HEX(UNHEX('1267'));
        -> '1267'
@end example

@code{UNHEX()} was added in MySQL 4.1.2.

@c description_for_help_topic UPPER
@item UPPER(@var{str})
@findex UPPER()
Returns the string @var{str} with all characters changed to uppercase
according to the current character set mapping (the default is ISO-8859-1
Latin1).
@c end_description_for_help_topic

@c example_for_help_topic UPPER
@example
mysql> SELECT UPPER('Hej');
        -> 'HEJ'
@end example

This function is multi-byte safe.

@end table


@menu
* String comparison functions::  String Comparison Functions
@end menu

@node String comparison functions,  , String functions, String functions
@subsection String Comparison Functions

@findex string comparison functions
@findex functions, string comparison

MySQL automatically converts numbers to strings as necessary, and
vice versa.

@example
mysql> SELECT 1+'1';
        -> 2
mysql> SELECT CONCAT(2,' test');
        -> '2 test'
@end example

If you want to convert a number to a string explicitly, use the @code{CAST()}
or @code{CONCAT()} function:

@example
mysql> SELECT 38.8, CAST(38.8 AS CHAR);
        -> 38.8, '38.8'
mysql> SELECT 38.8, CONCAT(38.8);
        -> 38.8, '38.8'
@end example

@code{CAST()} is preferable, but it is unavailable before MySQL 4.0.2.

If a string function is given a binary string as an argument, the resulting
string is also a binary string.  A number converted to a string is treated as
a binary string.  This affects only comparisons.

@cindex case sensitivity, in string comparisons
@cindex string comparisons, case sensitivity

Normally, if any expression in a string comparison is case sensitive, the
comparison is performed in case-sensitive fashion.

@table @code

@c description_for_help_topic LIKE  ESCAPE
@item @var{expr} LIKE @var{pat} [ESCAPE '@var{escape-char}']
@findex LIKE
Pattern matching using
SQL simple regular expression comparison. Returns @code{1} (TRUE) or @code{0}
(FALSE).  If either @var{expr} or @var{pat} is @code{NULL}, the result is
@code{NULL}.

With @code{LIKE} you can use the following two wildcard characters
in the pattern:

@multitable @columnfractions .20 .80
@item @strong{Character} @tab @strong{Description}
@item @code{%} @tab Matches any number of characters, even zero characters
@item @code{_} @tab Matches exactly one character
@end multitable
@c end_description_for_help_topic

@c example_for_help_topic LIKE
@example
mysql> SELECT 'David!' LIKE 'David_';
        -> 1
mysql> SELECT 'David!' LIKE '%D%v%';
        -> 1
@end example

To test for literal instances of a wildcard character, precede the character
with the escape character.  If you don't specify the @code{ESCAPE} character,
@samp{\} is assumed.

@multitable @columnfractions .20 .80
@item @strong{String} @tab @strong{Description}
@item @code{\%} @tab Matches one @samp{%} character
@item @code{\_} @tab Matches one @samp{_} character
@end multitable

@example
mysql> SELECT 'David!' LIKE 'David\_';
        -> 0
mysql> SELECT 'David_' LIKE 'David\_';
        -> 1
@end example

To specify a different escape character, use the @code{ESCAPE} clause:

@example
mysql> SELECT 'David_' LIKE 'David|_' ESCAPE '|';
        -> 1
@end example

The following two statements illustrate that string comparisons are
not case sensitive unless one of the operands is a binary string:

@example
mysql> SELECT 'abc' LIKE 'ABC';
        -> 1
mysql> SELECT 'abc' LIKE BINARY 'ABC';
        -> 0
@end example

In MySQL, @code{LIKE} is allowed on numeric expressions. (This is an
extension to the standard SQL @code{LIKE}.)

@example
mysql> SELECT 10 LIKE '1%';
        -> 1
@end example

Note: Because MySQL uses the C escape syntax in strings (for example,
@samp{\n} to represent newline), you must double any @samp{\} that you use in your @code{LIKE}
strings.  For example, to search for @samp{\n}, specify it as @samp{\\n}.  To
search for @samp{\}, specify it as @samp{\\\\} (the backslashes are stripped
once by the parser and another time when the pattern match is done, leaving
a single backslash to be matched).


@c description_for_help_topic NOT LIKE
@item @var{expr} NOT LIKE @var{pat} [ESCAPE '@var{escape-char}']
@findex NOT LIKE

This is the same as @code{NOT (@var{expr} LIKE @var{pat} [ESCAPE '@var{escape-char}'])}.
@c end_description_for_help_topic

@c description_for_help_topic NOT REGEXP
@item @var{expr} NOT REGEXP @var{pat}
@itemx @var{expr} NOT RLIKE @var{pat}
@findex NOT REGEXP

This is the same as @code{NOT (@var{expr} REGEXP @var{pat})}.
@c end_description_for_help_topic

@cindex mSQL compatibility
@cindex compatibility, with mSQL
@findex REGEXP
@findex RLIKE
@c description_for_help_topic RLIKE  REGEXP
@item @var{expr} REGEXP @var{pat}
@itemx @var{expr} RLIKE @var{pat}
Performs a pattern match of a string expression @var{expr} against a pattern
@var{pat}.  The pattern can be an extended regular expression.
The syntax for regular expressions is discussed in
@ref{Regexp}.  Returns @code{1} if @var{expr} matches @var{pat}, otherwise
returns @code{0}.  If either @var{expr} or @var{pat} is @code{NULL},
the result is @code{NULL}.  @code{RLIKE} is a synonym for @code{REGEXP},
provided for
@code{mSQL} compatibility. Note: Because MySQL uses the C escape
syntax in strings (for example, @samp{\n} to represent newline), you must double any @samp{\} that
you use in your @code{REGEXP} strings.  As of MySQL 3.23.4,
@code{REGEXP} is not case sensitive for normal (not binary) strings.
@c end_description_for_help_topic

@c example_for_help_topic RLIKE
@example
mysql> SELECT 'Monty!' REGEXP 'm%y%%';
        -> 0
mysql> SELECT 'Monty!' REGEXP '.*';
        -> 1
mysql> SELECT 'new*\n*line' REGEXP 'new\\*.\\*line';
        -> 1
mysql> SELECT 'a' REGEXP 'A', 'a' REGEXP BINARY 'A';
        -> 1  0
mysql> SELECT 'a' REGEXP '^[a-d]';
        -> 1
@end example

@code{REGEXP} and @code{RLIKE} use the current character set (ISO-8859-1
Latin1 by default) when deciding the type of a character.
However, these operators are not multi-byte safe.

@c description_for_help_topic STRCMP
@item STRCMP(@var{expr1},@var{expr2})
@findex STRCMP()
@code{STRCMP()}
returns @code{0} if the strings are the same, @code{-1} if the first
argument is smaller than the second according to the current sort order,
and @code{1} otherwise.
@c end_description_for_help_topic

@c example_for_help_topic STRCMP
@example
mysql> SELECT STRCMP('text', 'text2');
        -> -1
mysql> SELECT STRCMP('text2', 'text');
        -> 1
mysql> SELECT STRCMP('text', 'text');
        -> 0
@end example

As of MySQL 4.0,
@code{STRCMP()} uses the current character set when performing comparisons.
This makes the default comparison behavior case insensitive unless
one or both of the operands are binary strings.
Before MySQL 4.0, @code{STRCMP()} is case sensitive.

@end table


@node Numeric Functions, Date and time functions, String functions, Functions
@section Numeric Functions

@menu
* Arithmetic functions::        Arithmetic Operators
* Mathematical functions::      Mathematical Functions
@end menu
@c help_category Numeric Functions@Functions

@node Arithmetic functions, Mathematical functions, Numeric Functions, Numeric Functions
@subsection Arithmetic Operators

@cindex operators, cast
The usual arithmetic operators are available. Note that in the case of
@code{-}, @code{+}, and @code{*}, the result is calculated with
@code{BIGINT} (64-bit) precision if both arguments are integers.
If one of the argument is an unsigned integer, and the other argument
is also an integer, the result will be an unsigned integer.
@xref{Cast Functions}.

@cindex operations, arithmetic
@cindex arithmetic expressions

@table @code

@c description_for_help_topic +
@item +
@findex + (addition)
@findex addition (+)
Addition:
@c end_description_for_help_topic

@c example_for_help_topic +
@example
mysql> SELECT 3+5;
        -> 8
@end example

@c description_for_help_topic - binary
@item -
@findex - (subtraction)
@findex subtraction (-)
Subtraction:
@c end_description_for_help_topic

@c example_for_help_topic - binary
@example
mysql> SELECT 3-5;
        -> -2
@end example

@c description_for_help_topic - unary
@item -
@findex - (unary minus)
@findex minus, unary (-)
@findex unary minus (-)
Unary minus. Changes the sign of the argument.
@c end_description_for_help_topic

@c example_for_help_topic - unary
@example
mysql> SELECT - 2;
        -> -2
@end example

Note that if this operator is used with a @code{BIGINT}, the return value is a
@code{BIGINT}!  This means that you should avoid using @code{-} on integers that
may have the value of @code{-2^63}!

@c description_for_help_topic *
@item *
@findex * (multiplication)
@findex multiplication (*)
Multiplication:
@c end_description_for_help_topic

@c example_for_help_topic *
@example
mysql> SELECT 3*5;
        -> 15
mysql> SELECT 18014398509481984*18014398509481984.0;
        -> 324518553658426726783156020576256.0
mysql> SELECT 18014398509481984*18014398509481984;
        -> 0
@end example

The result of the last expression is incorrect because the result of the
integer multiplication exceeds the 64-bit range of @code{BIGINT}
calculations.

@c description_for_help_topic /
@item /
@findex / (division)
@findex division (/)
Division:
@c end_description_for_help_topic

@c example_for_help_topic /
@example
mysql> SELECT 3/5;
        -> 0.60
@end example

Division by zero produces a @code{NULL} result:

@example
mysql> SELECT 102/(1-1);
        -> NULL
@end example

A division will be calculated with @code{BIGINT} arithmetic only if performed
in a context where its result is converted to an integer!

@item DIV
@findex DIV
@c description_for_help_topic DIV  FLOOR BIGINT
Integer division.
Similar to @code{FLOOR()} but safe with @code{BIGINT} values.
@c end_description_for_help_topic

@c example_for_help_topic DIV
@example
mysql> SELECT 5 DIV 2;
        -> 2
@end example

@code{DIV} is new in MySQL 4.1.0.

@end table


@node Mathematical functions,  , Arithmetic functions, Numeric Functions
@subsection Mathematical Functions
All mathematical functions return @code{NULL} in case of an error.

@findex mathematical functions
@findex functions, mathematical

@table @code

@c description_for_help_topic ABS
@item ABS(@var{X})
@findex ABS()
Returns the absolute value of @var{X}.
@c end_description_for_help_topic

@c example_for_help_topic ABS
@example
mysql> SELECT ABS(2);
        -> 2
mysql> SELECT ABS(-32);
        -> 32
@end example

This function is safe to use with @code{BIGINT} values.

@c description_for_help_topic ACOS
@item ACOS(@var{X})
@findex ACOS()
Returns the arc cosine of @var{X}, that is, the value whose cosine is
@var{X}. Returns @code{NULL} if @var{X} is not in the range @code{-1} to
@code{1}.
@c end_description_for_help_topic

@c example_for_help_topic ACOS
@example
mysql> SELECT ACOS(1);
        -> 0.000000
mysql> SELECT ACOS(1.0001);
        -> NULL
mysql> SELECT ACOS(0);
        -> 1.570796
@end example

@c description_for_help_topic ASIN
@item ASIN(@var{X})
@findex ASIN()
Returns the arc sine of @var{X}, that is, the value whose sine is
@var{X}. Returns @code{NULL} if @var{X} is not in the range @code{-1} to
@code{1}.
@c end_description_for_help_topic

@c example_for_help_topic ASIN
@example
mysql> SELECT ASIN(0.2);
        -> 0.201358
mysql> SELECT ASIN('foo');
        -> 0.000000
@end example

@c description_for_help_topic ATAN
@item ATAN(@var{X})
@findex ATAN()
Returns the arc tangent of @var{X}, that is, the value whose tangent is
@var{X}.
@c end_description_for_help_topic

@c example_for_help_topic ATAN
@example
mysql> SELECT ATAN(2);
        -> 1.107149
mysql> SELECT ATAN(-2);
        -> -1.107149
@end example

@c description_for_help_topic ATAN2
@item ATAN(@var{Y},@var{X})
@itemx ATAN2(@var{Y},@var{X})
@findex ATAN2()
Returns the arc tangent of the two variables @var{X} and @var{Y}. It is
similar to calculating the arc tangent of @code{@var{Y} / @var{X}}, except that the
signs of both arguments are used to determine the quadrant of the
result.
@c end_description_for_help_topic

@c example_for_help_topic ATAN2
@example
mysql> SELECT ATAN(-2,2);
        -> -0.785398
mysql> SELECT ATAN2(PI(),0);
        -> 1.570796
@end example

@c description_for_help_topic CEILING  CEIL
@item CEILING(@var{X})
@itemx CEIL(@var{X})
@findex CEILING()
Returns the smallest integer value not less than @var{X}.
@c end_description_for_help_topic

@c example_for_help_topic CEILING
@example
mysql> SELECT CEILING(1.23);
        -> 2
mysql> SELECT CEIL(-1.23);
        -> -1
@end example

Note that the return value is converted to a @code{BIGINT}!

The @code{CEIL()} alias was added in MySQL 4.0.6.

@c description_for_help_topic COS
@item COS(@var{X})
@findex COS()
Returns the cosine of @var{X}, where @var{X} is given in radians.
@c end_description_for_help_topic

@c example_for_help_topic COS
@example
mysql> SELECT COS(PI());
        -> -1.000000
@end example

@c description_for_help_topic COT
@item COT(@var{X})
@findex COT()
Returns the cotangent of @var{X}.
@c end_description_for_help_topic

@c example_for_help_topic COT
@example
mysql> SELECT COT(12);
        -> -1.57267341
mysql> SELECT COT(0);
        -> NULL
@end example

@c description_for_help_topic CRC32
@item CRC32(@var{expr})
@findex CRC32()
Computes a cyclic redundancy check value and returns a 32-bit unsigned value.
The result is @code{NULL} if the argument is @code{NULL}.
The argument is expected be a string and will be treated as one if it is not.
@c end_description_for_help_topic

@c example_for_help_topic CRC32
@example
mysql> SELECT CRC32('MySQL');
        -> 3259397556
@end example

@code{CRC32()} is available as of MySQL 4.1.0.

@c description_for_help_topic DEGREES
@item DEGREES(@var{X})
@findex DEGREES()
Returns the argument @var{X}, converted from radians to degrees.
@c end_description_for_help_topic

@c example_for_help_topic DEGREES
@example
mysql> SELECT DEGREES(PI());
        -> 180.000000
@end example

@c description_for_help_topic EXP
@item EXP(@var{X})
@findex EXP()
Returns the value of @code{e} (the base of natural logarithms) raised to
the power of @var{X}.
@c end_description_for_help_topic

@c example_for_help_topic EXP
@example
mysql> SELECT EXP(2);
        -> 7.389056
mysql> SELECT EXP(-2);
        -> 0.135335
@end example

@c description_for_help_topic FLOOR
@item FLOOR(@var{X})
@findex FLOOR()
Returns the largest integer value not greater than @var{X}.
@c end_description_for_help_topic

@c example_for_help_topic FLOOR
@example
mysql> SELECT FLOOR(1.23);
        -> 1
mysql> SELECT FLOOR(-1.23);
        -> -2
@end example

Note that the return value is converted to a @code{BIGINT}!

@c description_for_help_topic LN
@item LN(@var{X})
@findex LN()
Returns the natural logarithm of @var{X}.
@c end_description_for_help_topic

@c example_for_help_topic LN
@example
mysql> SELECT LN(2);
        -> 0.693147
mysql> SELECT LN(-2);
        -> NULL
@end example

This function was added in MySQL 4.0.3.
It is synonymous with @code{LOG(@var{X})} in MySQL.

@c description_for_help_topic LOG
@item LOG(@var{X})
@itemx LOG(@var{B},@var{X})
@findex LOG()
If called with one parameter, this function returns the natural logarithm
of @var{X}.
@c end_description_for_help_topic

@c example_for_help_topic LOG
@example
mysql> SELECT LOG(2);
        -> 0.693147
mysql> SELECT LOG(-2);
        -> NULL
@end example

If called with two parameters, this function returns the logarithm of
@var{X} for an arbitrary base @var{B}.
@example
mysql> SELECT LOG(2,65536);
        -> 16.000000
mysql> SELECT LOG(1,100);
        -> NULL
@end example

The arbitrary base option was added in MySQL 4.0.3.
@code{LOG(@var{B},@var{X})} is equivalent to @code{LOG(@var{X})/LOG(@var{B})}.

@c description_for_help_topic LOG2
@item LOG2(@var{X})
@findex LOG2()
Returns the base-2 logarithm of @code{@var{X}}.
@c end_description_for_help_topic

@c example_for_help_topic LOG2
@example
mysql> SELECT LOG2(65536);
        -> 16.000000
mysql> SELECT LOG2(-100);
        -> NULL
@end example

@code{LOG2()} is useful for finding out how many bits a number would
require for storage.
This function was added in MySQL 4.0.3.
In earlier versions, you can use @code{LOG(@var{X})/LOG(2)} instead.

@c description_for_help_topic LOG10
@item LOG10(@var{X})
@findex LOG10()
Returns the base-10 logarithm of @var{X}.
@c end_description_for_help_topic

@c example_for_help_topic LOG10
@example
mysql> SELECT LOG10(2);
        -> 0.301030
mysql> SELECT LOG10(100);
        -> 2.000000
mysql> SELECT LOG10(-100);
        -> NULL
@end example

@c description_for_help_topic %  MOD
@item MOD(@var{N},@var{M})
@itemx @var{N} % @var{M}
@itemx @var{N} MOD @var{M}
@findex MOD()
@findex % (modulo)
@findex MOD (modulo)
@findex modulo (%)
@findex modulo (MOD)
Modulo operation.
Returns the remainder of @var{N} divided by @var{M}.
@c end_description_for_help_topic

@c example_for_help_topic %
@example
mysql> SELECT MOD(234, 10);
        -> 4
mysql> SELECT 253 % 7;
        -> 1
mysql> SELECT MOD(29,9);
        -> 2
mysql> SELECT 29 MOD 9;
        -> 2
@end example

This function is safe to use with @code{BIGINT} values.
The @code{@var{N} MOD @var{M}} syntax works only as of MySQL 4.1.

As of MySQL 4.1.7, @code{MOD()} works on values with a fractional part and
returns the exact remainder after division:

@example
mysql> SELECT MOD(34.5,3);
        -> 1.5
@end example

Before MySQL 4.1.7, @code{MOD()} rounds arguments with a fractional value
to integers and returns an integer result:

@example
mysql> SELECT MOD(34.5,3);
        -> 2
@end example

@c description_for_help_topic PI
@item PI()
@findex PI()
Returns the value of PI. The default number of decimals displayed is five, but
MySQL internally uses the full double-precision value for PI.
@c end_description_for_help_topic

@c example_for_help_topic PI
@example
mysql> SELECT PI();
        -> 3.141593
mysql> SELECT PI()+0.000000000000000000;
        -> 3.141592653589793116
@end example

@c description_for_help_topic POWER  POW
@item POW(@var{X},@var{Y})
@itemx POWER(@var{X},@var{Y})
@findex POW()
@findex POWER()
Returns the value of @var{X} raised to the power of @var{Y}.
@c end_description_for_help_topic

@c example_for_help_topic POWER
@example
mysql> SELECT POW(2,2);
        -> 4.000000
mysql> SELECT POW(2,-2);
        -> 0.250000
@end example

@c description_for_help_topic RADIANS
@item RADIANS(@var{X})
@findex RADIANS()
Returns the argument @var{X}, converted from degrees to radians.
@c end_description_for_help_topic

@c example_for_help_topic RADIANS
@example
mysql> SELECT RADIANS(90);
        -> 1.570796
@end example

@c description_for_help_topic RAND
@item RAND()
@itemx RAND(@var{N})
@findex RAND()
Returns a random floating-point value in the range from @code{0} to @code{1.0}.
If an integer argument @var{N} is specified, it is used as the seed value
(producing a repeatable sequence).
@c end_description_for_help_topic

@c example_for_help_topic RAND
@example
mysql> SELECT RAND();
        -> 0.9233482386203
mysql> SELECT RAND(20);
        -> 0.15888261251047
mysql> SELECT RAND(20);
        -> 0.15888261251047
mysql> SELECT RAND();
        -> 0.63553050033332
mysql> SELECT RAND();
        -> 0.70100469486881
@end example

You can't use a column with @code{RAND()} values in an @code{ORDER BY}
clause, because @code{ORDER BY} would evaluate the column multiple times.
As of MySQL 3.23, you can retrieve rows in random order like this:

@example
mysql> SELECT * FROM @var{tbl_name} ORDER BY RAND();
@end example

@code{ORDER BY RAND()} combined with @code{LIMIT} is useful for selecting
a random sample of a set of rows:

@example
mysql> SELECT * FROM table1, table2 WHERE a=b AND c<d
    -> ORDER BY RAND() LIMIT 1000;
@end example

Note that @code{RAND()} in a @code{WHERE} clause is re-evaluated
every time the @code{WHERE} is executed.

@code{RAND()} is not meant to be a perfect random generator, but instead a
fast way to generate ad hoc random numbers that will be portable between
platforms for the same MySQL version.

@c description_for_help_topic ROUND
@item ROUND(@var{X})
@itemx ROUND(@var{X},@var{D})
@findex ROUND()
Returns the argument @var{X}, rounded to the nearest integer.
With two arguments, returns @var{X} rounded to @var{D} decimals.
If @var{D} is negative, the integer part of the number is zeroed out.
@c end_description_for_help_topic

@c example_for_help_topic ROUND
@example
mysql> SELECT ROUND(-1.23);
        -> -1
mysql> SELECT ROUND(-1.58);
        -> -2
mysql> SELECT ROUND(1.58);
        -> 2
mysql> SELECT ROUND(1.298, 1);
        -> 1.3
mysql> SELECT ROUND(1.298, 0);
        -> 1
mysql> SELECT ROUND(23.298, -1);
        -> 20
@end example

Note that the behavior of @code{ROUND()} when the argument
is halfway between two integers depends on the C library
implementation.  Different implementations round to the nearest even number,
always up, always down, or always toward zero.  If you need
one kind of rounding, you should use a well-defined function
such as @code{TRUNCATE()} or @code{FLOOR()} instead.

@c description_for_help_topic SIGN
@item SIGN(@var{X})
@findex SIGN()
Returns the sign of the argument as @code{-1}, @code{0}, or @code{1}, depending
on whether @var{X} is negative, zero, or positive.
@c end_description_for_help_topic

@c example_for_help_topic SIGN
@example
mysql> SELECT SIGN(-32);
        -> -1
mysql> SELECT SIGN(0);
        -> 0
mysql> SELECT SIGN(234);
        -> 1
@end example

@c description_for_help_topic SIN
@item SIN(@var{X})
@findex SIN()
Returns the sine of @var{X}, where @var{X} is given in radians.
@c end_description_for_help_topic

@c example_for_help_topic SIN
@example
mysql> SELECT SIN(PI());
        -> 0.000000
@end example

@c description_for_help_topic SQRT
@item SQRT(@var{X})
@findex SQRT()
Returns the non-negative square root of @var{X}.
@c end_description_for_help_topic

@c example_for_help_topic SQRT
@example
mysql> SELECT SQRT(4);
        -> 2.000000
mysql> SELECT SQRT(20);
        -> 4.472136
@end example

@c description_for_help_topic TAN
@item TAN(@var{X})
@findex TAN()
Returns the tangent of @var{X}, where @var{X} is given in radians.
@c end_description_for_help_topic

@c example_for_help_topic TAN
@example
mysql> SELECT TAN(PI()+1);
        -> 1.557408
@end example

@c description_for_help_topic TRUNCATE
@item TRUNCATE(@var{X},@var{D})
@findex TRUNCATE()
Returns the number @var{X}, truncated to @var{D} decimals.  If @var{D}
is @code{0}, the result will have no decimal point or fractional part.
If @var{D} is negative, the integer part of the number is zeroed out.
@c end_description_for_help_topic

@c example_for_help_topic TRUNCATE
@example
mysql> SELECT TRUNCATE(1.223,1);
        -> 1.2
mysql> SELECT TRUNCATE(1.999,1);
        -> 1.9
mysql> SELECT TRUNCATE(1.999,0);
        -> 1
mysql> SELECT TRUNCATE(-1.999,1);
        -> -1.9
mysql> SELECT TRUNCATE(122,-2);
       -> 100
@end example

Starting from MySQL 3.23.51, all numbers are rounded toward zero.

Note that decimal numbers are normally not stored as exact numbers in
computers, but as double-precision values, so you may be surprised by the
following result:

@cindex rounding errors
@example
mysql> SELECT TRUNCATE(10.28*100,0);
       -> 1027
@end example

This happens because @code{10.28} is actually stored as something like
@code{10.2799999999999999}.

@end table

@node Date and time functions, Fulltext Search, Numeric Functions, Functions
@section Date and Time Functions
@c help_category Date and Time Functions@Functions

@findex date and time functions
@findex functions, date and time

This section describes the functions that can be used to manipulate
temporal values.
See @ref{Date and time types} for a description of the range of values
each date and time type has and the valid formats in which values may be
specified.

Here is an example that uses date functions.  The following query selects
all records with a @code{date_col} value from within the last 30 days:

@example
mysql> SELECT @var{something} FROM @var{tbl_name}
    -> WHERE DATE_SUB(CURDATE(),INTERVAL 30 DAY) <= @var{date_col};
@end example

Note that the query also will select records with dates that lie in the
future.

Functions that expect date values usually will accept datetime values
and ignore the time part. Functions that expect time values usually will
accept datetime values and ignore the date part.

Functions that return the current date or time each are evaluated only once
per query at the start of query execution. This means that multiple references
to a function such as @code{NOW()} within a single query will always produce
the same result.  This principle also applies to @code{CURDATE()},
@code{CURTIME()}, @code{UTC_DATE()}, @code{UTC_TIME()}, @code{UTC_TIMESTAMP()},
and to any of their synonyms.

Beginning with MySQL 4.1.3, the @code{CURRENT_TIMESTAMP()},
@code{CURRENT_TIME()}, @code{CURRENT_DATE()}, and @code{FROM_UNIXTIME()}
functions return values in the connection's current time zone, which is
available as the value of the @code{time_zone} system variable.  Also,
@code{UNIX_TIMESTAMP()} assumes that its argument is a datetime value in
the current time zone.  @xref{Time zone support}.

The return value ranges in the following function descriptions apply for
complete dates. If a date is a ``zero'' value or an incomplete date such
as @code{'2001-11-00'}, functions that extract a part of a date may return
@code{0}. For example, @code{DAYOFMONTH('2001-11-00')} returns @code{0}.

@table @code

@c description_for_help_topic ADDDATE
@item ADDDATE(@var{date},INTERVAL @var{expr} @var{type})
@itemx ADDDATE(@var{expr},@var{days})
@findex ADDDATE()

When invoked with the @code{INTERVAL} form of the second argument,
@code{ADDDATE()} is a synonym for @code{DATE_ADD()}.  The related
function @code{SUBDATE()} is a synonym for @code{DATE_SUB()}.
For information on the @code{INTERVAL} argument, see the
discussion for @code{DATE_ADD()}.

@example
mysql> SELECT DATE_ADD('1998-01-02', INTERVAL 31 DAY);
        -> '1998-02-02'
mysql> SELECT ADDDATE('1998-01-02', INTERVAL 31 DAY);
        -> '1998-02-02'
@end example

As of MySQL 4.1.1, the second syntax is allowed, where @var{expr} is a date
or datetime expression and @var{days} is the number of days to be added to
@var{expr}.

@example
mysql> SELECT ADDDATE('1998-01-02', 31);
        -> '1998-02-02'
@end example
@c end_description_for_help_topic

@c description_for_help_topic ADDTIME
@item ADDTIME(@var{expr},@var{expr2})
@findex ADDTIME()

@c TODO: DESCRIPTION. Depends on SAP/MySQL mode.

@code{ADDTIME()} adds @var{expr2} to @var{expr} and returns the result.
@var{expr} is a time or datetime expression, and @var{expr2} is a time
expression.
@c end_description_for_help_topic

@c example_for_help_topic ADDTIME
@example
mysql> SELECT ADDTIME('1997-12-31 23:59:59.999999',
    ->                '1 1:1:1.000002');
        -> '1998-01-02 01:01:01.000001'
mysql> SELECT ADDTIME('01:00:00.999999', '02:00:00.999998');
        -> '03:00:01.999997'
@end example

@code{ADDTIME()} was added in MySQL 4.1.1.

@c description_for_help_topic CONVERT_TZ
@item CONVERT_TZ(@var{dt},@var{from_tz},@var{to_tz})
@findex CONVERT_TZ()

@code{CONVERT_TZ()}
converts a datetime value @var{dt} from time zone given by @var{from_tz}
to the time zone given by @var{to_tz} and returns the resulting value.
Time zones may be specified as described in @ref{Time zone support}.
This function returns @code{NULL} if the arguments are invalid.
@c end_description_for_help_topic

If the value falls out of the supported range of the @code{TIMESTAMP}
type when converted fom @var{from_tz} to UTC, no conversion occurs.
The @code{TIMESTAMP} range is described at
@ref{Date and time type overview}.

@c example_for_help_topic CONVERT_TZ
@example
mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET');
        -> '2004-01-01 13:00:00'
mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','-07:00');
        -> '2004-01-01 05:00:00'
@end example

To use named time zones such as @code{'MET'} or @code{'Europe/Moscow'},
the time zone tables must be properly set up. See
@ref{Time zone support} for instructions.

@code{CONVERT_TZ()} was added in MySQL 4.1.3.

@c description_for_help_topic CURDATE
@item CURDATE()
@findex CURDATE()

Returns the current date as a value in @code{'YYYY-MM-DD'} or @code{YYYYMMDD}
format, depending on whether the function is used in a string or numeric
context.
@c end_description_for_help_topic

@c example_for_help_topic CURDATE
@example
mysql> SELECT CURDATE();
        -> '1997-12-15'
mysql> SELECT CURDATE() + 0;
        -> 19971215
@end example

@c description_for_help_topic CURRENT_DATE
@item CURRENT_DATE
@itemx CURRENT_DATE()
@findex CURRENT_DATE

@code{CURRENT_DATE} and @code{CURRENT_DATE()} are synonyms for
@code{CURDATE()}.
@c end_description_for_help_topic

@c description_for_help_topic CURTIME
@item CURTIME()
@findex CURTIME()

Returns the current time as a value in @code{'HH:MM:SS'} or @code{HHMMSS}
format, depending on whether the function is used in a string or numeric
context.
@c end_description_for_help_topic

@c example_for_help_topic CURTIME
@example
mysql> SELECT CURTIME();
        -> '23:50:26'
mysql> SELECT CURTIME() + 0;
        -> 235026
@end example

@c description_for_help_topic CURRENT_TIME
@item CURRENT_TIME
@itemx CURRENT_TIME()
@findex CURRENT_TIME

@code{CURRENT_TIME} and @code{CURRENT_TIME()} are synonyms for
@code{CURTIME()}.
@c end_description_for_help_topic

@c description_for_help_topic CURRENT_TIMESTAMP
@item CURRENT_TIMESTAMP
@itemx CURRENT_TIMESTAMP()
@findex CURRENT_TIMESTAMP

@code{CURRENT_TIMESTAMP} and @code{CURRENT_TIMESTAMP()} are synonyms for
@code{NOW()}.
@c end_description_for_help_topic

@c description_for_help_topic DATE function  DATE
@item DATE(@var{expr})
@findex DATE()

Extracts the date part of the date or datetime expression @var{expr}.
@c end_description_for_help_topic

@c example_for_help_topic DATE function
@example
mysql> SELECT DATE('2003-12-31 01:02:03');
        -> '2003-12-31'
@end example

@code{DATE()} is available as of MySQL 4.1.1.

@c description_for_help_topic DATEDIFF
@item DATEDIFF(@var{expr},@var{expr2})
@findex DATEDIFF()

@c TODO: DESCRIPTION. Depends on SAP/MySQL mode.

@code{DATEDIFF()} returns the number of days between the start date
@var{expr} and the end date @var{expr2}.
@var{expr} and @var{expr2} are date or date-and-time expressions.
Only the date parts of the values are used in the calculation.
@c end_description_for_help_topic

@c example_for_help_topic DATEDIFF
@example
mysql> SELECT DATEDIFF('1997-12-31 23:59:59','1997-12-30');
        -> 1
mysql> SELECT DATEDIFF('1997-11-30 23:59:59','1997-12-31');
        -> -31
@end example

@code{DATEDIFF()} was added in MySQL 4.1.1.

@c description_for_help_topic DATE OPERATIONS  DATE DATE_ADD DATE_SUB SECOND MINUTE HOUR DAY MONTH YEAR MINUTE_SECOND HOUR_MINUTE DAY_HOUR YEAR_MONTH HOUR_SECOND DAY_MINUTE DAY_SECOND INTERVAL
@item DATE_ADD(@var{date},INTERVAL @var{expr} @var{type})
@itemx DATE_SUB(@var{date},INTERVAL @var{expr} @var{type})
@findex DATE_ADD()
@findex DATE_SUB()

These functions perform date arithmetic.
@var{date} is a @code{DATETIME} or @code{DATE} value specifying the starting
date.  @var{expr} is an expression specifying the interval value to be added
or subtracted from the starting date.  @var{expr} is a string; it may start
with a @samp{-} for negative intervals.  @var{type} is a keyword indicating
how the expression should be interpreted.
@c end_description_for_help_topic

The @code{INTERVAL} keyword and the @code{type} specifier are not case
sensitive.

The following table shows how the @var{type} and @var{expr} arguments
are related:

@multitable @columnfractions .45 .55
@item @var{type} @strong{Value} @tab @strong{Expected} @var{expr} @strong{Format}
@item @code{MICROSECOND}        @tab @code{MICROSECONDS}
@item @code{SECOND}             @tab @code{SECONDS}
@item @code{MINUTE}             @tab @code{MINUTES}
@item @code{HOUR}               @tab @code{HOURS}
@item @code{DAY}                @tab @code{DAYS}
@item @code{WEEK}               @tab @code{WEEKS}
@item @code{MONTH}              @tab @code{MONTHS}
@item @code{QUARTER}            @tab @code{QUARTERS}
@item @code{YEAR}               @tab @code{YEARS}
@item @code{SECOND_MICROSECOND} @tab @code{'SECONDS.MICROSECONDS'}
@item @code{MINUTE_MICROSECOND} @tab @code{'MINUTES.MICROSECONDS'}
@item @code{MINUTE_SECOND}      @tab @code{'MINUTES:SECONDS'}
@item @code{HOUR_MICROSECOND}   @tab @code{'HOURS.MICROSECONDS'}
@item @code{HOUR_SECOND}        @tab @code{'HOURS:MINUTES:SECONDS'}
@item @code{HOUR_MINUTE}        @tab @code{'HOURS:MINUTES'}
@item @code{DAY_MICROSECOND}    @tab @code{'DAYS.MICROSECONDS'}
@item @code{DAY_SECOND}         @tab @code{'DAYS HOURS:MINUTES:SECONDS'}
@item @code{DAY_MINUTE}         @tab @code{'DAYS HOURS:MINUTES'}
@item @code{DAY_HOUR}           @tab @code{'DAYS HOURS'}
@item @code{YEAR_MONTH}         @tab @code{'YEARS-MONTHS'}
@end multitable

The @var{type} values @code{DAY_MICROSECOND}, @code{HOUR_MICROSECOND},
@code{MINUTE_MICROSECOND}, @code{SECOND_MICROSECOND},
and @code{MICROSECOND} are allowed as of MySQL 4.1.1.
The values @code{QUARTER} and @code{WEEK} are allowed as of MySQL 5.0.0.

MySQL allows any punctuation delimiter in the @var{expr} format.
Those shown in the table are the suggested delimiters.  If the @var{date}
argument is a @code{DATE} value and your calculations involve only
@code{YEAR}, @code{MONTH}, and @code{DAY} parts (that is, no time parts), the
result is a @code{DATE} value.  Otherwise, the result is a @code{DATETIME}
value.

As of MySQL 3.23, @code{INTERVAL @var{expr} @var{type}} is allowed on either
side of the @code{+} operator if the expression on the other side is a
date or datetime value.
For the @code{-} operator, @code{INTERVAL @var{expr} @var{type}} is allowed only on
the right side, because
it makes no sense to subtract a date or datetime value from an interval.
(See examples below.)

@c example_for_help_topic DATE OPERATIONS
@example
mysql> SELECT '1997-12-31 23:59:59' + INTERVAL 1 SECOND;
        -> '1998-01-01 00:00:00'
mysql> SELECT INTERVAL 1 DAY + '1997-12-31';
        -> '1998-01-01'
mysql> SELECT '1998-01-01' - INTERVAL 1 SECOND;
        -> '1997-12-31 23:59:59'
mysql> SELECT DATE_ADD('1997-12-31 23:59:59',
    ->                 INTERVAL 1 SECOND);
        -> '1998-01-01 00:00:00'
mysql> SELECT DATE_ADD('1997-12-31 23:59:59',
    ->                 INTERVAL 1 DAY);
        -> '1998-01-01 23:59:59'
mysql> SELECT DATE_ADD('1997-12-31 23:59:59',
    ->                 INTERVAL '1:1' MINUTE_SECOND);
        -> '1998-01-01 00:01:00'
mysql> SELECT DATE_SUB('1998-01-01 00:00:00',
    ->                 INTERVAL '1 1:1:1' DAY_SECOND);
        -> '1997-12-30 22:58:59'
mysql> SELECT DATE_ADD('1998-01-01 00:00:00',
    ->                 INTERVAL '-1 10' DAY_HOUR);
        -> '1997-12-30 14:00:00'
mysql> SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
        -> '1997-12-02'
mysql> SELECT DATE_ADD('1992-12-31 23:59:59.000002',
    ->            INTERVAL '1.999999' SECOND_MICROSECOND);
        -> '1993-01-01 00:00:01.000001'
@end example

If you specify an interval value that is too short (does not include all the
interval parts that would be expected from the @var{type} keyword),
MySQL assumes that you have left out the leftmost parts of the interval
value.  For example, if you specify a @code{type} of @code{DAY_SECOND}, the
value of @var{expr} is expected to have days, hours, minutes, and seconds
parts.  If you specify a value like @code{'1:10'}, MySQL assumes
that the days and hours parts are missing and the value represents minutes
and seconds.  In other words, @code{'1:10' DAY_SECOND} is interpreted in such
a way that it is equivalent to @code{'1:10' MINUTE_SECOND}.  This is
analogous to the way that MySQL interprets @code{TIME} values
as representing elapsed time rather than as time of day.

If you add to or subtract from a date value something that
contains a time part, the result is automatically converted to a
datetime value:

@example
mysql> SELECT DATE_ADD('1999-01-01', INTERVAL 1 DAY);
        -> '1999-01-02'
mysql> SELECT DATE_ADD('1999-01-01', INTERVAL 1 HOUR);
        -> '1999-01-01 01:00:00'
@end example

If you use really malformed dates, the result is @code{NULL}. If you add
@code{MONTH}, @code{YEAR_MONTH}, or @code{YEAR} and the resulting date
has a day that is larger than the maximum day for the new month, the day is
adjusted to the maximum days in the new month:

@example
mysql> SELECT DATE_ADD('1998-01-30', INTERVAL 1 MONTH);
        -> '1998-02-28'
@end example

@c description_for_help_topic DATE_FORMAT
@item DATE_FORMAT(@var{date},@var{format})
@findex DATE_FORMAT()
Formats the @var{date} value according to the @var{format} string. The
following specifiers may be used in the @var{format} string:

@multitable @columnfractions .20 .70
@item @strong{Specifier} @tab @strong{Description}
@item @code{%a} @tab Abbreviated weekday name (@code{Sun}..@code{Sat})
@item @code{%b} @tab Abbreviated month name (@code{Jan}..@code{Dec})
@item @code{%c} @tab Month, numeric (@code{0}..@code{12})
@item @code{%D} @tab Day of the month with English suffix (@code{0th}, @code{1st}, @code{2nd}, @code{3rd}, ...)
@item @code{%d} @tab Day of the month, numeric (@code{00}..@code{31})
@item @code{%e} @tab Day of the month, numeric (@code{0}..@code{31})
@item @code{%f} @tab Microseconds (@code{000000}..@code{999999})
@item @code{%H} @tab Hour (@code{00}..@code{23})
@item @code{%h} @tab Hour (@code{01}..@code{12})
@item @code{%I} @tab Hour (@code{01}..@code{12})
@item @code{%i} @tab Minutes, numeric (@code{00}..@code{59})
@item @code{%j} @tab Day of year (@code{001}..@code{366})
@item @code{%k} @tab Hour (@code{0}..@code{23})
@item @code{%l} @tab Hour (@code{1}..@code{12})
@item @code{%M} @tab Month name (@code{January}..@code{December})
@item @code{%m} @tab Month, numeric (@code{00}..@code{12})
@item @code{%p} @tab @code{AM} or @code{PM}
@item @code{%r} @tab Time, 12-hour (@code{hh:mm:ss} followed by @code{AM} or @code{PM})
@item @code{%S} @tab Seconds (@code{00}..@code{59})
@item @code{%s} @tab Seconds (@code{00}..@code{59})
@item @code{%T} @tab Time, 24-hour (@code{hh:mm:ss})
@item @code{%U} @tab Week (@code{00}..@code{53}), where Sunday is the first day of the week
@item @code{%u} @tab Week (@code{00}..@code{53}), where Monday is the first day of the week
@item @code{%V} @tab Week (@code{01}..@code{53}), where Sunday is the first day of the week; used with @code{%X}
@item @code{%v} @tab Week (@code{01}..@code{53}), where Monday is the first day of the week; used with @code{%x}
@item @code{%W} @tab Weekday name (@code{Sunday}..@code{Saturday})
@item @code{%w} @tab Day of the week (@code{0}=Sunday..@code{6}=Saturday)
@item @code{%X} @tab Year for the week where Sunday is the first day of the week, numeric, four digits; used with @code{%V}
@item @code{%x} @tab Year for the week, where Monday is the first day of the week, numeric, four digits; used with @code{%v}
@item @code{%Y} @tab Year, numeric, four digits
@item @code{%y} @tab Year, numeric, two digits
@item @code{%%} @tab A literal @samp{%}.
@end multitable

All other characters are copied to the result without interpretation.

The @code{%v}, @code{%V}, @code{%x}, and @code{%X} format specifiers are
available as of MySQL 3.23.8.  @code{%f} is available as of MySQL 4.1.1.

As of MySQL 3.23, the @samp{%} character is required before
format specifier characters.  In earlier versions of MySQL,
@samp{%} was optional.

The reason the ranges for the month and day specifiers begin with zero
is that MySQL allows incomplete dates such as @code{'2004-00-00'} to be
stored as of MySQL 3.23.
@c end_description_for_help_topic

@c example_for_help_topic DATE_FORMAT
@example
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
        -> 'Saturday October 1997'
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
        -> '22:23:00'
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',
                          '%D %y %a %d %m %b %j');
        -> '4th 97 Sat 04 10 Oct 277'
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',
                          '%H %k %I %r %T %S %w');
        -> '22 22 10 10:23:00 PM 22:23:00 00 6'
mysql> SELECT DATE_FORMAT('1999-01-01', '%X %V');
        -> '1998 52'
@end example

@c description_for_help_topic DAY
@item DAY(@var{date})
@findex DAY()

@code{DAY()} is a synonym for @code{DAYOFMONTH()}.
It is available as of MySQL 4.1.1.
@c end_description_for_help_topic

@c description_for_help_topic DAYNAME
@item DAYNAME(@var{date})
@findex DAYNAME()
Returns the name of the weekday for @var{date}.
@c end_description_for_help_topic

@c example_for_help_topic DAYNAME
@example
mysql> SELECT DAYNAME('1998-02-05');
        -> 'Thursday'
@end example

@c description_for_help_topic DAYOFMONTH
@item DAYOFMONTH(@var{date})
@findex DAYOFMONTH()
Returns the day of the month for @var{date}, in the range @code{1} to
@code{31}.
@c end_description_for_help_topic

@c example_for_help_topic DAYOFMONTH
@example
mysql> SELECT DAYOFMONTH('1998-02-03');
        -> 3
@end example

@c description_for_help_topic DAYOFWEEK
@item DAYOFWEEK(@var{date})
@findex DAYOFWEEK()
Returns the weekday index
for @var{date} (@code{1} = Sunday, @code{2} = Monday, ..., @code{7} =
Saturday).  These index values correspond to the ODBC standard.
@c end_description_for_help_topic

@c example_for_help_topic DAYOFWEEK
@example
mysql> SELECT DAYOFWEEK('1998-02-03');
        -> 3
@end example

@c description_for_help_topic DAYOFYEAR
@item DAYOFYEAR(@var{date})
@findex DAYOFYEAR()
Returns the day of the year for @var{date}, in the range @code{1} to
@code{366}.
@c end_description_for_help_topic

@c example_for_help_topic DAYOFYEAR
@example
mysql> SELECT DAYOFYEAR('1998-02-03');
        -> 34
@end example

@c description_for_help_topic EXTRACT
@item EXTRACT(@var{type} FROM @var{date})
@findex EXTRACT()

The @code{EXTRACT()} function uses the same kinds of interval type
specifiers as @code{DATE_ADD()} or @code{DATE_SUB()}, but extracts parts
from the date rather than performing date arithmetic.
@c end_description_for_help_topic

@c example_for_help_topic EXTRACT
@example
mysql> SELECT EXTRACT(YEAR FROM '1999-07-02');
       -> 1999
mysql> SELECT EXTRACT(YEAR_MONTH FROM '1999-07-02 01:02:03');
       -> 199907
mysql> SELECT EXTRACT(DAY_MINUTE FROM '1999-07-02 01:02:03');
       -> 20102
mysql> SELECT EXTRACT(MICROSECOND
    ->                FROM '2003-01-02 10:30:00.00123');
        -> 123
@end example

@code{EXTRACT()} was added in MySQL 3.23.0.

@c description_for_help_topic FROM_DAYS
@item FROM_DAYS(@var{N})
@findex FROM_DAYS()
Given a daynumber @var{N}, returns a @code{DATE} value.
@c end_description_for_help_topic

@c example_for_help_topic FROM_DAYS
@example
mysql> SELECT FROM_DAYS(729669);
        -> '1997-10-07'
@end example

@code{FROM_DAYS()} is not intended for use with values that precede the
advent of the Gregorian calendar (1582), because it does not take into account
the days that were lost when the calendar was changed.

@c description_for_help_topic FROM_UNIXTIME
@item FROM_UNIXTIME(@var{unix_timestamp})
@itemx FROM_UNIXTIME(@var{unix_timestamp},@var{format})
@findex FROM_UNIXTIME()
Returns a representation of the @var{unix_timestamp} argument as a value in
@code{'YYYY-MM-DD HH:MM:SS'} or @code{YYYYMMDDHHMMSS} format, depending on
whether the function is used in a string or numeric context.

@c example_for_help_topic FROM_UNIXTIME
@example
mysql> SELECT FROM_UNIXTIME(875996580);
        -> '1997-10-04 22:23:00'
mysql> SELECT FROM_UNIXTIME(875996580) + 0;
        -> 19971004222300
@end example

If @var{format} is given, the result is formatted according to the
@var{format} string. @var{format} may contain the same specifiers as
those listed in the entry for the @code{DATE_FORMAT()} function.
@c end_description_for_help_topic

@c example_for_help_topic FROM_UNIXTIME
@example
mysql> SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(),
    ->                      '%Y %D %M %h:%i:%s %x');
        -> '2003 6th August 06:22:58 2003'
@end example

@c description_for_help_topic GET_FORMAT
@item GET_FORMAT(DATE|TIME|DATETIME, 'EUR'|'USA'|'JIS'|'ISO'|'INTERNAL')
@findex GET_FORMAT()
Returns a format string. This function is useful in combination with the 
@code{DATE_FORMAT()} and the @code{STR_TO_DATE()} functions.
@c Following is commented out because not yet implemented
@c and when setting 
@c the server variables @code{DATE_FORMAT}, @code{TIME_FORMAT}, and 
@c @code{DATETIME_FORMAT}.
The three possible values for the first argument 
and the five possible values for the second argument result in 15 possible 
format strings (for the specifiers used, see the table in the 
@code{DATE_FORMAT()} function description).
@multitable @columnfractions .60 .40
@item @strong{Function Call} @tab @strong{Result}
@item @code{GET_FORMAT(DATE,'USA')} @tab @code{'%m.%d.%Y'}
@item @code{GET_FORMAT(DATE,'JIS')} @tab @code{'%Y-%m-%d'}
@item @code{GET_FORMAT(DATE,'ISO')} @tab @code{'%Y-%m-%d'}
@item @code{GET_FORMAT(DATE,'EUR')} @tab @code{'%d.%m.%Y'}
@item @code{GET_FORMAT(DATE,'INTERNAL')} @tab @code{'%Y%m%d'}
@item @code{GET_FORMAT(DATETIME,'USA')} @tab @code{'%Y-%m-%d-%H.%i.%s'}
@item @code{GET_FORMAT(DATETIME,'JIS')} @tab @code{'%Y-%m-%d %H:%i:%s'}
@item @code{GET_FORMAT(DATETIME,'ISO')} @tab @code{'%Y-%m-%d %H:%i:%s'}
@item @code{GET_FORMAT(DATETIME,'EUR')} @tab @code{'%Y-%m-%d-%H.%i.%s'}
@item @code{GET_FORMAT(DATETIME,'INTERNAL')} @tab @code{'%Y%m%d%H%i%s'}
@item @code{GET_FORMAT(TIME,'USA')} @tab @code{'%h:%i:%s %p'}
@item @code{GET_FORMAT(TIME,'JIS')} @tab @code{'%H:%i:%s'}
@item @code{GET_FORMAT(TIME,'ISO')} @tab @code{'%H:%i:%s'}
@item @code{GET_FORMAT(TIME,'EUR')} @tab @code{'%H.%i.%S'}
@item @code{GET_FORMAT(TIME,'INTERNAL')} @tab @code{'%H%i%s'}
@end multitable
ISO format is ISO 9075, not ISO 8601.

As of MySQL 4.1.4, @code{TIMESTAMP} can also be used;
@code{GET_FORMAT()} returns the same values as for @code{DATETIME}.

@c If the first argument of 
@c @code{GET_FORMAT()} is illegal or missing, or if the second argument 
@c is missing, the function returns an error. If the second argument is illegal, 
@c the function returns @code{NULL}.
@c end_description_for_help_topic

@c example_for_help_topic GET_FORMAT
@example
mysql> SELECT DATE_FORMAT('2003-10-03',GET_FORMAT(DATE,'EUR'));
        -> '03.10.2003'
mysql> SELECT STR_TO_DATE('10.31.2003',GET_FORMAT(DATE,'USA'));
        -> 2003-10-31
@c Following is commented out because not yet implemented
@c mysql> SET DATE_FORMAT=GET_FORMAT(DATE, 'USA'); SELECT '2003-10-31';
@c         -> 10-31-2003
@end example
@code{GET_FORMAT()} is available as of MySQL 4.1.1.
@xref{SET OPTION,  , @code{SET OPTION}}.
@c INSERT STOP

@c description_for_help_topic HOUR
@item HOUR(@var{time})
@findex HOUR()
Returns the hour for @var{time}. The range of the return value will be
@code{0} to @code{23} for time-of-day values.
@c end_description_for_help_topic

@c example_for_help_topic HOUR
@example
mysql> SELECT HOUR('10:05:03');
        -> 10
@end example

However, the range of @code{TIME} values actually is much larger, so
@code{HOUR} can return values greater than @code{23}.
@example

mysql> SELECT HOUR('272:59:59');
        -> 272
@end example

@c description_for_help_topic LAST_DAY
@item LAST_DAY(@var{date})
@findex LAST_DAY()

Takes a date or datetime value and returns the corresponding value for the
last day of the month.  Returns @code{NULL} if the argument is invalid.
@c end_description_for_help_topic

@c example_for_help_topic LAST_DAY
@example
mysql> SELECT LAST_DAY('2003-02-05');
        -> '2003-02-28'
mysql> SELECT LAST_DAY('2004-02-05');
        -> '2004-02-29'
mysql> SELECT LAST_DAY('2004-01-01 01:01:01');
        -> '2004-01-31'
mysql> SELECT LAST_DAY('2003-03-32');
        -> NULL
@end example

@code{LAST_DAY()} is available as of MySQL 4.1.1.

@c description_for_help_topic LOCALTIME
@item LOCALTIME
@itemx LOCALTIME()
@findex LOCALTIME

@code{LOCALTIME} and @code{LOCALTIME()} are synonyms for
@code{NOW()}.
@c end_description_for_help_topic
They were added in MySQL 4.0.6.

@c description_for_help_topic LOCALTIMESTAMP
@item LOCALTIMESTAMP
@itemx LOCALTIMESTAMP()
@findex LOCALTIMESTAMP

@code{LOCALTIMESTAMP} and @code{LOCALTIMESTAMP()} are synonyms for
@code{NOW()}.
@c end_description_for_help_topic
They were added in MySQL 4.0.6.

@c description_for_help_topic MAKEDATE
@item MAKEDATE(@var{year},@var{dayofyear})
@findex MAKEDATE()

Returns a date, given year and day-of-year values.
@var{dayofyear} must be greater than 0 or the result will be @code{NULL}.
@c end_description_for_help_topic

@c example_for_help_topic MAKEDATE
@example
mysql> SELECT MAKEDATE(2001,31), MAKEDATE(2001,32);
        -> '2001-01-31', '2001-02-01'
mysql> SELECT MAKEDATE(2001,365), MAKEDATE(2004,365);
        -> '2001-12-31', '2004-12-30'
mysql> SELECT MAKEDATE(2001,0);
        -> NULL
@end example

@code{MAKEDATE()} is available as of MySQL 4.1.1.

@c description_for_help_topic MAKETIME
@item MAKETIME(@var{hour},@var{minute},@var{second})
@findex MAKETIME()

Returns a time value calculated from the @var{hour}, @var{minute}, and
@var{second} arguments.
@c end_description_for_help_topic

@c example_for_help_topic MAKETIME
@example
mysql> SELECT MAKETIME(12,15,30);
        -> '12:15:30'
@end example

@code{MAKETIME()} is available as of MySQL 4.1.1.

@c description_for_help_topic MICROSECOND
@item MICROSECOND(@var{expr})
@findex MICROSECOND()

Returns the microseconds from the time or datetime expression @var{expr} as a
number in the range from @code{0} to @code{999999}.
@c end_description_for_help_topic

@c example_for_help_topic MICROSECOND
@example
mysql> SELECT MICROSECOND('12:00:00.123456');
        -> 123456
mysql> SELECT MICROSECOND('1997-12-31 23:59:59.000010');
        -> 10
@end example

@code{MICROSECOND()} is available as of MySQL 4.1.1.

@c description_for_help_topic MINUTE
@item MINUTE(@var{time})
@findex MINUTE()
Returns the minute for @var{time}, in the range @code{0} to @code{59}.
@c end_description_for_help_topic

@c example_for_help_topic MINUTE
@example
mysql> SELECT MINUTE('98-02-03 10:05:03');
        -> 5
@end example

@c description_for_help_topic MONTH
@item MONTH(@var{date})
@findex MONTH()
Returns the month for @var{date}, in the range @code{1} to @code{12}.
@c end_description_for_help_topic

@c example_for_help_topic MONTH
@example
mysql> SELECT MONTH('1998-02-03');
        -> 2
@end example

@c description_for_help_topic MONTHNAME
@item MONTHNAME(@var{date})
@findex MONTHNAME()
Returns the full name of the month for @var{date}.
@c end_description_for_help_topic

@c example_for_help_topic MONTHNAME
@example
mysql> SELECT MONTHNAME('1998-02-05');
        -> 'February'
@end example

@c description_for_help_topic NOW
@item NOW()
@findex NOW()

Returns the current date and time as a value in @code{'YYYY-MM-DD HH:MM:SS'}
or @code{YYYYMMDDHHMMSS} format, depending on whether the function is used in
a string or numeric context.
@c end_description_for_help_topic

@c example_for_help_topic NOW
@example
mysql> SELECT NOW();
        -> '1997-12-15 23:50:26'
mysql> SELECT NOW() + 0;
        -> 19971215235026
@end example

@c description_for_help_topic PERIOD_ADD
@item PERIOD_ADD(@var{P},@var{N})
@findex PERIOD_ADD()
Adds @var{N} months to period @var{P} (in the format @code{YYMM} or
@code{YYYYMM}). Returns a value in the format @code{YYYYMM}.
Note that the period argument @var{P} is @emph{not} a date value.
@c end_description_for_help_topic

@c example_for_help_topic PERIOD_ADD
@example
mysql> SELECT PERIOD_ADD(9801,2);
        -> 199803
@end example

@c description_for_help_topic PERIOD_DIFF
@item PERIOD_DIFF(@var{P1},@var{P2})
@findex PERIOD_DIFF()
Returns the number of months between periods @var{P1} and @var{P2}.
@var{P1} and @var{P2} should be in the format @code{YYMM} or @code{YYYYMM}.
Note that the period arguments @var{P1} and @var{P2} are @emph{not}
date values.
@c end_description_for_help_topic

@c example_for_help_topic PERIOD_DIFF
@example
mysql> SELECT PERIOD_DIFF(9802,199703);
        -> 11
@end example

@c description_for_help_topic QUARTER
@item QUARTER(@var{date})
@findex QUARTER()
Returns the quarter of the year for @var{date}, in the range @code{1}
to @code{4}.
@c end_description_for_help_topic

@c example_for_help_topic QUARTER
@example
mysql> SELECT QUARTER('98-04-01');
        -> 2
@end example

@c description_for_help_topic SECOND
@item SECOND(@var{time})
@findex SECOND()
Returns the second for @var{time}, in the range @code{0} to @code{59}.
@c end_description_for_help_topic

@c example_for_help_topic SECOND
@example
mysql> SELECT SECOND('10:05:03');
        -> 3
@end example

@c description_for_help_topic SEC_TO_TIME
@item SEC_TO_TIME(@var{seconds})
@findex SEC_TO_TIME()
Returns the @var{seconds} argument, converted to hours, minutes, and seconds,
as a value in @code{'HH:MM:SS'} or @code{HHMMSS} format, depending on whether
the function is used in a string or numeric context.
@c end_description_for_help_topic

@c example_for_help_topic SEC_TO_TIME
@example
mysql> SELECT SEC_TO_TIME(2378);
        -> '00:39:38'
mysql> SELECT SEC_TO_TIME(2378) + 0;
        -> 3938
@end example

@c INSERT START
@c description_for_help_topic STR_TO_DATE
@item STR_TO_DATE(@var{str},@var{format})
@findex STR_TO_DATE()
This is the reverse function of the @code{DATE_FORMAT()} function. It takes a 
string @var{str} and a format string @var{format}.
@code{STR_TO_DATE()} returns a @code{DATETIME} value if the format
string contains both date and time parts, or a @code{DATE} or @code{TIME}
value if the string contains only date or time parts.

@c NOT YET IMPLEMENTED START
@c If @var{format_str} is not specified, values are expected to be in the 
@c following format (for the specifiers used. (See the table in the 
@c @code{DATE_FORMAT()} function description.)
@c @multitable @columnfractions .20 .65
@c @item @strong{Type} @tab @strong{Format}
@c @item @code{DATE} @tab @code{'%Y-%m-%d'}
@c @item @code{TIME} @tab @code{'%h-%m-%s'}
@c @item @code{TIMESTAMP} @tab @code{'%Y-%m-%d %H:%i:%s'}
@c @end multitable
@c NOT YET IMPLEMENTED STOP
The date, time, or datetime values contained in @var{str} should be given 
in the format indicated by @var{format}. For the specifiers that can be 
used in @var{format}, see the table in the @code{DATE_FORMAT()} function 
description. All other characters are just taken verbatim, thus not being 
interpreted.
If @var{str} contains an illegal date, time, or datetime value, 
@code{STR_TO_DATE()} returns @code{NULL}.
@c end_description_for_help_topic

@c example_for_help_topic STR_TO_DATE
@example
@c next example commented out until format string becomes optional
@c mysql> SELECT STR_TO_DATE('2003-10-03');
@c         -> 2003-10-03 00:00:00
mysql> SELECT STR_TO_DATE('03.10.2003 09.20',
    ->                    '%d.%m.%Y %H.%i');
        -> '2003-10-03 09:20:00'
mysql> SELECT STR_TO_DATE('10arp', '%carp');
        -> '0000-10-00 00:00:00'
mysql> SELECT STR_TO_DATE('2003-15-10 00:00:00',
    ->                    '%Y-%m-%d %H:%i:%s');
        -> NULL
@end example

Range checking on the parts of date values is as described in
@ref{DATETIME, , @code{DATETIME}}. This means, for example, that a date with
a day part larger than the number of days in a month is allowable as long
as the day part is in the range from 1 to 31. Also, ``zero'' dates or dates
with part values of 0 are allowed.

@example
mysql> SELECT STR_TO_DATE('00/00/0000', '%m/%d/%Y');
        -> '0000-00-00'
mysql> SELECT STR_TO_DATE('04/31/2004', '%m/%d/%Y');
        -> '2004-04-31'
@end example

@code{STR_TO_DATE()} is available as of MySQL 4.1.1.

@c description_for_help_topic SUBDATE
@item SUBDATE(@var{date},INTERVAL @var{expr} @var{type})
@itemx SUBDATE(@var{expr},@var{days})
@findex SUBDATE()

When invoked with the @code{INTERVAL} form of the second argument,
@code{SUBDATE()} is a synonym for @code{DATE_SUB()}.
For information on the @code{INTERVAL} argument, see the
discussion for @code{DATE_ADD()}.

@example
mysql> SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
        -> '1997-12-02'
mysql> SELECT SUBDATE('1998-01-02', INTERVAL 31 DAY);
        -> '1997-12-02'
@end example

As of MySQL 4.1.1, the second syntax is allowed, where @var{expr} is a date
or datetime expression and @var{days} is the number of days to be
subtracted from @var{expr}.

@example
mysql> SELECT SUBDATE('1998-01-02 12:00:00', 31);
        -> '1997-12-02 12:00:00'
@end example
@c end_description_for_help_topic

@c description_for_help_topic SUBTIME
@item SUBTIME(@var{expr},@var{expr2})
@findex SUBTIME()

@c TODO: DESCRIPTION. Depends on SAP/MySQL mode.

@code{SUBTIME()} subtracts @var{expr2} from @var{expr} and returns the result.
@var{expr} is a time or datetime expression, and @var{expr2} is a time
expression.
@c end_description_for_help_topic

@c example_for_help_topic SUBTIME
@example
mysql> SELECT SUBTIME('1997-12-31 23:59:59.999999',
    ->                '1 1:1:1.000002');
        -> '1997-12-30 22:58:58.999997'
mysql> SELECT SUBTIME('01:00:00.999999', '02:00:00.999998');
        -> '-00:59:59.999999'
@end example

@code{SUBTIME()} was added in MySQL 4.1.1.

@c description_for_help_topic SYSDATE
@item SYSDATE()
@findex SYSDATE()

@code{SYSDATE()} is a synonym for @code{NOW()}.
@c end_description_for_help_topic

@c description_for_help_topic TIME function  TIME
@item TIME(@var{expr})
@findex TIME()

Extracts the time part of the time or datetime expression @var{expr}.
@c end_description_for_help_topic

@c example_for_help_topic TIME function
@example
mysql> SELECT TIME('2003-12-31 01:02:03');
        -> '01:02:03'
mysql> SELECT TIME('2003-12-31 01:02:03.000123');
        -> '01:02:03.000123'
@end example

@code{TIME()} is available as of MySQL 4.1.1.

@c description_for_help_topic TIMEDIFF
@item TIMEDIFF(@var{expr},@var{expr2})
@findex TIMEDIFF()

@c TODO: DESCRIPTION. Depends on SAP/MySQL mode.

@code{TIMEDIFF()} returns the time between the start time
@var{expr} and the end time @var{expr2}.
@var{expr} and @var{expr2} are time or date-and-time expressions, but both
must be of the same type.
@c end_description_for_help_topic

@c example_for_help_topic TIMEDIFF
@example
mysql> SELECT TIMEDIFF('2000:01:01 00:00:00',
    ->                 '2000:01:01 00:00:00.000001');
        -> '-00:00:00.000001'
mysql> SELECT TIMEDIFF('1997-12-31 23:59:59.000001',
    ->                 '1997-12-30 01:01:01.000002');
        -> '46:58:57.999999'
@end example

@code{TIMEDIFF()} was added in MySQL 4.1.1.

@c description_for_help_topic TIMESTAMP function  TIMESTAMP
@item TIMESTAMP(@var{expr})
@itemx TIMESTAMP(@var{expr},@var{expr2})
@findex TIMESTAMP()

With one argument, returns the date or datetime expression @var{expr}
as a datetime value.
With two arguments, adds the time expression @var{expr2} to the
date or datetime expression @var{expr} and returns a datetime value.
@c end_description_for_help_topic

@c example_for_help_topic TIMESTAMP function
@example
mysql> SELECT TIMESTAMP('2003-12-31');
        -> '2003-12-31 00:00:00'
mysql> SELECT TIMESTAMP('2003-12-31 12:00:00','12:00:00');
        -> '2004-01-01 00:00:00'
@end example

@code{TIMESTAMP()} is available as of MySQL 4.1.1.

@c description_for_help_topic TIMESTAMPADD
@item TIMESTAMPADD(@var{interval},@var{int_expr},@var{datetime_expr})
@findex TIMESTAMPADD()

Adds the integer expression @var{int_expr} to the date or datetime expression
@var{datetime_expr}. The unit for @var{int_expr} is given by the
@code{interval} argument, which should be one of the following values:
@code{FRAC_SECOND},
@code{SECOND},
@code{MINUTE},
@code{HOUR},
@code{DAY},
@code{WEEK},
@code{MONTH},
@code{QUARTER},
or
@code{YEAR}.

The @var{interval} value may be specified using one of keywords as shown,
or with a prefix of @code{SQL_TSI_}. For example, @code{DAY} or
@code{SQL_TSI_DAY} both are legal.
@c end_description_for_help_topic

@c example_for_help_topic TIMESTAMPADD function
@example
mysql> SELECT TIMESTAMPADD(MINUTE,1,'2003-01-02');
        -> '2003-01-02 00:01:00'
mysql> SELECT TIMESTAMPADD(WEEK,1,'2003-01-02');
        -> '2003-01-09'
@end example

@code{TIMESTAMPADD()} is available as of MySQL 5.0.0.

@c description_for_help_topic TIMESTAMPDIFF
@item TIMESTAMPDIFF(@var{interval},@var{datetime_expr1},@var{datetime_expr2})
@findex TIMESTAMPDIFF()

Returns the integer difference between the date or datetime expressions
@var{datetime_expr1} and
@var{datetime_expr2}. The unit for the result is given by the
@var{interval} argument. The legal values for @var{interval} are the same as
those listed in the description of the @code{TIMESTAMPADD()} function.
@c end_description_for_help_topic

@c example_for_help_topic TIMESTAMPDIFF function
@example
mysql> SELECT TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');
        -> 3
mysql> SELECT TIMESTAMPDIFF(YEAR,'2002-05-01','2001-01-01');
        -> -1
@end example

@code{TIMESTAMPDIFF()} is available as of MySQL 5.0.0.

@c description_for_help_topic TIME_FORMAT
@item TIME_FORMAT(@var{time},@var{format})
@findex TIME_FORMAT()
This is used like the @code{DATE_FORMAT()} function, but the
@var{format} string may contain only those format specifiers that handle
hours, minutes, and seconds.  Other specifiers produce a @code{NULL} value or
@code{0}.
@c end_description_for_help_topic

If the @var{time} value contains an hour part that is greater than
@code{23}, the @code{%H} and @code{%k} hour format specifiers produce a
value larger than the usual range of @code{0..23}. The other hour format
specifiers produce the hour value modulo 12.

@example
mysql> SELECT TIME_FORMAT('100:00:00', '%H %k %h %I %l');
        -> '100 100 04 04 4'
@end example

@c description_for_help_topic TIME_TO_SEC
@item TIME_TO_SEC(@var{time})
@findex TIME_TO_SEC()
Returns the @var{time} argument, converted to seconds.
@c end_description_for_help_topic

@c example_for_help_topic TIME_TO_SEC
@example
mysql> SELECT TIME_TO_SEC('22:23:00');
        -> 80580
mysql> SELECT TIME_TO_SEC('00:39:38');
        -> 2378
@end example

@c description_for_help_topic TO_DAYS
@item TO_DAYS(@var{date})
@findex TO_DAYS()
Given a date @var{date}, returns a daynumber (the number of days since year
0).
@c end_description_for_help_topic

@c example_for_help_topic TO_DAYS
@example
mysql> SELECT TO_DAYS(950501);
        -> 728779
mysql> SELECT TO_DAYS('1997-10-07');
        -> 729669
@end example

@code{TO_DAYS()} is not intended for use with values that precede the advent
of the Gregorian calendar (1582), because it does not take into account the
days that were lost when the calendar was changed.

Remember that MySQL converts two-digit year values in dates to
four-digit form using the rules in @ref{Date and time types}.  For example,
@code{'1997-10-07'} and @code{'97-10-07'} are seen as identical dates:

@example
mysql> SELECT TO_DAYS('1997-10-07'), TO_DAYS('97-10-07');
        -> 729669, 729669
@end example

For other dates before 1582, results from this function are undefined.

@c description_for_help_topic UNIX_TIMESTAMP
@item UNIX_TIMESTAMP()
@itemx UNIX_TIMESTAMP(@var{date})
@findex UNIX_TIMESTAMP()
If called with no argument, returns a Unix timestamp (seconds since
@code{'1970-01-01 00:00:00'} GMT) as an unsigned integer. If
@code{UNIX_TIMESTAMP()} is called with a @var{date} argument, it
returns the value of the argument as seconds since @code{'1970-01-01
00:00:00'} GMT.  @var{date} may be a @code{DATE} string, a
@code{DATETIME} string, a @code{TIMESTAMP}, or a number in the format
@code{YYMMDD} or @code{YYYYMMDD} in local time.
@c end_description_for_help_topic

@c example_for_help_topic UNIX_TIMESTAMP
@example
mysql> SELECT UNIX_TIMESTAMP();
        -> 882226357
mysql> SELECT UNIX_TIMESTAMP('1997-10-04 22:23:00');
        -> 875996580
@end example

When @code{UNIX_TIMESTAMP} is used on a @code{TIMESTAMP} column, the function
returns the internal timestamp value directly, with no implicit
``string-to-Unix-timestamp'' conversion.
If you pass an out-of-range date to @code{UNIX_TIMESTAMP()}, it
returns @code{0}, but please note that only basic range checking is performed
(year from @code{1970} to @code{2037}, month from @code{01} to @code{12}, day
from @code{01} from @code{31}).

If you want to subtract @code{UNIX_TIMESTAMP()} columns, you might want to
cast the result to signed integers. @xref{Cast Functions}.

@c description_for_help_topic UTC_DATE
@item UTC_DATE
@itemx UTC_DATE()
@findex UTC_DATE()
Returns the current UTC date as a value in @code{'YYYY-MM-DD'} or
@code{YYYYMMDD} format, depending on whether the function is used in a
string or numeric context.
@c end_description_for_help_topic

@c example_for_help_topic UTC_DATE
@example
mysql> SELECT UTC_DATE(), UTC_DATE() + 0;
        -> '2003-08-14', 20030814
@end example

@code{UTC_DATE()} is available as of MySQL 4.1.1.

@c description_for_help_topic UTC_TIME
@item UTC_TIME
@itemx UTC_TIME()
@findex UTC_TIME()
Returns the current UTC time as a value in @code{'HH:MM:SS'} or @code{HHMMSS}
format, depending on whether the function is used in a string or numeric
context.
@c end_description_for_help_topic

@c example_for_help_topic UTC_TIME
@example
mysql> SELECT UTC_TIME(), UTC_TIME() + 0;
        -> '18:07:53', 180753
@end example

@code{UTC_TIME()} is available as of MySQL 4.1.1.

@c description_for_help_topic UTC_TIMESTAMP
@item UTC_TIMESTAMP
@itemx UTC_TIMESTAMP()
@findex UTC_TIMESTAMP()
Returns the current UTC date and time as a value in @code{'YYYY-MM-DD HH:MM:SS'}
or @code{YYYYMMDDHHMMSS} format, depending on whether the function is used in
a string or numeric context.
@c end_description_for_help_topic

@c example_for_help_topic UTC_TIMESTAMP
@example
mysql> SELECT UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0;
        -> '2003-08-14 18:08:04', 20030814180804
@end example

@code{UTC_TIMESTAMP()} is available as of MySQL 4.1.1.

@c description_for_help_topic WEEK
@item WEEK(@var{date}[,@var{mode}])
@findex WEEK()
The function returns the week number for @var{date}.  The two-argument form
of @code{WEEK()} allows you to specify whether the week starts on Sunday or
Monday and whether the return value should be in the range from @code{0} to
@code{53} or from @code{1} to @code{52}. If the @var{mode} argument is
omitted, the value of the @code{default_week_format} system variable is
used (or @code{0} before MySQL 4.0.14).
@xref{Server system variables}.

The following table describes how the @var{mode} argument works:

@multitable @columnfractions .10 .80
@item @strong{Value} @tab @strong{Meaning}
@item @code{0} @tab Week starts on Sunday; return value range is @code{0} to
@code{53}; week 1 is the first week that starts in this year
@item @code{1} @tab Week starts on Monday; return value range is @code{0} to
@code{53}; week 1 is the first week that has more than three days in this year
@item @code{2} @tab Week starts on Sunday; return value range is @code{1} to
@code{53}; week 1 is the first week that starts in this year
@item @code{3} @tab Week starts on Monday; return value range is @code{1} to
@code{53}; week 1 is the first week that has more than three days in this year
@item @code{4} @tab Week starts on Sunday; return value range is @code{0} to
@code{53}; week 1 is the first week that has more than three days in this year
@item @code{5} @tab Week starts on Monday; return value range is @code{0} to
@code{53}; week 1 is the first week that starts in this year
@item @code{6} @tab Week starts on Sunday; return value range is @code{1} to
@code{53}; week 1 is the first week that has more than three days in this year
@item @code{7} @tab Week starts on Monday; return value range is @code{1} to
@code{53}; week 1 is the first week that starts in this year
@end multitable

The @var{mode} value of @code{3} can be used as of MySQL 4.0.5.
Values of @code{4} and above can be used as of MySQL 4.0.17.
@c end_description_for_help_topic

@c example_for_help_topic WEEK
@example
mysql> SELECT WEEK('1998-02-20');
        -> 7
mysql> SELECT WEEK('1998-02-20',0);
        -> 7
mysql> SELECT WEEK('1998-02-20',1);
        -> 8
mysql> SELECT WEEK('1998-12-31',1);
        -> 53
@end example

Note: In MySQL 4.0, @code{WEEK(@var{date},0)} was changed to match the
calendar in the USA.  Before that, @code{WEEK()} was calculated incorrectly
for dates in the USA. (In effect, @code{WEEK(@var{date})} and @code{WEEK(@var{date},0)} were
incorrect for all cases.)

Note that if a date falls in the last week of the previous year, MySQL
returns @code{0} if you don't use @code{2}, @code{3}, @code{6}, or @code{7}
as the optional @code{mode} argument:

@example
mysql> SELECT YEAR('2000-01-01'), WEEK('2000-01-01',0);
        -> 2000, 0
@end example

One might argue that MySQL should return @code{52} for the @code{WEEK()}
function, because the given date actually occurs in the 52nd week of 1999.  We
decided to return @code{0} instead because we want the function to return ``the week
number in the given year.''  This makes use of the @code{WEEK()}
function reliable when combined with other functions that extract a
date part from a date.

If you would prefer the result to be evaluated with respect to the year
that contains the first day of the week for the given date, you should use
@code{2}, @code{3}, @code{6}, or @code{7} as the optional @code{mode} argument.

@example
mysql> SELECT WEEK('2000-01-01',2);
        -> 52
@end example

Alternatively, use the @code{YEARWEEK()} function:

@example
mysql> SELECT YEARWEEK('2000-01-01');
        -> 199952
mysql> SELECT MID(YEARWEEK('2000-01-01'),5,2);
        -> '52'
@end example

@c description_for_help_topic WEEKDAY
@item WEEKDAY(@var{date})
@findex WEEKDAY()
Returns the weekday index for
@var{date} (@code{0} = Monday, @code{1} = Tuesday, ... @code{6} = Sunday).
@c end_description_for_help_topic

@c example_for_help_topic WEEKDAY
@example
mysql> SELECT WEEKDAY('1998-02-03 22:23:00');
        -> 1
mysql> SELECT WEEKDAY('1997-11-05');
        -> 2
@end example

@c description_for_help_topic WEEKOFYEAR
@item WEEKOFYEAR(@var{date})
@findex WEEKOFYEAR()

Returns the calendar week of the date as a number in the
range from @code{1} to @code{53}.
@c end_description_for_help_topic

@c example_for_help_topic WEEKOFYEAR
@example
mysql> SELECT WEEKOFYEAR('1998-02-20');
        -> 8
@end example

@code{WEEKOFYEAR()} is available as of MySQL 4.1.1.

@c description_for_help_topic YEAR
@item YEAR(@var{date})
@findex YEAR()
Returns the year for @var{date}, in the range @code{1000} to @code{9999}.
@c end_description_for_help_topic

@c example_for_help_topic YEAR
@example
mysql> SELECT YEAR('98-02-03');
        -> 1998
@end example

@item YEARWEEK(@var{date})
@itemx YEARWEEK(@var{date},@var{start})
@c description_for_help_topic YEARWEEK
Returns year and week for a date.  The @var{start} argument works exactly
like the @var{start} argument to @code{WEEK()}.  The year in the
result may be
different from the year in the date argument for the first and the last
week of the year.
@c end_description_for_help_topic

@c example_for_help_topic YEARWEEK
@example
mysql> SELECT YEARWEEK('1987-01-01');
        -> 198653
@end example

Note that the week number is different from what the @code{WEEK()}
function would return (@code{0}) for optional arguments @code{0} or @code{1},
as @code{WEEK()} then returns the week in the context of the given year.

@code{YEARWEEK()} was added in MySQL 3.23.8.

@end table


@c TODO: change node name to use "Full-text"; by convention, we use a dash

@node Fulltext Search, Cast Functions, Date and time functions, Functions
@section Full-Text Search Functions
@c help_category String Functions@Functions

@cindex searching, full-text
@cindex full-text search
@cindex FULLTEXT

@menu
* Fulltext Boolean::            Boolean Full-Text Searches
* Fulltext Query Expansion::    Full-Text Searches with Query Expansion
* Fulltext Restrictions::       Full-Text Restrictions
* Fulltext Fine-tuning::        Fine-Tuning MySQL Full-Text Search
* Fulltext TODO::               Full-Text Search TODO
@end menu

@table @code

@item MATCH (@var{col1},@var{col2},...) AGAINST (@var{expr} [IN BOOLEAN MODE | WITH QUERY EXPANSION])
@findex MATCH ... AGAINST()

@c description_for_help_topic MATCH AGAINST  MATCH AGAINST BOOLEAN IN MODE  MATCH AGAINST QUERY EXPANSION WITH
As of MySQL 3.23.23, MySQL has support for full-text indexing
and searching.  A full-text index in MySQL is an index of type
@code{FULLTEXT}.  @code{FULLTEXT} indexes are used with @code{MyISAM} tables
only and can be created from @code{CHAR}, @code{VARCHAR},
or @code{TEXT} columns at @code{CREATE TABLE} time or added later with
@code{ALTER TABLE} or @code{CREATE INDEX}.  For large datasets, it will be
much faster to load your data into a table that has no @code{FULLTEXT}
index, then create the index with @code{ALTER TABLE} (or
@code{CREATE INDEX}).  Loading data into a table that already has a
@code{FULLTEXT} index could be significantly slower.
@c end_description_for_help_topic

Constraints on full-text searching are listed in @ref{Fulltext Restrictions}.

@end table

Full-text searching is performed with the @code{MATCH()} function.

@example
mysql> CREATE TABLE articles (
    ->   id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
    ->   title VARCHAR(200),
    ->   body TEXT,
    ->   FULLTEXT (title,body)
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO articles (title,body) VALUES
    -> ('MySQL Tutorial','DBMS stands for DataBase ...'),
    -> ('How To Use MySQL Well','After you went through a ...'),
    -> ('Optimizing MySQL','In this tutorial we will show ...'),
    -> ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
    -> ('MySQL vs. YourSQL','In the following database comparison ...'),
    -> ('MySQL Security','When configured properly, MySQL ...');
Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM articles
    -> WHERE MATCH (title,body) AGAINST ('database');
+----+-------------------+------------------------------------------+
| id | title             | body                                     |
+----+-------------------+------------------------------------------+
|  5 | MySQL vs. YourSQL | In the following database comparison ... |
|  1 | MySQL Tutorial    | DBMS stands for DataBase ...             |
+----+-------------------+------------------------------------------+
2 rows in set (0.00 sec)
@end example

The @code{MATCH()} function performs a natural language search for a string
against a text collection. A collection is a set of one or more columns
included in a @code{FULLTEXT} index.  The search string is given as the
argument to @code{AGAINST()}.
For every row in the table, @code{MATCH()} returns a relevance
value, that is, a similarity measure between the search string and the text
in that row in the columns named in the @code{MATCH()} list.

By default, the search is performed in case-insensitive fashion. In MySQL
4.1 and up, you can make a full-text search by using a binary collation for
the indexed columns. For example, a column that has a character set of
@code{latin1} can be assigned a collation of @code{latin1_bin} to make it
case sensitive for full-text searches.

When @code{MATCH()} is used in a @code{WHERE} clause, as in the preceding
example,
the rows returned are automatically sorted with the highest relevance first.
Relevance values are non-negative floating-point numbers.  Zero relevance
means no similarity.  Relevance is computed based on the number of words
in the row, the number of unique words in that row, the total number of
words in the collection, and the number of documents (rows) that contain
a particular word.

For natural-language full-text searches, it is a requirement that the
columns named in the @code{MATCH()} function be the same columns included in
some @code{FULLTEXT} index in your table.  For the preceding query, note
that the columns named in the @code{MATCH()} function (@code{title} and
@code{body}) are the same as those named in the definition of the
@code{article} table's @code{FULLTEXT} index.  If you wanted to search the
@code{title} or @code{body} separately, you would need to create
@code{FULLTEXT} indexes for each column.

It is also possible to perform a boolean search or a search with query
expansion.  These search types are described in @ref{Fulltext Boolean} and
@ref{Fulltext Query Expansion}.

The preceding example is a basic illustration showing how to use the
@code{MATCH()} function where rows are returned in order of decreasing
relevance.  The next example shows how to retrieve the relevance values
explicitly.  Returned rows are not ordered because the @code{SELECT}
statement includes neither @code{WHERE} nor @code{ORDER BY} clauses:

@example
mysql> SELECT id, MATCH (title,body) AGAINST ('Tutorial')
    -> FROM articles;
+----+-----------------------------------------+
| id | MATCH (title,body) AGAINST ('Tutorial') |
+----+-----------------------------------------+
|  1 |                        0.65545833110809 |
|  2 |                                       0 |
|  3 |                        0.66266459226608 |
|  4 |                                       0 |
|  5 |                                       0 |
|  6 |                                       0 |
+----+-----------------------------------------+
6 rows in set (0.00 sec)
@end example

The following example is more complex.  The query returns the relevance values
and it also sorts the rows in order of decreasing relevance. To achieve
this result, you should specify @code{MATCH()} twice: once in the
@code{SELECT} list and once in the @code{WHERE} clause. This causes no
additional overhead, because the MySQL optimizer notices that the
two @code{MATCH()} calls are identical and invokes the full-text search
code only once.

@c help_category String Functions@Functions
@c example_for_help_topic MATCH AGAINST
@example
mysql> SELECT id, body, MATCH (title,body) AGAINST
    -> ('Security implications of running MySQL as root') AS score
    -> FROM articles WHERE MATCH (title,body) AGAINST
    -> ('Security implications of running MySQL as root');
+----+-------------------------------------+-----------------+
| id | body                                | score           |
+----+-------------------------------------+-----------------+
|  4 | 1. Never run mysqld as root. 2. ... | 1.5219271183014 |
|  6 | When configured properly, MySQL ... | 1.3114095926285 |
+----+-------------------------------------+-----------------+
2 rows in set (0.00 sec)
@end example

MySQL uses a very simple parser to split text into words.  A ``word'' is any
sequence of true word characters (letters, digits, and underscores),
optionally separated by no more than one sequential @samp{'} character.
For example, @code{wasn't} is parsed as a single word, but @code{wasn''t}
is parsed as two words @code{wasn} and @code{t}.  (And then @code{t} would
be ignored as too short according to the rules following.) Also, single
quotes at the ends of words are stripped; only embedded single quotes
are retained.

Some words are ignored in full-text searches:

@itemize @bullet
@item
Any word that is too short is ignored.  The default minimum length of
words that will be found by full-text searches is four characters.

@item
Words in the stopword list are ignored.  A stopword is a word such as
``the'' or ``some'' that is so common that it is considered to have zero
semantic value.  There is a built-in stopword list.

@end itemize

The default minimum word length and stopword list can be changed as
described in @ref{Fulltext Fine-tuning}.

@c TODO: what is a "correct" word? A non-ignored word?

Every correct word in the collection and in the query is weighted
according to its significance in the collection or query.  This way, a
word that is present in many documents has a lower weight (and may
even have a zero weight), because it has lower semantic value in this
particular collection.  Conversely, if the word is rare, it receives a
higher weight.  The weights of the words are then combined to compute the
relevance of the row.

Such a technique works best with large collections (in fact, it was
carefully tuned this way).  For very small tables, word distribution
does not adequately reflect their semantic value, and this model
may sometimes produce bizarre results. For example, although the word
``MySQL'' is present in every row of the @code{articles} table, a search for
the word produces no results:

@example
mysql> SELECT * FROM articles
    -> WHERE MATCH (title,body) AGAINST ('MySQL');
Empty set (0.00 sec)
@end example

The search result is empty because the word ``MySQL'' is present in at least
50% of the rows.  As such, it is effectively treated as a stopword.
For large datasets, this is the most desirable behavior---a natural language
query should not return every second row from a 1GB table. For small datasets,
it may be less desirable.

A word that matches half of rows in a table is less likely to locate relevant
documents.  In fact, it will most likely find plenty of irrelevant documents.
We all know this happens far too often when we are trying to find something on
the Internet with a search engine.  It is with this reasoning that rows
containing the word are assigned a low semantic value for @emph{the
particular dataset in which they occur}.  A given word may exceed the 50%
threshold in one dataset but not another.

The 50% threshold has a significant implication when you first try
full-text searching to see how it works: If you create a table and insert only
one or two rows of text into it, every word in the text occurs in at least
50% of the rows. As a result, no search returns any results. Be sure to
insert at least three rows, and preferably many more.


@node Fulltext Boolean, Fulltext Query Expansion, Fulltext Search, Fulltext Search
@subsection Boolean Full-Text Searches

As of Version 4.0.1, MySQL can also perform boolean full-text searches using
the @code{IN BOOLEAN MODE} modifier.

@example
mysql> SELECT * FROM articles WHERE MATCH (title,body)
    -> AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE);
+----+-----------------------+-------------------------------------+
| id | title                 | body                                |
+----+-----------------------+-------------------------------------+
|  1 | MySQL Tutorial        | DBMS stands for DataBase ...        |
|  2 | How To Use MySQL Well | After you went through a ...        |
|  3 | Optimizing MySQL      | In this tutorial we will show ...   |
|  4 | 1001 MySQL Tricks     | 1. Never run mysqld as root. 2. ... |
|  6 | MySQL Security        | When configured properly, MySQL ... |
+----+-----------------------+-------------------------------------+
@end example

This query retrieves all the rows that contain the word ``MySQL''
but that do @emph{not} contain
the word ``YourSQL''.

Boolean full-text searches have these characteristics:

@itemize @bullet
@item
They do not use the 50% threshold.

@item
They do not automatically sort rows in order of decreasing relevance.  You
can see this from the preceding query result: The row with the highest
relevance is the one that contains ``MySQL'' twice, but it is listed last,
not first.

@item
They can work even without a @code{FULLTEXT} index, although this would be
@emph{slow}.

@item
The minimum and maximum word length full-text parameters apply.

@item
The stopword list applies.

@end itemize

The boolean full-text search capability supports the following operators:

@c Note: the operators are listed here in the order in
@c which they appear in the ft_boolean_syntax variable
@c (default value: + -><()~*:""&|)
@c Exceptions:
@c - The third item (no operator) that corresponds to the
@c   space is in the second position of the ft_boolean_syntax
@c   value.
@c - The :, &, and | characters are omitted from the
@c - following list.

@table @code

@item +
A leading plus sign indicates that this word @emph{must be}
present in every row returned.

@item -
A leading minus sign indicates that this word @emph{must not be}
present in any row returned.

@item (no operator)
By default (when neither @code{+} nor @code{-} is specified) the word is optional,
but the rows that contain it will be rated higher. This mimics the
behavior of @code{MATCH() ... AGAINST()} without the @code{IN BOOLEAN
MODE} modifier.

@item > <
These two operators are used to change a word's contribution to the
relevance value that is assigned to a row.  The @code{>} operator
increases the contribution and the @code{<} operator decreases it.
See the example below.

@item ( )
Parentheses are used to group words into subexpressions.
Parenthesized groups can be nested.

@item ~
A leading tilde acts as a negation operator, causing the word's
contribution to the row relevance to be negative. It's useful for marking
noise words. A row that contains such a word will be rated lower than
others, but will not be excluded altogether, as it would be with the
@code{-} operator.

@item *
An asterisk is the truncation operator. Unlike the other operators, it
should be @emph{appended} to the word.

@item "
A phrase that is enclosed within double quote (@samp{"}) characters matches only
rows that contain the phrase @emph{literally, as it was typed}.

@end table

The following examples demonstrate some search strings that use boolean
full-text operators:

@table @code

@item 'apple banana'
Find rows that contain at least one of the two words.

@item '+apple +juice'
Find rows that contain both words.

@item '+apple macintosh'
Find rows that contain the
word ``apple'', but rank rows higher if they also contain ``macintosh''.

@item '+apple -macintosh'
Find rows that contain the
word ``apple'' but not ``macintosh''.

@item '+apple +(>turnover <strudel)'
Find rows that contain the words
``apple'' and ``turnover'', or ``apple'' and ``strudel'' (in any
order), but rank ``apple turnover'' higher than ``apple strudel''.

@item 'apple*'
Find rows that contain words such as
``apple'', ``apples'', ``applesauce'', or ``applet''.

@item '"some words"'
Find rows that contain the exact phrase ``some words'' (for example, rows
that contain ``some words of wisdom'' but not ``some noise words'').  Note
that the @samp{"} characters that surround the phrase are operator characters
that delimit the phrase.
They are not the quotes that surround the search string
itself.

@end table


@node Fulltext Query Expansion, Fulltext Restrictions, Fulltext Boolean, Fulltext Search
@subsection Full-Text Searches with Query Expansion

As of MySQL 4.1.1, full-text search supports query expansion (in particular,
its variant ``blind query expansion''). This is generally useful when a search
phrase is too short, which often means that the user is relying on implied
knowledge that the full-text search engine usually lacks. For example, a user
searching for ``database'' may really mean that ``MySQL'', ``Oracle'',
``DB2'', and ``RDBMS'' all are phrases that should match
``databases'' and should be returned, too. This is implied knowledge.

Blind query expansion (also known as automatic relevance feedback) is
enabled by adding @code{WITH QUERY EXPANSION} following the search phrase.
It works by performing the search twice, where the search phrase for the
second search is the original search phrase concatenated with the few top
found documents from the first search.  Thus, if one of these documents
contains the word ``databases'' and the word ``MySQL'', the second search
will find the documents that contain the word ``MySQL'' even if they do not
contain the word ``database''.  The following example shows this difference:

@example
mysql> SELECT * FROM articles
    -> WHERE MATCH (title,body) AGAINST ('database');
+----+-------------------+------------------------------------------+
| id | title             | body                                     |
+----+-------------------+------------------------------------------+
|  5 | MySQL vs. YourSQL | In the following database comparison ... |
|  1 | MySQL Tutorial    | DBMS stands for DataBase ...             |
+----+-------------------+------------------------------------------+
2 rows in set (0.00 sec)

mysql> SELECT * FROM articles
    -> WHERE MATCH (title,body)
    -> AGAINST ('database' WITH QUERY EXPANSION);
+----+-------------------+------------------------------------------+
| id | title             | body                                     |
+----+-------------------+------------------------------------------+
|  1 | MySQL Tutorial    | DBMS stands for DataBase ...             |
|  5 | MySQL vs. YourSQL | In the following database comparison ... |
|  3 | Optimizing MySQL  | In this tutorial we will show ...        |
+----+-------------------+------------------------------------------+
3 rows in set (0.00 sec)
@end example

Another example could be searching for books by Georges Simenon about
Maigret, when a user is not sure how to spell ``Maigret''. A search for
``Megre and the reluctant witnesses'' will find only ``Maigret and the
Reluctant Witnesses'' without query expansion.  A search with query
expansion will find all books with the word ``Maigret'' on the second pass.

Note: Because blind query expansion tends to increase noise significantly
by returning non-relevant documents, it's only meaningful to use when a
search phrase is rather short.


@node Fulltext Restrictions, Fulltext Fine-tuning, Fulltext Query Expansion, Fulltext Search
@subsection Full-Text Restrictions

@itemize @bullet
@item
Full-text searches are supported for @code{MyISAM} tables only.
@item
As of MySQL 4.1.1, full-text searches can be used with most multi-byte
character sets. The exception is that for Unicode, the @code{utf8} character
set can be used, but not the @code{ucs2} character set.
@item
As of MySQL 4.1, the use of multiple character sets within a single table
is supported. However, all columns in a @code{FULLTEXT} index must have
the same character set and collation.
@item
The @code{MATCH()} column list must exactly match the column list in some
@code{FULLTEXT} index definition for the table, unless this @code{MATCH()}
is @code{IN BOOLEAN MODE}.
@item
The argument to @code{AGAINST()} must be a constant string.
@end itemize


@node Fulltext Fine-tuning, Fulltext TODO, Fulltext Restrictions, Fulltext Search
@subsection Fine-Tuning MySQL Full-Text Search

The MySQL full-text search capability has few user-tunable parameters yet,
although adding more is very high on the TODO.  You can exert more control
over full-text searching behavior if you have a MySQL source distribution
because some changes require source code modfications.
@xref{Installing source}.

Note that full-text search was carefully tuned for the best searching
effectiveness.  Modifying the default behavior will, in most cases,
make the search results worse.  Do not alter the MySQL sources
unless you know what you are doing!

Most full-text variables described in the following items must be set at
server startup time. For these variables, a server restart is required to
change them and you cannot modify them dynamically while the server is
running.

Some variable changes require that you rebuild the @code{FULLTEXT} indexes
in your tables. Instructions for doing this are given at the end of this
section.

@itemize @bullet

@item
The minimum and maximum length of words to be indexed is defined by the
@code{ft_min_word_len} and @code{ft_max_word_len} system variables
(available as of MySQL 4.0.0).
@xref{Server system variables}.
The default minimum value is four characters.  The default maximum depends
on your version of MySQL. If you change either value, you must rebuild your
@code{FULLTEXT} indexes.  For example, if you want three-character words to
be searchable, you can set the @code{ft_min_word_len} variable by putting
the following lines in an option file:

@example
[mysqld]
ft_min_word_len=3
@end example

Then restart the server and rebuild your @code{FULLTEXT} indexes.
Also note particularly the remarks regarding @command{myisamchk} in the
instructions following this list.

@item
To override the default stopword list, set the @code{ft_stopword_file}
system variable (available as of MySQL 4.0.10).
@xref{Server system variables}.
The variable value should be the pathname of the file containing the stopword
list, or the empty string to disable stopword filtering. After changing the value, rebuild your @code{FULLTEXT} indexes.

@item
The 50% threshold for natural language searches is determined by the
particular weighting scheme chosen.  To disable it, look for the following
line in @file{myisam/ftdefs.h}:

@example
#define GWS_IN_USE GWS_PROB
@end example

Change the line to this:

@example
#define GWS_IN_USE GWS_FREQ
@end example

Then recompile MySQL.
There is no need to rebuild the indexes in this case.
@strong{Note}: By doing this you @emph{severely} decrease MySQL's ability
to provide adequate relevance values for the @code{MATCH()} function.
If you really need to search for such common words, it would be better to
search using @code{IN BOOLEAN MODE} instead, which does not observe the 50%
threshold.

@item
To change the operators used for boolean full-text searches, set the
@code{ft_boolean_syntax} system variable (available as of MySQL 4.0.1).  The
variable also can be changed while the server is running, but you must have
the @code{SUPER} privilege to do so.
No index rebuilding is necessary.
@ref{Server system variables} describes the rules that define how to set this
variable.

@end itemize

If you modify full-text variables that affect indexing
(@code{ft_min_word_len}, @code{ft_max_word_len}, or
@code{ft_stopword_file}), you must rebuild your @code{FULLTEXT} indexes
after making the changes and restarting the server. To rebuild the indexes
in this case, it's sufficient to do a @code{QUICK} repair operation:

@example
mysql> REPAIR TABLE @var{tbl_name} QUICK;
@end example

With regard specifically to using the @code{IN BOOLEAN MODE} capability, if
you upgrade from MySQL 3.23 to 4.0 or later, it's necessary to replace the
index header as well.  To do this, do a @code{USE_FRM} repair operation:

@example
mysql> REPAIR TABLE @var{tbl_name} USE_FRM;
@end example

This is necessary because boolean full-text searches require a flag in the
index header that was not present in MySQL 3.23, and that is not added if
you do only a @code{QUICK} repair.  If you attempt a boolean full-text
search without rebuilding the indexes this way, the search will return
incorrect results.

Note that if you use @command{myisamchk} to perform an operation that modifies
table indexes (such as repair or analyze), the @code{FULLTEXT} indexes
are rebuilt using the default full-text parameter values for minimum and
maximum word length and the stopword file unless you specify otherwise.
This can result in queries failing.

The problem occurs because these parameters are known only by the server.
They are not stored in @code{MyISAM} index files.  To avoid the problem if
you have modified the minimum or maximum word length or the stopword file in
the server, specify the same @code{ft_min_word_len}, @code{ft_max_word_len},
and @code{ft_stopword_file} values to @command{myisamchk} that you use for
@command{mysqld}. For example, if you have set the minimum word length to 3,
you can repair a table with @command{myisamchk} like this:

@example
shell> myisamchk --recover --ft_min_word_len=3 @var{tbl_name}.MYI
@end example

To ensure that @command{myisamchk} and the server use the same values for
full-text parameters, you can place each one in both the @code{[mysqld]}
and @code{[myisamchk]} sections of an option file:

@example
[mysqld]
ft_min_word_len=3

[myisamchk]
ft_min_word_len=3
@end example

An alternative to using @command{myisamchk} is to use the @code{REPAIR TABLE},
@code{ANALYZE TABLE}, @code{OPTIMIZE TABLE}, or @code{ALTER TABLE}.
These statements are performed by the server, which knows the proper
full-text parameter values to use.


@node Fulltext TODO,  , Fulltext Fine-tuning, Fulltext Search
@subsection Full-Text Search TODO

@itemize @bullet
@item Improved performance for all @code{FULLTEXT} operations.
@item Proximity operators.
@item Support for ``always-index words.'' These could be any strings
the user wants to treat as words, such as ``C++'', ``AS/400'', or ``TCP/IP''.
@item Support for full-text search in @code{MERGE} tables.
@item Support for the @code{ucs2} character set.
@item Make the stopword list dependent on the language of the dataset.
@item Stemming (dependent on the language of the dataset).
@item Generic user-suppliable UDF preparser.
@item Make the model more flexible (by adding some adjustable
parameters to @code{FULLTEXT} in @code{CREATE TABLE} and @code{ALTER TABLE}
statements).
@end itemize


@node Cast Functions, Other Functions, Fulltext Search, Functions
@section Cast Functions and Operators

@findex casts

@cindex cast operators
@cindex operators, cast
@cindex cast functions
@cindex functions, cast

@table @code

@c description_for_help_topic BINARY operator
@item BINARY
@findex BINARY
The @code{BINARY} operator casts the string following it to a binary string.
This is an easy way to force a column comparison to be done byte by byte
rather than character by character. This causes the comparison to be
case sensitive even
if the column isn't defined as @code{BINARY} or @code{BLOB}.
@code{BINARY} also causes trailing spaces to be significant.
@c end_description_for_help_topic

@c example_for_help_topic BINARY operator
@example
mysql> SELECT 'a' = 'A';
        -> 1
mysql> SELECT BINARY 'a' = 'A';
        -> 0
mysql> SELECT 'a' = 'a ';
        -> 1
mysql> SELECT BINARY 'a' = 'a ';
        -> 0
@end example

@code{BINARY} affects the entire comparison; it can be given before
either operand with the same result.

@code{BINARY} was added in MySQL 3.23.0. As of MySQL 4.0.2,
@code{BINARY str} is a shorthand for @code{CAST(str AS BINARY)}.

Note that in some contexts, if you cast an indexed column to @code{BINARY},
MySQL will not be able to use the index efficiently.

If you want to compare a @code{BLOB} value or other binary string
in case-insensitive fashion, you can do so as follows:

@itemize @bullet
@item
Before MySQL 4.1.1, use the @code{UPPER()} function to convert the binary
string to uppercase before performing the comparison:

@example
SELECT 'A' LIKE UPPER(@var{blob_col}) FROM @var{tbl_name};
@end example

If the comparison value is lowercase, convert the string value using
@code{LOWER()} instead.

@item
For MySQL 4.1.1 and up, binary strings have no character set, and
thus no concept of lettercase. To perform a
case-insensitive comparison, use the @code{CONVERT()} function to
convert the string value to a character set that
is not case sensitive. The result is a non-binary string, so the
@code{LIKE} operation is not case sensitive:

@example
SELECT 'A' LIKE CONVERT(@var{blob_col} USING latin1) FROM @var{tbl_name};
@end example

To use a different character set, substitute its name for @code{latin1}
in the preceding statement.

@end itemize

@code{CONVERT()} can be used more generally for comparing strings that
are represented in different character sets.


@item CAST(@var{expr} AS @var{type})
@itemx CONVERT(@var{expr},@var{type})
@itemx CONVERT(@var{expr} USING @var{transcoding_name})
@findex CAST
@findex CONVERT

@c description_for_help_topic CAST  CONVERT SIGNED UNSIGNED BINARY CHAR DATE DATETIME TIME
The @code{CAST()} and @code{CONVERT()} functions can be used to take a
value of one type and produce a value of another type.

The @var{type} can be one of the following values:

@itemize @bullet
@item
@code{BINARY}
@item
@code{CHAR}
@item
@code{DATE}
@item
@code{DATETIME}
@item
@code{SIGNED [INTEGER]}
@item
@code{TIME}
@item
@code{UNSIGNED [INTEGER]}
@end itemize

@code{BINARY} produces a binary string. See the entry for the @code{BINARY}
operator in this section for a description of how this affects comparisons.

@code{CAST()} and @code{CONVERT()} are available as of MySQL 4.0.2.
The @code{CHAR} conversion type is available as of 4.0.6.
The @code{USING} form of @code{CONVERT()} is available as of 4.1.0.

@code{CAST()} and @code{CONVERT(... USING ...)} are standard SQL syntax.
The non-@code{USING} form of @code{CONVERT()} is ODBC syntax.

@code{CONVERT()} with @code{USING} is used to convert data between different
character sets.  In MySQL, transcoding names are the same as the
corresponding character set names.  For example, this statement converts
the string @code{'abc'} in the server's default character set to the
corresponding string in the @code{utf8} character set:

@example
SELECT CONVERT('abc' USING utf8);
@end example

@end table

The cast functions are useful when you want to create a column with
a specific type in a @code{CREATE ... SELECT} statement:
@c end_description_for_help_topic

@example
CREATE TABLE new_table SELECT CAST('2000-01-01' AS DATE);
@end example

The functions also can be useful for sorting @code{ENUM} columns in lexical
order. Normally sorting of @code{ENUM} columns occurs using the internal
numeric values. Casting the values to @code{CHAR} results in a lexical
sort:

@c example_for_help_topic CAST
@example
SELECT @var{enum_col} FROM @var{tbl_name} ORDER BY CAST(@var{enum_col} AS CHAR);
@end example

@code{CAST(@var{str} AS BINARY)} is the same thing as @code{BINARY @var{str}}.
@code{CAST(@var{expr} AS CHAR)} treats the expression as a string with the
default character set.

@strong{Note}: In MysQL 4.0, a @code{CAST()} to @code{DATE},
@code{DATETIME}, or @code{TIME} only marks the column to be a specific
type but doesn't change the value of the column.

As of MySQL 4.1.0, the value is converted to the correct column type when
it's sent to the user (this is a feature of how the new protocol in 4.1
sends date information to the client):

@example
mysql> SELECT CAST(NOW() AS DATE);
       -> 2003-05-26
@end example

As of MySQL 4.1.1, @code{CAST()}
also changes the result if you use it as part of a more complex expression
such as @code{CONCAT('Date: ',CAST(NOW() AS DATE))}.

You should not use @code{CAST()} to extract data in different formats but
instead use string functions like @code{LEFT()} or
@code{EXTRACT()}. @xref{Date and time functions}.

To cast a string to a numeric value in numeric context, you don't normally
have to do anything. Just use the string value as though it were a number:

@example
mysql> SELECT 1+'1';
       -> 2
@end example

If you use a number in string context, the number automatically is
converted to a @code{BINARY} string.

@example
mysql> SELECT CONCAT('hello you ',2);
        -> 'hello you 2'
@end example

MySQL supports arithmetic with both signed and unsigned 64-bit values.
If you are using numeric operators (such as @code{+}) and one of the
operands is an unsigned integer, the result is unsigned.
You can override this by using the @code{SIGNED} and @code{UNSIGNED}
cast operators to cast the operation to a signed or
unsigned 64-bit integer, respectively.

@example
mysql> SELECT CAST(1-2 AS UNSIGNED)
        -> 18446744073709551615
mysql> SELECT CAST(CAST(1-2 AS UNSIGNED) AS SIGNED);
        -> -1
@end example

Note that if either operand is a floating-point value, the result is
a floating-point value and is not affected by the preceding rule.
(In this context, @code{DECIMAL} column values are regarded as
floating-point values.)

@example
mysql> SELECT CAST(1 AS UNSIGNED) - 2.0;
        -> -1.0
@end example

If you are using a string in an arithmetic operation, this is converted
to a floating-point number.

The handing of unsigned values was changed in MySQL 4.0 to be able to
support @code{BIGINT} values properly. If you have some code that you
want to run in both MySQL 4.0 and 3.23, you probably can't
use the @code{CAST()} function. You can use the following technique to get
a signed result when subtracting two unsigned integer columns @code{ucol1} and
@code{ucol2}:

@example
mysql> SELECT (ucol1+0.0)-(ucol2+0.0) FROM ...;
@end example

The idea is that the columns are converted to floating-point values before
the subtraction occurs.

If you have a problem with @code{UNSIGNED} columns in old MySQL
applications when porting them to MySQL 4.0, you can use the
@code{--sql-mode=NO_UNSIGNED_SUBTRACTION} option when starting
@command{mysqld}.  However, as long as you use this option, you will not
be able to make efficient use of the @code{BIGINT UNSIGNED} column type.


@node Other Functions, Group by functions and modifiers, Cast Functions, Functions
@section Other Functions

@menu
* Bit functions::               Bit Functions
* Encryption functions::        Encryption Functions
* Information functions::       Information Functions
* Miscellaneous functions::     Miscellaneous Functions
@end menu
@c help_category Bit Functions@Functions

@node Bit functions, Encryption functions, Other Functions, Other Functions
@subsection Bit Functions

@findex arithmetic functions
@findex functions, arithmetic
@findex functions, bit

MySQL uses @code{BIGINT} (64-bit) arithmetic for bit operations, so
these operators have a maximum range of 64 bits.

@table @code

@c description_for_help_topic |
@item |
@findex | (bitwise OR)
@findex OR, bitwise
Bitwise OR:
@c end_description_for_help_topic

@c example_for_help_topic |
@example
mysql> SELECT 29 | 15;
        -> 31
@end example

The result is an unsigned 64-bit integer.

@c description_for_help_topic &
@item &
@findex & (bitwise AND)
@findex AND, bitwise
Bitwise AND:
@c end_description_for_help_topic

@c example_for_help_topic &
@example
mysql> SELECT 29 & 15;
        -> 13
@end example

The result is an unsigned 64-bit integer.

@c description_for_help_topic ^
@item ^
@findex ^ (bitwise XOR)
@findex XOR, bitwise
Bitwise XOR:
@c end_description_for_help_topic

@c example_for_help_topic ^
@example
mysql> SELECT 1 ^ 1;
        -> 0
mysql> SELECT 1 ^ 0;
        -> 1
mysql> SELECT 11 ^ 3;
        -> 8
@end example

The result is an unsigned 64-bit integer.

Bitwise XOR was added in MySQL 4.0.2.

@c description_for_help_topic <<
@item <<
@findex << (left shift)
Shifts a longlong (@code{BIGINT}) number to the left.
@c end_description_for_help_topic

@c example_for_help_topic <<
@example
mysql> SELECT 1 << 2;
        -> 4
@end example

The result is an unsigned 64-bit integer.

@c description_for_help_topic >>
@item >>
@findex >> (right shift)
Shifts a longlong (@code{BIGINT}) number to the right.
@c end_description_for_help_topic

@c example_for_help_topic >>
@example
mysql> SELECT 4 >> 2;
        -> 1
@end example

The result is an unsigned 64-bit integer.

@c description_for_help_topic ~
@item ~
@findex ~
Invert all bits.
@c end_description_for_help_topic

@c example_for_help_topic ~
@example
mysql> SELECT 5 & ~1;
        -> 4
@end example

The result is an unsigned 64-bit integer.

@c description_for_help_topic BIT_COUNT
@item BIT_COUNT(@var{N})
@findex BIT_COUNT()
Returns the number of bits that are set in the argument @var{N}.
@c end_description_for_help_topic

@c example_for_help_topic BIT_COUNT
@example
mysql> SELECT BIT_COUNT(29);
        -> 4
@end example

@end table


@node Encryption functions, Information functions, Bit functions, Other Functions
@subsection Encryption Functions

@findex encryption functions
@findex functions, encryption
@c help_category Encryption Functions@Functions

The functions in this section encrypt and decrypt data values.
If you want to store results from an encryption function that might contain
arbitrary byte values, use a @code{BLOB} column rather than a @code{CHAR}
or @code{VARCHAR} column to avoid potential problems with trailing
space removal that would change data values.

@table @code

@c description_for_help_topic AES_DECRYPT  AES_ENCRYPT
@item AES_ENCRYPT(@var{str},@var{key_str})
@itemx AES_DECRYPT(@var{crypt_str},@var{key_str})
@findex AES_ENCRYPT()
@findex AES_DECRYPT()
These functions allow encryption and decryption of data using the official
AES (Advanced Encryption Standard) algorithm, previously known as "Rijndael."
Encoding with a 128-bit key length is used, but you can extend it up to
256 bits by modifying the source. We chose 128 bits because it is much
faster and it is usually secure enough.

The input arguments may be any length. If either argument is @code{NULL},
the result of this function is also @code{NULL}.

Because AES is a block-level algorithm, padding is used to encode uneven length
strings and so the result string length may be calculated as
@code{16*(trunc(@var{string_length}/16)+1)}.

If @code{AES_DECRYPT()} detects invalid data or incorrect padding, it
returns @code{NULL}. However, it is possible for @code{AES_DECRYPT()}
to return a non-@code{NULL} value (possibly garbage) if the input data or
the key is invalid.

You can use the AES functions to store data in an encrypted form by
modifying your queries:
@c end_description_for_help_topic

@c example_for_help_topic AES_DECRYPT
@example
INSERT INTO t VALUES (1,AES_ENCRYPT('text','password'));
@end example

You can get even more security by not transferring the key over the
connection for each query, which can be accomplished by storing it in a
server-side variable at connection time. For example:
@example
SELECT @@password:='my password';
INSERT INTO t VALUES (1,AES_ENCRYPT('text',@@password));
@end example

@code{AES_ENCRYPT()} and @code{AES_DECRYPT()} were added in MySQL 4.0.2,
and can be considered the most cryptographically secure encryption
functions currently available in MySQL.

@c description_for_help_topic DECODE
@item DECODE(@var{crypt_str},@var{pass_str})
@findex DECODE()
Decrypts the encrypted string @var{crypt_str} using @var{pass_str} as the
password.  @var{crypt_str} should be a string returned from
@code{ENCODE()}.
@c end_description_for_help_topic

@c description_for_help_topic ENCODE
@item ENCODE(@var{str},@var{pass_str})
@findex ENCODE()
Encrypt @var{str} using @var{pass_str} as the password.
To decrypt the result, use @code{DECODE()}.

The result is a binary string of the same length as @var{str}.
If you want to save it in a column, use a @code{BLOB} column type.
@c end_description_for_help_topic

@c description_for_help_topic DES_DECRYPT
@item DES_DECRYPT(@var{crypt_str}[,@var{key_str}])
@findex DES_DECRYPT()

Decrypts a string encrypted with @code{DES_ENCRYPT()}.
On error, this function returns @code{NULL}.

Note that this function works only if MySQL has been configured with
SSL support. @xref{Secure connections}.

If no @var{key_str} argument is given, @code{DES_DECRYPT()} examines
the first byte of the encrypted string to determine the DES key number
that was used to encrypt the original string, and then reads the key
from the DES key file to decrypt the message.  For this to work,
the user must have the @code{SUPER} privilege. The key file can be specified
with the @code{--des-key-file} server option.

If you pass this function a @var{key_str} argument, that string
is used as the key for decrypting the message.

If the @var{crypt_str} argument doesn't look like an encrypted string,
MySQL will return the given @var{crypt_str}.
@c end_description_for_help_topic

@code{DES_DECRYPT()} was added in MySQL 4.0.1.

@c description_for_help_topic DES_ENCRYPT
@item DES_ENCRYPT(@var{str}[,(@var{key_num}|@var{key_str})])
@findex DES_ENCRYPT()

Encrypts the string with the given key using the Triple-DES algorithm.
On error, this function returns @code{NULL}.

Note that this function works only if MySQL has been configured with
SSL support. @xref{Secure connections}.

The encryption key to use is chosen based on the second argument to
@code{DES_ENCRYPT()}, if one was given:

@multitable @columnfractions .25 .65
@item @strong{Argument} @tab @strong{Description}
@item No argument @tab
The first key from the DES key file is used.
@item @var{key_num} @tab
The given key number (0-9) from the DES key file is used.
@item @var{key_str} @tab
The given key string is used to encrypt @var{str}.
@end multitable

The key file can be specified with the @code{--des-key-file} server option.

The return string is a binary string where the first character
is @code{CHAR(128 | key_num)}.

The 128 is added to make it easier to recognize an encrypted key.
If you use a string key, @var{key_num} will be 127.

The string length for the result will be
@code{@var{new_len} = @var{orig_len} + (8-(@var{orig_len} % 8))+1}.
@c end_description_for_help_topic

Each line in the DES key file has the following format:

@c example_for_help_topic DES_ENCRYPT
@example
@var{key_num} @var{des_key_str}
@end example

Each @var{key_num} must be a number in the range from @code{0} to @code{9}.  Lines in
the file may be in any order.  @var{des_key_str} is the string that
will be used to encrypt the message.  Between the number and the key there
should be at least one space.  The first key is the default key that is
used if you don't specify any key argument to @code{DES_ENCRYPT()}

You can tell MySQL to read new key values from the key file with the
@code{FLUSH DES_KEY_FILE} statement.  This requires the @code{RELOAD}
privilege.

One benefit of having a set of default keys is that it gives applications
a way to check for the existence of encrypted column values, without giving
the end user the right to decrypt those values.

@example
mysql> SELECT customer_address FROM customer_table WHERE
       crypted_credit_card = DES_ENCRYPT('credit_card_number');
@end example

@code{DES_ENCRYPT()} was added in MySQL 4.0.1.

@c description_for_help_topic ENCRYPT
@item ENCRYPT(@var{str}[,@var{salt}])
@findex ENCRYPT()
Encrypt @var{str} using the Unix @code{crypt()} system call. The
@var{salt} argument should be a string with two characters.
(As of MySQL 3.22.16, @var{salt} may be longer than two characters.)
If no @var{salt} argument is given, a random value is used.
@c end_description_for_help_topic

@c example_for_help_topic ENCRYPT
@example
mysql> SELECT ENCRYPT('hello');
        -> 'VxuFAJXVARROc'
@end example

@code{ENCRYPT()} ignores all but the first eight characters of @var{str}, at
least on some systems.  This behavior is determined by the implementation
of the underlying @code{crypt()} system call.

If @code{crypt()} is not available on your system, @code{ENCRYPT()} always
returns @code{NULL}.  Because of this, we recommend that you use @code{MD5()}
or @code{SHA1()} instead, because those two functions exist on all platforms.

@c description_for_help_topic MD5
@item MD5(@var{str})
@findex MD5()
Calculates an MD5 128-bit checksum for the string. The value is returned
as a binary string of 32 hex digits,
or @code{NULL} if the argument was @code{NULL}.
The return value can, for example, be used as a hash key.
@c end_description_for_help_topic

@c example_for_help_topic MD5
@example
mysql> SELECT MD5('testing');
        -> 'ae2b1fca515949e5d54fb22b8ed95575'
@end example

This is the "RSA Data Security, Inc. MD5 Message-Digest Algorithm."

If you want to convert the value to uppercase, see the description of binary
string conversion given in the entry for the @code{BINARY} operator in
@ref{Cast Functions}.

@code{MD5()} was added in MySQL 3.23.2.

@c description_for_help_topic OLD_PASSWORD
@item OLD_PASSWORD(@var{str})
@findex OLD_PASSWORD()


@code{OLD_PASSWORD()} is available as of MySQL 4.1, when the implementation of
@code{PASSWORD()} was changed to improve security. @code{OLD_PASSWORD()}
returns the value of the pre-4.1 implementation of @code{PASSWORD()}.
@ref{Password hashing}.

@c description_for_help_topic PASSWORD
@item PASSWORD(@var{str})
@findex PASSWORD()
Calculates and returns a password string from the plaintext password
@var{str}, or @code{NULL} if the argument was @code{NULL}. This is
the function that is used for encrypting MySQL passwords for storage
in the @code{Password} column of the @code{user} grant table.
@c end_description_for_help_topic

@c example_for_help_topic PASSWORD
@example
mysql> SELECT PASSWORD('badpwd');
        -> '7f84554057dd964b'
@end example

@cindex password encryption, reversibility of
@code{PASSWORD()} encryption is one-way (not reversible).

@code{PASSWORD()} does not perform password encryption in the same way that
Unix passwords are encrypted. See @code{ENCRYPT()}.

@strong{Note}:
The @code{PASSWORD()} function is used by the authentication system in
MySQL Server, you should @emph{not} use it in your own applications.
For that purpose, use @code{MD5()} or @code{SHA1()} instead.
Also see RFC 2195 for more information about handling passwords
and authentication securely in your application.

@c description_for_help_topic SHA  SHA1
@item SHA1(@var{str})
@itemx SHA(@var{str})
@findex SHA1()
@findex SHA()
Calculates an SHA1 160-bit checksum for the string, as described in
RFC 3174 (Secure Hash Algorithm). The value is returned as a string of 40 hex
digits, or @code{NULL} if the argument was @code{NULL}.
One of the possible uses for this function is as a hash key. You can
also use it as a cryptographically safe function for storing passwords.

@c end_description_for_help_topic
@c example_for_help_topic SHA
@example
mysql> SELECT SHA1('abc');
        -> 'a9993e364706816aba3e25717850c26c9cd0d89d'
@end example

@code{SHA1()} was added in MySQL 4.0.2, and can be considered
a cryptographically more secure equivalent of @code{MD5()}.
@code{SHA()} is synonym for @code{SHA1()}.

@end table


@node Information functions, Miscellaneous functions, Encryption functions, Other Functions
@subsection Information Functions

@findex information functions
@findex functions, information
@c help_category Information Functions@Functions

@table @code

@c description_for_help_topic BENCHMARK
@item BENCHMARK(@var{count},@var{expr})
@findex BENCHMARK()
The @code{BENCHMARK()} function executes the expression @var{expr}
repeatedly @var{count} times.  It may be used to time how fast MySQL
processes the expression.  The result value is always @code{0}.  The intended
use is from within the @command{mysql} client, which reports query execution times:
@c end_description_for_help_topic

@c example_for_help_topic BENCHMARK
@example
mysql> SELECT BENCHMARK(1000000,ENCODE('hello','goodbye'));
+----------------------------------------------+
| BENCHMARK(1000000,ENCODE('hello','goodbye')) |
+----------------------------------------------+
|                                            0 |
+----------------------------------------------+
1 row in set (4.74 sec)
@end example

The time reported is elapsed time on the client end, not CPU time on the
server end.  It is advisable to execute @code{BENCHMARK()} several
times, and to interpret the result with regard to how heavily loaded the
server machine is.

@c description_for_help_topic CHARSET
@item CHARSET(@var{str})
@findex CHARSET()
Returns the character set of the string argument.
@c end_description_for_help_topic

@c example_for_help_topic CHARSET
@example
mysql> SELECT CHARSET('abc');
        -> 'latin1'
mysql> SELECT CHARSET(CONVERT('abc' USING utf8));
        -> 'utf8'
mysql> SELECT CHARSET(USER());
        -> 'utf8'
@end example

@code{CHARSET()} was added in MySQL 4.1.0.

@c description_for_help_topic COERCIBILITY
@item COERCIBILITY(@var{str})
@findex COERCIBILITY()
Returns the collation coercibility value of the string argument.
@c end_description_for_help_topic

@c example_for_help_topic COERCIBILITY
@example
mysql> SELECT COERCIBILITY('abc' COLLATE latin1_swedish_ci);
        -> 0
mysql> SELECT COERCIBILITY('abc');
        -> 3
mysql> SELECT COERCIBILITY(USER());
        -> 2
@end example

The return values have the following meanings:

@multitable @columnfractions .30 .50
@item @strong{Coercibility} @tab @strong{Meaning}
@item @code{0} @tab Explicit collation
@item @code{1} @tab No collation
@item @code{2} @tab Implicit collation
@item @code{3} @tab Coercible
@end multitable

Lower values have higher precedence.

@code{COERCIBILITY()} was added in MySQL 4.1.1.

@c description_for_help_topic COLLATION
@item COLLATION(@var{str})
@findex COLLATION()
Returns the collation for the character set of the string argument.
@c end_description_for_help_topic

@c example_for_help_topic COLLATION
@example
mysql> SELECT COLLATION('abc');
        -> 'latin1_swedish_ci'
mysql> SELECT COLLATION(_utf8'abc');
        -> 'utf8_general_ci'
@end example

@code{COLLATION()} was added in MySQL 4.1.0.

@c description_for_help_topic CONNECTION_ID
@item CONNECTION_ID()
@findex CONNECTION_ID()
Returns the connection ID (thread ID) for the connection.
Every connection has its own unique ID.
@c end_description_for_help_topic

@c example_for_help_topic CONNECTION_ID
@example
mysql> SELECT CONNECTION_ID();
        -> 23786
@end example

@code{CONNECTION_ID()} was added in MySQL 3.23.14.

@c description_for_help_topic CURRENT_USER
@item CURRENT_USER()
@findex CURRENT_USER()
Returns the username and hostname combination that the current session was authenticated
as. This value corresponds to the MySQL account that determines your
access privileges. It can be different from the value of @code{USER()}.
@c end_description_for_help_topic

@c example_for_help_topic CURRENT_USER
@example
mysql> SELECT USER();
        -> 'davida@@localhost'
mysql> SELECT * FROM mysql.user;
ERROR 1044: Access denied for user ''@@'localhost' to
database 'mysql'
mysql> SELECT CURRENT_USER();
        -> '@@localhost'
@end example

The example illustrates that although the client specified a username of
@code{davida} (as indicated by the value of the @code{USER()} function),
the server authenticated the client using an anonymous user account (as seen by
the empty username part of the @code{CURRENT_USER()} value). One way this might
occur is that there is no account listed in the grant tables for
@code{davida}.

@code{CURRENT_USER()} was added in MySQL 4.0.6.

@c description_for_help_topic DATABASE
@item DATABASE()
@findex DATABASE()
Returns the default (current) database name.
@c end_description_for_help_topic

@c example_for_help_topic DATABASE
@example
mysql> SELECT DATABASE();
        -> 'test'
@end example

If there is no default database, @code{DATABASE()} returns @code{NULL} as
of MySQL 4.1.1, and the empty string before that.


@item FOUND_ROWS()
@findex FOUND_ROWS()
@findex LIMIT
@c description_for_help_topic FOUND_ROWS

A @code{SELECT} statement may include a @code{LIMIT} clause to restrict the
number of rows the server returns to the client.
In some cases, it is desirable to know how many rows the statement would have
returned without the @code{LIMIT}, but without running the statement again.
To get this row count, include a @code{SQL_CALC_FOUND_ROWS} option in the
@code{SELECT} statement, then invoke @code{FOUND_ROWS()} afterward:
@c end_description_for_help_topic

@c example_for_help_topic FOUND_ROWS
@example
mysql> SELECT SQL_CALC_FOUND_ROWS * FROM @var{tbl_name}
    -> WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();
@end example

The second @code{SELECT} will return a number indicating how many rows the
first @code{SELECT} would have returned had it been written without the
@code{LIMIT} clause.
(If the preceding @code{SELECT} statement does not include the
@code{SQL_CALC_FOUND_ROWS} option, then @code{FOUND_ROWS()} may return
a different result when @code{LIMIT} is used than when it is not.)

Note that if you are using @code{SELECT SQL_CALC_FOUND_ROWS}, MySQL must
calculate how many rows are in the full result set.  However, this is
faster than running the query again without @code{LIMIT}, because the result
set need not be sent to the client.

@code{SQL_CALC_FOUND_ROWS} and @code{FOUND_ROWS()} can be useful in situations
when you want to restrict the number of rows that a query returns, but also
determine the number of rows in the full result set without running the query
again. An example is a Web script that presents a paged display containing
links to the pages that show other sections of a search result. Using
@code{FOUND_ROWS()} allows you to determine how many other pages are needed
for the rest of the result.

The use of @code{SQL_CALC_FOUND_ROWS} and @code{FOUND_ROWS()} is more complex
for @code{UNION} queries than for simple @code{SELECT} statements, because
@code{LIMIT} may occur at multiple places in a @code{UNION}. It may be applied
to individual @code{SELECT} statements in the @code{UNION}, or global to the
@code{UNION} result as a whole.

The intent of @code{SQL_CALC_FOUND_ROWS} for @code{UNION} is that it should
return the row count that would be returned without a global @code{LIMIT}.
The conditions for use of @code{SQL_CALC_FOUND_ROWS} with @code{UNION} are:

@itemize @bullet

@item
The @code{SQL_CALC_FOUND_ROWS} keyword must appear in the first @code{SELECT}
of the @code{UNION}.

@item
The value of @code{FOUND_ROWS()} is exact only if @code{UNION ALL} is used.
If @code{UNION} without @code{ALL} is used, duplicate removal occurs and the
value of @code{FOUND_ROWS()} is only approximate.

@item
If no @code{LIMIT} is present in the @code{UNION}, @code{SQL_CALC_FOUND_ROWS}
is ignored and returns the number of rows in the temporary table that is
created to process the @code{UNION}.

@end itemize

@code{SQL_CALC_FOUND_ROWS} and @code{FOUND_ROWS()} are available starting
at MySQL 4.0.0.

@c description_for_help_topic LAST_INSERT_ID
@item LAST_INSERT_ID()
@itemx LAST_INSERT_ID(@var{expr})
@findex LAST_INSERT_ID([@var{expr}])
Returns the last automatically generated value that was inserted into
an @code{AUTO_INCREMENT} column.
@c end_description_for_help_topic

@c example_for_help_topic LAST_INSERT_ID
@example
mysql> SELECT LAST_INSERT_ID();
        -> 195
@end example

The last ID that was generated is maintained in the server on a
per-connection basis. This means the value the function returns to a given
client is the most recent @code{AUTO_INCREMENT} value generated by that
client. The value cannot be affected by other clients, even if they generate
@code{AUTO_INCREMENT} values of their own. This behavior ensures that you can
retrieve your own ID without concern for the activity of other clients, and
without the need for locks or transactions.

The value of @code{LAST_INSERT_ID()} is not changed if you
update the @code{AUTO_INCREMENT} column of a row with a
non-magic value (that is, a value that is not @code{NULL} and not @code{0}).

If you insert many rows at the same time with an insert statement,
@code{LAST_INSERT_ID()} returns the value for the first inserted row.
The reason for this is to make it possible to easily reproduce
the same @code{INSERT} statement against some other server.

If you use @code{INSERT IGNORE} and the record is ignored, the
@code{AUTO_INCREMENT} counter still is incremented and
@code{LAST_INSERT_ID()} returns the new value.

@cindex sequence emulation
If @var{expr} is given as an argument to @code{LAST_INSERT_ID()},
the value of the argument is returned by the function and is remembered as the
next value to be returned by @code{LAST_INSERT_ID()}.  This can be used
to simulate sequences:

@itemize @bullet
@item
Create a table to hold the sequence counter and initialize it:

@example
mysql> CREATE TABLE sequence (id INT NOT NULL);
mysql> INSERT INTO sequence VALUES (0);
@end example

@item
Use the table to generate sequence numbers like this:

@example
mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1);
mysql> SELECT LAST_INSERT_ID();
@end example

The @code{UPDATE} statement increments the sequence counter and causes the
next call to @code{LAST_INSERT_ID()} to return the updated value.
The @code{SELECT} statement retrieves that value.
The @code{mysql_insert_id()} C API function
can also be used to get the value.
@xref{mysql_insert_id,, @code{mysql_insert_id()}}.

@end itemize

You can generate sequences without calling @code{LAST_INSERT_ID()}, but the
utility of using the function this way is that the ID value is maintained in
the server as the last automatically generated value.
It is multi-user safe because multiple clients can issue the @code{UPDATE}
statement and get their own sequence value with the @code{SELECT} statement
(or @code{mysql_insert_id()}), without affecting or being affected by other
clients that generate their own sequence values.

Note that @code{mysql_insert_id()} is only updated after @code{INSERT}
and @code{UPDATE} statements, so you cannot use the C API function to
retrieve the value for @code{LAST_INSERT_ID(@var{expr})} after executing other
SQL statements like @code{SELECT} or @code{SET}.

@c description_for_help_topic ROW_COUNT
@item ROW_COUNT()
@findex ROW_COUNT()

@code{ROW_COUNT()} returns the number of rows updated, inserted, or deleted
by the preceding statement.  This is the same as the row count that the
@command{mysql} client displays and the value from the
@code{mysql_affected_rows()} C API function.
@c end_description_for_help_topic

@c example_for_help_topic ROW_COUNT
@example
mysql> INSERT INTO t VALUES(1),(2),(3);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|           3 |
+-------------+
1 row in set (0.00 sec)

mysql> DELETE FROM t WHERE i IN(1,2);
Query OK, 2 rows affected (0.00 sec)

mysql> SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|           2 |
+-------------+
1 row in set (0.00 sec)
@end example

@code{ROW_COUNT()} was added in MySQL 5.0.1.

@c description_for_help_topic SESSION_USER
@item SESSION_USER()
@findex SESSION_USER()

@code{SESSION_USER()} is a synonym for @code{USER()}.
@c end_description_for_help_topic

@c description_for_help_topic SYSTEM_USER
@item SYSTEM_USER()
@findex SYSTEM_USER()

@code{SYSTEM_USER()} is a synonym for @code{USER()}.
@c end_description_for_help_topic

@c description_for_help_topic USER
@item USER()
@findex USER()

Returns the current MySQL username and hostname.
@c end_description_for_help_topic

@c example_for_help_topic USER
@example
mysql> SELECT USER();
        -> 'davida@@localhost'
@end example

The value indicates the username you specified when connecting to
the server, and the client host from which you connected. The value can be
different than that of @code{CURRENT_USER()}.

Prior to MySQL 3.22.11, the function value does not include the client
hostname.  You can extract just the username part, regardless of whether the
value includes a hostname part, like this:

@example
mysql> SELECT SUBSTRING_INDEX(USER(),'@@',1);
        -> 'davida'
@end example

As of MySQL 4.1, @code{USER()} returns a value in the @code{utf8} character
set, so you should also make sure that the @code{'@@'} string literal is
interpreted in that character set:

@example
mysql> SELECT SUBSTRING_INDEX(USER(),_utf8'@@',1);
        -> 'davida'
@end example

@c description_for_help_topic VERSION
@item VERSION()
@findex VERSION()
Returns a string that indicates the MySQL server version.
@c end_description_for_help_topic

@c example_for_help_topic VERSION
@example
mysql> SELECT VERSION();
        -> '4.1.3-beta-log'
@end example

Note that if your version string ends with @code{-log} this means that
logging is enabled.

@end table


@node Miscellaneous functions,  , Information functions, Other Functions
@subsection Miscellaneous Functions

@findex miscellaneous functions
@findex functions, miscellaneous
@c help_category Miscellaneous Functions@Functions

@table @code

@c description_for_help_topic DEFAULT
@item DEFAULT(@var{col_name})
@findex DEFAULT()
Returns the default value for a table column.
Starting from MySQL 5.0.2, you will get an error if the column doesn't have
a default value.
@c end_description_for_help_topic

@c example_for_help_topic DEFAULT
@example
mysql> UPDATE t SET i = DEFAULT(i)+1 WHERE id < 100;
@end example

@code{DEFAULT()} was added in MySQL 4.1.0.

@c description_for_help_topic FORMAT
@item FORMAT(@var{X},@var{D})
@findex FORMAT()
Formats the number @var{X} to a format like @code{'#,###,###.##'}, rounded
to @var{D} decimals, and returns the result as a string.
If @var{D} is @code{0}, the result will have no
decimal point or fractional part.
@c end_description_for_help_topic

@c example_for_help_topic FORMAT
@example
mysql> SELECT FORMAT(12332.123456, 4);
        -> '12,332.1235'
mysql> SELECT FORMAT(12332.1,4);
        -> '12,332.1000'
mysql> SELECT FORMAT(12332.2,0);
        -> '12,332'
@end example

@c description_for_help_topic GET_LOCK
@item GET_LOCK(@var{str},@var{timeout})
@cindex timeout
@findex GET_LOCK()
Tries to obtain a lock with a name given by the string @var{str}, with a
timeout of @var{timeout} seconds.  Returns @code{1} if the lock was obtained
successfully, @code{0} if the attempt timed out (for example, because another
client has already locked the name), or @code{NULL} if an error
occurred (such as running out of memory or the thread was killed with
@command{mysqladmin kill}).  If you have a lock obtained with @code{GET_LOCK()},
it is released when you execute
@code{RELEASE_LOCK()}, execute a new @code{GET_LOCK()}, or your connection
terminates (either normally or abnormally).

This function can be used to implement application locks or to
simulate record locks.  Names are locked on a server-wide basis.
If a name has been locked by one client, @code{GET_LOCK()} blocks
any request by another client for a lock with the same name. This
allows clients that agree on a given lock name to use the name to
perform cooperative advisory locking.
@c end_description_for_help_topic

@c example_for_help_topic GET_LOCK
@example
mysql> SELECT GET_LOCK('lock1',10);
        -> 1
mysql> SELECT IS_FREE_LOCK('lock2');
        -> 1
mysql> SELECT GET_LOCK('lock2',10);
        -> 1
mysql> SELECT RELEASE_LOCK('lock2');
        -> 1
mysql> SELECT RELEASE_LOCK('lock1');
        -> NULL
@end example

Note that the second @code{RELEASE_LOCK()} call returns @code{NULL} because
the lock @code{'lock1'} was automatically released by the second
@code{GET_LOCK()} call.

@c description_for_help_topic INET_ATON
@item INET_ATON(@var{expr})
@findex INET_ATON()
Given the dotted-quad representation of a network address as a string,
returns an integer that represents the numeric value of the address.
Addresses may be 4- or 8-byte addresses.
@c end_description_for_help_topic

@c example_for_help_topic INET_ATON
@example
mysql> SELECT INET_ATON('209.207.224.40');
        -> 3520061480
@end example

The generated number is always in network byte order. For the example
just shown, the number is calculated as @code{209*256^3 + 207*256^2 +
224*256 + 40}.

As of MySQL 4.1.2, @code{INET_ATON()} also understands short-form IP
addresses:

@example
mysql> SELECT INET_ATON('127.0.0.1'), INET_ATON('127.1');
        -> 2130706433, 2130706433
@end example

@code{INET_ATON()} was added in MySQL 3.23.15.

@c description_for_help_topic INET_NTOA
@item INET_NTOA(@var{expr})
@findex INET_NTOA()
Given a numeric network address (4 or 8 byte), returns the dotted-quad
representation of the address as a string.
@c end_description_for_help_topic

@c example_for_help_topic INET_NTOA
@example
mysql> SELECT INET_NTOA(3520061480);
        -> '209.207.224.40'
@end example

@code{INET_NTOA()} was added in MySQL 3.23.15.

@c description_for_help_topic IS_FREE_LOCK
@item IS_FREE_LOCK(@var{str})
@findex IS_FREE_LOCK()
Checks whether the lock named @var{str} is free to use (that is, not locked).
Returns @code{1} if the lock is free (no one is using the lock),
@code{0} if the lock is in use, and
@code{NULL} on errors (such as incorrect arguments).
@c end_description_for_help_topic

@code{IS_FREE_LOCK()} was added in MySQL 4.0.2.

@c description_for_help_topic IS_USED_LOCK
@item IS_USED_LOCK(@var{str})
@findex IS_USED_LOCK()
Checks whether the lock named @var{str} is in use (that is, locked).
If so, it returns the connection identifier of the client that holds
the lock.
Otherwise, it returns @code{NULL}.
@c end_description_for_help_topic

@code{IS_USED_LOCK()} was added in MySQL 4.1.0.


@c description_for_help_topic MASTER_POS_WAIT
@item MASTER_POS_WAIT(@var{log_name},@var{log_pos}[,@var{timeout}])
@findex MASTER_POS_WAIT()

This function is useful for control of master/slave synchronization.
It blocks until the slave has read and applied all updates up to the specified
position in the master log.
The return value is the number of log events it had to wait for to get to
the specified position.  The function returns @code{NULL} if the slave SQL thread
is not started, the slave's master information is not initialized, the
arguments are incorrect, or an error occurs. It returns @code{-1} if the
timeout has been exceeded. If the slave SQL thread stops while
@code{MASTER_POS_WAIT()} is waiting, the function returns @code{NULL}.
If the slave is already past the specified position, the function returns
immediately.
@c end_description_for_help_topic

If a @var{timeout} value is specified, @code{MASTER_POS_WAIT()}
stops waiting when @var{timeout} seconds have elapsed. @var{timeout} must
be greater than 0; a zero or negative @var{timeout} means no timeout.

@code{MASTER_POS_WAIT()} was added in MySQL 3.23.32.
The @var{timeout} argument was added in 4.0.10.

@c description_for_help_topic RELEASE_LOCK
@item RELEASE_LOCK(@var{str})
@findex RELEASE_LOCK()
Releases the lock named by the string @var{str} that was obtained with
@code{GET_LOCK()}. Returns @code{1} if the lock was released, @code{0} if the
lock wasn't locked by this thread (in which case the lock is not released),
and @code{NULL} if the named lock didn't exist.  The lock will not exist if
it was never obtained by a call to @code{GET_LOCK()} or if it already has
been released.

The @code{DO} statement is convenient to use with @code{RELEASE_LOCK()}.
@xref{DO,  , @code{DO}}.
@c end_description_for_help_topic

@c description_for_help_topic UUID
@item UUID()
@findex UUID()

Returns a Universal Unique Identifier (UUID) generated
according to ``DCE 1.1: Remote Procedure Call'' (Appendix A)
CAE (Common Applications Environment) Specifications
published by The Open Group in October 1997 (Document Number C706).

A UUID is designed as a number that is globally unique in space and
time. Two calls to @code{UUID()} are expected to generate two different
values, even if these calls are performed on two separate computers that are
not connected to each other.

A UUID is a 128-bit number represented by a string
of five hexadecimal numbers in @code{aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee}
format:

@itemize @bullet

@item
The first three numbers are generated from a timestamp.

@item
The fourth number preserves temporal uniqueness in case the timestamp value loses
monotonicity (for example, due to daylight saving time).

@item
The fifth number is an IEEE 802 node number that provides spatial uniqueness.  A
random number is substituted if the latter is not available (for example,
because the host computer has no Ethernet card, or we do not know how to
find the hardware address of an interface on your operating system).  In
this case, spatial uniqueness cannot be guaranteed. Nevertheless, a
collision should have @emph{very} low probability.

Currently, the MAC address of an interface is taken into account only on
FreeBSD and Linux. On other operating systems, MySQL uses a randomly generated
48-bit number.

@end itemize
@c end_description_for_help_topic

@c example_for_help_topic UUID
@example
mysql> SELECT UUID();
        -> '6ccd780c-baba-1026-9564-0040f4311e29'
@end example

Note that @code{UUID()} does not yet work with replication.

@code{UUID()} was added in MySQL 4.1.2.

@end table

@node Group by functions and modifiers,  , Other Functions, Functions
@section Functions and Modifiers for Use with @code{GROUP BY} Clauses
@c help_category Functions and Modifiers for Use with GROUP BY Clauses@Functions

@menu
* GROUP-BY-Functions::          @code{GROUP BY} (Aggregate) Functions
* GROUP-BY-Modifiers::          @code{GROUP BY} Modifiers
* GROUP-BY-hidden-fields::      @code{GROUP BY} with Hidden Fields
@end menu

@node GROUP-BY-Functions, GROUP-BY-Modifiers, Group by functions and modifiers, Group by functions and modifiers
@subsection @code{GROUP BY} (Aggregate) Functions

@findex GROUP BY functions
@findex functions, GROUP BY

If you use a group function in a statement containing no @code{GROUP BY}
clause, it is equivalent to grouping on all rows.

@table @code

@c description_for_help_topic AVG
@item AVG(@var{expr})
@findex AVG()
Returns the average value of @code{@var{expr}}.
@c end_description_for_help_topic

@c example_for_help_topic AVG
@example
mysql> SELECT student_name, AVG(test_score)
    ->        FROM student
    ->        GROUP BY student_name;
@end example

@c description_for_help_topic BIT_AND
@item BIT_AND(@var{expr})
@findex BIT_AND()
Returns the bitwise @code{AND} of all bits in @var{expr}. The calculation is
performed with 64-bit (@code{BIGINT}) precision.
@c end_description_for_help_topic

As of MySQL 4.0.17, this function returns
@code{18446744073709551615} if there were no matching rows.
(This is an unsigned @code{BIGINT} value with all bits set to 1.)
Before 4.0.17, the function returns @code{-1} if there were no matching rows.

@c description_for_help_topic BIT_OR
@item BIT_OR(@var{expr})
@findex BIT_OR()
Returns the bitwise @code{OR} of all bits in @var{expr}. The calculation is
performed with 64-bit (@code{BIGINT}) precision.
@c end_description_for_help_topic

This function returns @code{0} if there were no matching rows.

@c description_for_help_topic BIT_XOR
@item BIT_XOR(@var{expr})
@findex BIT_XOR()
Returns the bitwise @code{XOR} of all bits in @var{expr}. The calculation is
performed with 64-bit (@code{BIGINT}) precision.
@c end_description_for_help_topic

This function returns @code{0} if there were no matching rows.

This function is available as of MySQL 4.1.1.

@c description_for_help_topic COUNT
@item COUNT(@var{expr})
@findex COUNT()
Returns a count of the number of non-@code{NULL} values in the rows
retrieved by a @code{SELECT} statement.
@c end_description_for_help_topic

@c example_for_help_topic COUNT
@example
mysql> SELECT student.student_name,COUNT(*)
    ->        FROM student,course
    ->        WHERE student.student_id=course.student_id
    ->        GROUP BY student_name;

@end example

@code{COUNT(*)} is somewhat different in that it returns a count of
the number of rows retrieved, whether or not they contain @code{NULL}
values.

@code{COUNT(*)} is optimized to
return very quickly if the @code{SELECT} retrieves from one table, no
other columns are retrieved, and there is no @code{WHERE} clause.
For example:

@example
mysql> SELECT COUNT(*) FROM student;
@end example

This optimization applies only to @code{MyISAM} and @code{ISAM} tables
only, because an exact record count is stored for these table types and
can be accessed very quickly. For transactional storage engines
(@code{InnoDB}, @code{BDB}), storing an exact row count is more problematic
because multiple transactions may be occurring, each of which may affect the
count.

@c description_for_help_topic COUNT DISTINCT  COUNT DISTINCT
@item COUNT(DISTINCT @var{expr},[@var{expr}...])
@findex COUNT(DISTINCT)
@findex DISTINCT
Returns a count of the number of different non-@code{NULL} values.
@c end_description_for_help_topic

@c example_for_help_topic COUNT DISTINCT
@example
mysql> SELECT COUNT(DISTINCT results) FROM student;
@end example

In MySQL, you can get the number of distinct expression
combinations that don't contain @code{NULL} by giving a list of expressions.
In standard SQL, you would have to do a concatenation of all expressions
inside @code{COUNT(DISTINCT ...)}.

@code{COUNT(DISTINCT ...)} was added in MySQL 3.23.2.

@c description_for_help_topic GROUP_CONCAT  DISTINCT SEPARATOR ORDER BY ASC DESC
@item GROUP_CONCAT(@var{expr})
@findex GROUP_CONCAT()
This function returns a string result with the concatenated values from a
group.  The full syntax is as follows:

@example
GROUP_CONCAT([DISTINCT] @var{expr} [,@var{expr} ...]
             [ORDER BY @{@var{unsigned_integer} | @var{col_name} | @var{expr}@}
                 [ASC | DESC] [,@var{col_name} ...]]
             [SEPARATOR @var{str_val}])
@end example
@c end_description_for_help_topic

@c example_for_help_topic GROUP_CONCAT
@example
mysql> SELECT student_name,
    ->     GROUP_CONCAT(test_score)
    ->     FROM student 
    ->     GROUP BY student_name;
@end example

Or:

@example
mysql> SELECT student_name,
    ->     GROUP_CONCAT(DISTINCT test_score
    ->               ORDER BY test_score DESC SEPARATOR ' ')
    ->     FROM student
    ->     GROUP BY student_name;
@end example

In MySQL, you can get the concatenated values of expression combinations.
You can eliminate duplicate values by using @code{DISTINCT}.
If you want to sort values in the result, you should use @code{ORDER BY}
clause.
To sort in reverse order, add the @code{DESC} (descending) keyword to the
name of the column you are sorting by in the @code{ORDER BY} clause. The
default is ascending order; this may be specified explicitly using the
@code{ASC} keyword.
@code{SEPARATOR} is followed by the string value that should be inserted between
values of result. The default is a comma (@samp{,}). You can remove
the separator altogether by specifying @code{SEPARATOR ''}.

You can set a maximum allowed length with the
@code{group_concat_max_len} system variable.
The syntax to do this at runtime is as follows, where @code{val} is an
unsigned integer:

@example
SET [SESSION | GLOBAL] group_concat_max_len = val;
@end example

If a maximum length has been set, the result is truncated to this
maximum length. 

@c commented out until someone can say what GROUP_CONCAT() can do that
@c LIST() cannot...
@c The @code{GROUP_CONCAT()} function is an enhanced implementation of
@c the basic @code{LIST()} function supported by Sybase SQL Anywhere.
@c @code{GROUP_CONCAT()} is backward compatible with the extremely limited
@c functionality of @code{LIST()} if only one column and no other options
@c are specified. @code{LIST()} does have a default sorting order.

@code{GROUP_CONCAT()} was added in MySQL 4.1.

Note: Before MySQL 4.1.6, there are some small limitations with
@code{GROUP_CONCAT()} for @code{BLOB} and @code{TEXT} values when it comes
to using @code{DISTINCT} together with @code{ORDER BY}. To work around
this limitation, use @code{MID(@var{expr},1,255)} instead.

@c description_for_help_topic MIN MAX  MIN MAX
@item MIN(@var{expr})
@itemx MAX(@var{expr})
@findex MIN()
@findex MAX()
Returns the minimum or maximum value of @var{expr}.  @code{MIN()} and
@code{MAX()} may take a string argument; in such cases they return the
minimum or maximum string value. @xref{MySQL indexes}.
@c end_description_for_help_topic

@c example_for_help_topic MIN MAX
@example
mysql> SELECT student_name, MIN(test_score), MAX(test_score)
    ->        FROM student
    ->        GROUP BY student_name;
@end example

For @code{MIN()}, @code{MAX()}, and other aggregate functions, MySQL
currently compares @code{ENUM} and @code{SET} columns by their string
value rather than by the string's relative position in the set.
This differs from how @code{ORDER BY} compares them.
This will be rectified.

@c description_for_help_topic STDDEV  STD
@item STD(@var{expr})
@itemx STDDEV(@var{expr})
@findex STD()
@findex STDDEV()
@cindex Oracle compatibility
@cindex compatibility, with Oracle
Returns the standard deviation of @var{expr} (the square root of
@code{VARIANCE()}). This is an extension to standard SQL. The @code{STDDEV()}
form of this function is provided for Oracle compatibility.
@c end_description_for_help_topic

@c description_for_help_topic SUM
@item SUM(@var{expr})
@findex SUM()
Returns the sum of @var{expr}.  If the return set has no rows,
@code{SUM()} returns @code{NULL}.
@c end_description_for_help_topic

@c description_for_help_topic VARIANCE
@item VARIANCE(@var{expr})
@findex VARIANCE()
Returns the standard variance of @var{expr} (considering rows as the
whole population, not as a sample; so it has the number of rows as
denominator). This is an extension to 
standard SQL, available only in MySQL 4.1 or later.
@c end_description_for_help_topic

@end table

@node GROUP-BY-Modifiers, GROUP-BY-hidden-fields, GROUP-BY-Functions, Group by functions and modifiers
@subsection @code{GROUP BY} Modifiers

@findex OLAP
@findex ROLLUP

@c TODO: Comparison with UNION, WRT: complexity, table accesses,
@c optimization

@c Statements to create and populate the sales table used in the
@c ROLLUP examples

@c DROP TABLE IF EXISTS sales;
@c CREATE TABLE sales
@c (
@c     year    INT NOT NULL,
@c     country VARCHAR(20) NOT NULL,
@c     product VARCHAR(32) NOT NULL,
@c     profit  INT
@c );
@c INSERT INTO sales (product,country,year,profit) VALUES
@c INSERT INTO sales  VALUES
@c ('Computer', 'India', 2000, 1200),
@c ('TV', 'USA', 2001, 150),
@c ('Calculator', 'USA', 2001, 50),
@c ('Computer', 'USA', 2001, 1500),
@c ('Computer', 'USA', 2000, 1500),
@c ('Phone', 'Finland', 2000, 100),
@c ('Calculator', 'USA', 2000, 75),
@c ('Calculator', 'India', 2000, 75),
@c ('TV', 'USA', 2001, 100),
@c ('Computer', 'USA', 2001, 1200),
@c ('Computer', 'Finland', 2000, 1500),
@c ('Calculator', 'India', 2000, 75),
@c ('Phone', 'Finland', 2001, 10)
@c ;

As of MySQL 4.1.1, the @code{GROUP BY} clause allows a @code{WITH
ROLLUP} modifier that causes extra rows to be added to the summary
output. These rows represent higher-level (or super-aggregate) summary
operations. @code{ROLLUP} thus allows you to answer questions at multiple
levels of analysis with a single query. It can be used, for example,
to provide support for OLAP (Online Analytical Processing) operations.

As an illustration, suppose that a table named @code{sales} has @code{year},
@code{country},
@code{product}, and @code{profit} columns for recording sales profitability:

@example
CREATE TABLE sales
(
    year    INT NOT NULL,
    country VARCHAR(20) NOT NULL,
    product VARCHAR(32) NOT NULL,
    profit  INT
);
@end example

The table's contents can be summarized per year with a simple @code{GROUP BY}
like this:

@example
mysql> SELECT year, SUM(profit) FROM sales GROUP BY year;
+------+-------------+
| year | SUM(profit) |
+------+-------------+
| 2000 |        4525 |
| 2001 |        3010 |
+------+-------------+
@end example

This output shows the total profit for each year, but if you also want
to determine the total profit summed over all years, you must add up
the individual values yourself or run an additional query.

Or you can use @code{ROLLUP}, which provides both levels of analysis with a
single query.
Adding a @code{WITH ROLLUP} modifier to the @code{GROUP BY} clause causes the query
to produce another row that shows the grand total over all year values:

@example
mysql> SELECT year, SUM(profit) FROM sales GROUP BY year WITH ROLLUP;
+------+-------------+
| year | SUM(profit) |
+------+-------------+
| 2000 |        4525 |
| 2001 |        3010 |
| NULL |        7535 |
+------+-------------+
@end example

The grand total super-aggregate line is identified by the value @code{NULL} in
the @code{year} column.

@code{ROLLUP} has a more complex effect when there are multiple @code{GROUP BY}
columns. In this case, each time there is a ``break'' (change in value)
in any but the last grouping column, the query produces an extra
super-aggregate summary row.

For example, without @code{ROLLUP}, a summary on the @code{sales} table based
on @code{year},
@code{country}, and @code{product} might look like this:

@example
mysql> SELECT year, country, product, SUM(profit)
    -> FROM sales
    -> GROUP BY year, country, product;
+------+---------+------------+-------------+
| year | country | product    | SUM(profit) |
+------+---------+------------+-------------+
| 2000 | Finland | Computer   |        1500 |
| 2000 | Finland | Phone      |         100 |
| 2000 | India   | Calculator |         150 |
| 2000 | India   | Computer   |        1200 |
| 2000 | USA     | Calculator |          75 |
| 2000 | USA     | Computer   |        1500 |
| 2001 | Finland | Phone      |          10 |
| 2001 | USA     | Calculator |          50 |
| 2001 | USA     | Computer   |        2700 |
| 2001 | USA     | TV         |         250 |
+------+---------+------------+-------------+
@end example

The output indicates summary values only at the year/country/product level of
analysis.  When @code{ROLLUP} is added, the query produces several extra rows:

@example
mysql> SELECT year, country, product, SUM(profit)
    -> FROM sales
    -> GROUP BY year, country, product WITH ROLLUP;
+------+---------+------------+-------------+
| year | country | product    | SUM(profit) |
+------+---------+------------+-------------+
| 2000 | Finland | Computer   |        1500 |
| 2000 | Finland | Phone      |         100 |
| 2000 | Finland | NULL       |        1600 |
| 2000 | India   | Calculator |         150 |
| 2000 | India   | Computer   |        1200 |
| 2000 | India   | NULL       |        1350 |
| 2000 | USA     | Calculator |          75 |
| 2000 | USA     | Computer   |        1500 |
| 2000 | USA     | NULL       |        1575 |
| 2000 | NULL    | NULL       |        4525 |
| 2001 | Finland | Phone      |          10 |
| 2001 | Finland | NULL       |          10 |
| 2001 | USA     | Calculator |          50 |
| 2001 | USA     | Computer   |        2700 |
| 2001 | USA     | TV         |         250 |
| 2001 | USA     | NULL       |        3000 |
| 2001 | NULL    | NULL       |        3010 |
| NULL | NULL    | NULL       |        7535 |
+------+---------+------------+-------------+
@end example

For this query, adding @code{ROLLUP} causes the output to include summary
information at four levels of analysis, not just one.  Here's how to
interpret the @code{ROLLUP} output:

@itemize @bullet

@item
Following each set of product rows for a given year and country, an
extra summary row is produced showing the total for all products. These rows
have the @code{product} column set to @code{NULL}.

@item
Following each set of rows for a given year, an extra summary row is
produced showing the total for all countries and products. These rows
have the @code{country} and @code{products} columns set to @code{NULL}.

@item
Finally, following all other rows, an extra summary row is produced
showing the grand total for all years, countries, and products. This
row has the @code{year}, @code{country}, and @code{products} columns set to
@code{NULL}.

@end itemize

@strong{Other Considerations When using @code{ROLLUP}}

The following items list some behaviors specific to the MySQL implementation
of @code{ROLLUP}:

When you use @code{ROLLUP}, you cannot also use an @code{ORDER BY} clause to
sort the results. In other words, @code{ROLLUP} and @code{ORDER BY} are mutually
exclusive. However, you still have some control over sort order.
@code{GROUP BY}
in MySQL sorts results, and you can use explicit @code{ASC} and @code{DESC} keywords
with columns named in the @code{GROUP BY} list to specify sort order for
individual columns.  (The higher-level summary rows added by @code{ROLLUP}
still appear after the rows from which they are calculated, regardless
of the sort order.)

@code{LIMIT} can be used to restrict the number of rows returned to the
client. @code{LIMIT} is applied after @code{ROLLUP}, so the limit applies
against the extra rows added by @code{ROLLUP}. For example:

@example
mysql> SELECT year, country, product, SUM(profit)
    -> FROM sales
    -> GROUP BY year, country, product WITH ROLLUP
    -> LIMIT 5;
+------+---------+------------+-------------+
| year | country | product    | SUM(profit) |
+------+---------+------------+-------------+
| 2000 | Finland | Computer   |        1500 |
| 2000 | Finland | Phone      |         100 |
| 2000 | Finland | NULL       |        1600 |
| 2000 | India   | Calculator |         150 |
| 2000 | India   | Computer   |        1200 |
+------+---------+------------+-------------+
@end example

Using @code{LIMIT} with @code{ROLLUP} may produce results
that are more difficult to interpret, because you have less context
for understanding the super-aggregate rows.

The @code{NULL} indicators in each super-aggregate row are produced when the
row is sent to the client.  The server looks at the columns named in
the @code{GROUP BY} clause following the leftmost one that has changed value.
For any column in the result set with a name that is a lexical match to
any of those names, its value is set to @code{NULL}.  (If you specify grouping
columns by column number, the server identifies which columns to set to
@code{NULL} by number.)

Because the @code{NULL} values in the super-aggregate rows are placed into the
result set at such a late stage in query processing, you cannot test them
as @code{NULL} values within the query itself.  For example, you cannot add
@code{HAVING product IS NULL} to the query to eliminate from the output all
but the super-aggregate rows.

On the other hand, the @code{NULL} values do appear as @code{NULL}
on the client side and can be tested as such using any MySQL client
programming interface.

@node GROUP-BY-hidden-fields,  , GROUP-BY-Modifiers, Group by functions and modifiers
@subsection @code{GROUP BY} with Hidden Fields

@cindex @code{GROUP BY}, extensions to standard SQL
MySQL extends the use of @code{GROUP BY} so that you can use columns or
calculations in the @code{SELECT} list that don't appear in
the @code{GROUP BY} clause. This stands for @emph{any possible value for this
group}.  You can use this to get better performance by avoiding sorting and
grouping on unnecessary items.  For example, you don't need to group on
@code{customer.name} in the following query:
@c end_description_for_help_topic

@c example_for_help_topic BIT_AND
@example
mysql> SELECT order.custid, customer.name, MAX(payments)
    ->        FROM order,customer
    ->        WHERE order.custid = customer.custid
    ->        GROUP BY order.custid;
@end example

In standard SQL, you would have to add @code{customer.name} to the
@code{GROUP BY} clause.  In MySQL, the name is redundant if you don't run in
ANSI mode.

Do @emph{not} use this feature if the columns you omit from the
@code{GROUP BY} part are not unique in the group!  You will get
unpredictable results.

In some cases, you can use @code{MIN()} and @code{MAX()} to obtain a specific
column value even if it isn't unique. The following gives the value of
@code{column} from the row containing the smallest value in the @code{sort}
column:

@example
SUBSTR(MIN(CONCAT(RPAD(sort,6,' '),column)),7)
@end example

@xref{example-Maximum-column-group-row}.

@cindex @code{ORDER BY}, aliases in
@cindex aliases, in @code{ORDER BY} clauses
@cindex @code{GROUP BY}, aliases in
@cindex aliases, in @code{GROUP BY} clauses
@cindex expression aliases
@cindex aliases, for expressions
Note that if you are using MySQL 3.22 (or earlier) or if
you are trying to follow standard SQL, you can't use expressions in @code{GROUP
BY} or @code{ORDER BY} clauses.  You can work around this limitation by
using an alias for the expression:

@example
mysql> SELECT id,FLOOR(value/100) AS val FROM @var{tbl_name}
    ->     GROUP BY id, val ORDER BY val;
@end example

In MySQL 3.23 and up, aliases are unnecessary. You can use expressions 
in @code{GROUP BY} and @code{ORDER BY} clauses.  For example:

@example
mysql> SELECT id, FLOOR(value/100) FROM @var{tbl_name} ORDER BY RAND();
@end example


@node SQL Syntax, Storage engines, Functions, Top
@chapter SQL Statement Syntax

@c TODO: move DDL before DML; you have to create something before you
@c can manipulate it...

This chapter describes the syntax for the SQL statements supported in MySQL.

@menu
* Data Manipulation::           Data Manipulation Statements
* Data Definition::             Data Definition Statements
* Basic User Commands::         MySQL Utility Statements
* Transactional Commands::      MySQL Transactional and Locking Statements
* Database Administration::     Database Administration Statements
* Replication SQL::             Replication Statements
* SQLPS::                       SQL Syntax for Prepared Statements
@end menu
@node Data Manipulation, Data Definition, SQL Syntax, SQL Syntax
@section Data Manipulation Statements


@menu
* DELETE::                      @code{DELETE} Syntax
* DO::                          @code{DO} Syntax
* HANDLER::                     @code{HANDLER} Syntax
* INSERT::                      @code{INSERT} Syntax
* LOAD DATA::                   @code{LOAD DATA INFILE} Syntax
* REPLACE::                     @code{REPLACE} Syntax
* SELECT::                      @code{SELECT} Syntax
* Subqueries::                  Subquery Syntax
* TRUNCATE::                    @code{TRUNCATE} Syntax
* UPDATE::                      @code{UPDATE} Syntax
@end menu

@c help_category Data Manipulation


@node DELETE, DO, Data Manipulation, Data Manipulation
@subsection @code{DELETE} Syntax

@findex DELETE

@c example_for_help_topic DELETE
Single-table syntax:
@example
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM @var{tbl_name}
       [WHERE @var{where_definition}]
       [ORDER BY ...]
       [LIMIT @var{row_count}]
@end example

Multiple-table syntax:

@example
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
       @var{tbl_name}[.*] [, @var{tbl_name}[.*] ...]
       FROM @var{table_references}
       [WHERE @var{where_definition}]
@end example

Or:

@example
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
       FROM @var{tbl_name}[.*] [, @var{tbl_name}[.*] ...]
       USING @var{table_references}
       [WHERE @var{where_definition}]
@end example

@c description_for_help_topic DELETE  BY ORDER LIMIT WHERE FROM USING LOW_PRIORITY QUICK
@code{DELETE} deletes rows from @var{tbl_name} that satisfy the condition
given by @var{where_definition}, and returns the number of records deleted.

If you issue a @code{DELETE} statement with no @code{WHERE} clause, all
rows are deleted.  A faster way to do this, when you don't want to know
the number of deleted rows, is to use @code{TRUNCATE TABLE}.
@xref{TRUNCATE,  , @code{TRUNCATE}}.
@c end_description_for_help_topic

In MySQL 3.23, @code{DELETE} without a @code{WHERE} clause returns zero
as the number of affected records.

In MySQL 3.23, if you really want to know how many records are deleted
when you are deleting all rows, and are willing to suffer a speed
penalty, you can use a @code{DELETE} statement that includes a
@code{WHERE} clause with an expression that is true for every row. For
example:

@example
mysql> DELETE FROM @var{tbl_name} WHERE 1>0;
@end example

This is much slower than @code{TRUNCATE @var{tbl_name}}, because it deletes
rows one at a time.

If you delete the row containing the maximum value for an
@code{AUTO_INCREMENT} column, the value will be reused for an @code{ISAM}
or @code{BDB} table, but not for a @code{MyISAM} or @code{InnoDB} table.
If you delete all rows in the table with @code{DELETE FROM @var{tbl_name}}
(without a @code{WHERE}) in @code{AUTOCOMMIT} mode, the sequence starts
over for all table types except for @code{InnoDB} and (as of MySQL 4.0)
@code{MyISAM}. There are some exceptions to this behavior for @code{InnoDB}
tables, discussed in
@ref{InnoDB auto-increment column,  , @code{InnoDB} auto-increment column}.

For @code{MyISAM} and @code{BDB} tables, you can specify an
@code{AUTO_INCREMENT} secondary column in a multiple-column key.  In this
case, reuse of values deleted from the top of the sequence occurs even
for @code{MyISAM} tables.
@xref{example-AUTO_INCREMENT,  , example-@code{AUTO_INCREMENT}}.

The @code{DELETE} statement supports the following modifiers:

@itemize @bullet

@item
If you specify the @code{LOW_PRIORITY} keyword, execution of the
@code{DELETE} is delayed until no other clients are reading from the table.

@item
For @code{MyISAM} tables, if you specify the @code{QUICK} keyword, the
storage engine does not merge index leaves during delete, which may speed up
certain kind of deletes.

@item
The @code{IGNORE} keyword causes MySQL to ignore all errors during the
process of deleting rows. (Errors encountered during the parsing stage are
processed in the usual manner.) Errors that are ignored due to the use of
this option are returned as warnings. This option first appeared in MySQL
4.1.1.

@end itemize

The speed of delete operations may also be affected by factors discussed in
@ref{Delete speed}.

In @code{MyISAM} tables, deleted records are maintained in a linked list and
subsequent @code{INSERT} operations reuse old record positions. To
reclaim unused space and reduce file sizes, use the @code{OPTIMIZE
TABLE} statement or the @command{myisamchk} utility to reorganize tables.
@code{OPTIMIZE TABLE} is easier, but @command{myisamchk} is faster.  See
@ref{OPTIMIZE TABLE, , @code{OPTIMIZE TABLE}} and @ref{Optimization}.

The @code{QUICK} modifier affects whether index leaves are merged for
delete operations.  @code{DELETE QUICK} is most useful for applications
where index values for deleted rows will be replaced by similar index
values from rows inserted later.  In this case, the holes left by deleted
values will be reused.

@code{DELETE QUICK} is not useful when deleted values lead to underfilled
index blocks spanning a range of index values for which new inserts will
occur again.  In this case, use of @code{QUICK} can lead to wasted space in
the index that remains unreclaimed.  Here is an example of such a scenario:

@enumerate

@item
Create a table that contains an indexed @code{AUTO_INCREMENT} column.

@item
Insert many records into the table.  Each insert results in an index values
that is added to the high end of the index.

@item
Delete a block of records at the low end of the column range using
@code{DELETE QUICK}.

@end enumerate

In this scenario, the index blocks associated with the deleted index
values become underfilled but are not merged with other index blocks due
to the use of @code{QUICK}.  They will remain underfilled when new inserts
occur, because new records will not have index values in the deleted range.
Furthermore, they will remain underfilled even if you later use @code{DELETE}
without @code{QUICK}, unless some of the deleted index values happen
to lie in index blocks within or adjacent to the underfilled blocks.
To reclaim unused index space under these circumstances, you can use
@code{OPTIMIZE TABLE}.

If you are going to delete many rows from a table, it might be faster to use
@code{DELETE QUICK} followed by @code{OPTIMIZE TABLE}. This rebuilds the index
rather than performing many index block merge operations.

The MySQL-specific @code{LIMIT @var{row_count}} option to @code{DELETE} tells
the server the maximum number of rows to be deleted before control is
returned to the client.  This can be used to ensure that a specific
@code{DELETE} statement doesn't take too much time.  You can simply repeat
the @code{DELETE} statement until the number of affected rows is less than
the @code{LIMIT} value.

If the @code{DELETE} statement includes an @code{ORDER BY} clause, the rows
are deleted in the order specified by the clause. This is really useful only
in conjunction with @code{LIMIT}.  For example, the following statement
finds rows matching the @code{WHERE} clause, sorts them in @code{timestamp}
order, and deletes the first (oldest) one:

@example
DELETE FROM somelog
WHERE user = 'jcole'
ORDER BY timestamp
LIMIT 1
@end example

@code{ORDER BY} can be used with @code{DELETE} beginning with MySQL 4.0.0.

From MySQL 4.0, you can specify multiple tables in the @code{DELETE}
statement to delete rows from one or more tables depending on a particular
condition in multiple tables. However, you cannot use @code{ORDER BY}
or @code{LIMIT} in a multiple-table @code{DELETE}.

The first multiple-table @code{DELETE} syntax is supported starting from
MySQL 4.0.0.  The second is supported starting from MySQL 4.0.2. The
@code{table_references} part lists the tables involved in the join.
Its syntax is described in @ref{JOIN,  , @code{JOIN}}.

For the first syntax, only matching rows from the tables listed before the
@code{FROM} clause are deleted. For the second syntax, only matching rows
from the tables listed in the @code{FROM} clause (before the @code{USING}
clause) are deleted.  The effect is that you can delete rows from many
tables at the same time and also have additional tables that are used for
searching:

@example
DELETE t1, t2 FROM t1, t2, t3 WHERE t1.id=t2.id AND t2.id=t3.id;
@end example

Or:

@example
DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.id=t2.id AND t2.id=t3.id;
@end example

These statements use all three files when searching for rows to delete, but
delete matching rows only from tables @code{t1} and @code{t2}.

The examples show inner joins using the comma operator, but
multiple-table @code{DELETE} statements can use any type of
join allowed in @code{SELECT} statements, such as @code{LEFT JOIN}.

The syntax allows @code{.*} after the table names for compatibility with
@code{Access}.

If you use a multiple-table @code{DELETE} statement involving
@code{InnoDB} tables for which there are foreign key constraints,
the MySQL optimizer might process tables in an order that differs from
that of their parent/child relationship. In this case, the statement
fails and rolls back. Instead, delete from a single table and rely on the
@code{ON DELETE} capabilities that @code{InnoDB} provides to cause the
other tables to be modified accordingly.

@strong{Note}: In MySQL 4.0, you should refer to the table names to be
deleted with the true table name. In MySQL 4.1, you must use the alias
(if one was given) when referring to a table name:

In MySQL 4.0:

@example
DELETE test FROM test AS t1, test2 WHERE ...
@end example

In MySQL 4.1:

@example
DELETE t1 FROM test AS t1, test2 WHERE ...
@end example

The reason we didn't make this change in 4.0 is that we didn't
want to break any old 4.0 applications that were using the old syntax.

Currently, you cannot delete from a table and select from the same table in a
subquery.


@node DO, HANDLER, DELETE, Data Manipulation
@subsection @code{DO} Syntax

@findex DO

@c example_for_help_topic DO
@example
DO @var{expr} [, @var{expr}] ...
@end example

@c description_for_help_topic DO
@code{DO} executes the expressions but doesn't return any results.  This is
shorthand for @code{SELECT @var{expr}, ...}, but has the advantage that it's
slightly faster when you don't care about the result.

@code{DO} is useful mainly with functions that have side effects, such as
@code{RELEASE_LOCK()}.
@c end_description_for_help_topic

@code{DO} was added in MySQL 3.23.47.


@node HANDLER, INSERT, DO, Data Manipulation
@subsection @code{HANDLER} Syntax

@findex HANDLER

@c example_for_help_topic HANDLER
@example
HANDLER @var{tbl_name} OPEN [ AS @var{alias} ]
HANDLER @var{tbl_name} READ @var{index_name} @{ = | >= | <= | < @} (@var{value1},@var{value2},...)
    [ WHERE @var{where_condition} ] [LIMIT ... ]
HANDLER @var{tbl_name} READ @var{index_name} @{ FIRST | NEXT | PREV | LAST @}
    [ WHERE @var{where_condition} ] [LIMIT ... ]
HANDLER @var{tbl_name} READ @{ FIRST | NEXT @}
    [ WHERE @var{where_condition} ] [LIMIT ... ]
HANDLER @var{tbl_name} CLOSE
@end example

@c description_for_help_topic HANDLER  OPEN READ LIMIT FIRST NEXT PREV LAST WHERE CLOSE
The @code{HANDLER} statement provides direct access to table storage engine
interfaces.  It is available for @code{MyISAM} tables as MySQL 4.0.0 and
@code{InnoDB} tables as of MySQL 4.0.3.
@c end_description_for_help_topic

The @code{HANDLER ... OPEN} statement opens a table, making
it accessible via subsequent @code{HANDLER ... READ} statements.
This table object is not shared by other threads and is not closed
until the thread calls @code{HANDLER ... CLOSE} or the thread terminates.
If you open the table using an alias, further references to the table with
other @code{HANDLER} statements must use the alias rather than the table
name.

The first @code{HANDLER ... READ} syntax fetches a row where the index
specified satisfies the given values and the @code{WHERE} condition is met.
If you have a multiple-column index, specify the index column values as a
comma-separated list. Either specify values for all the columns in the
index, or specify values for a leftmost prefix of the index columns. Suppose
that an index includes three columns named @code{col_a}, @code{col_b}, and
@code{col_c}, in that order.  The @code{HANDLER} statement can specify
values for all three columns in the index, or for the columns in a leftmost
prefix. For example:

@example
HANDLER ... @var{index_name} = (col_a_val,col_b_val,col_c_val) ...
HANDLER ... @var{index_name} = (col_a_val,col_b_val) ...
HANDLER ... @var{index_name} = (col_a_val) ...
@end example

The second @code{HANDLER ... READ} syntax fetches a row from the table in
index order that that matches @code{WHERE} condition.

The third @code{HANDLER ... READ} syntax fetches a row from the table in
natural row order that matches the @code{WHERE} condition. It is faster than
@code{HANDLER @var{tbl_name} READ index_name} when a full table scan is desired.
Natural row order is the order in which rows are stored in a @code{MyISAM}
table data file. This statement works for @code{InnoDB} tables as well, but
there is no such concept because there is no separate data file.

Without a @code{LIMIT} clause, all forms of @code{HANDLER ... READ} fetch a
single row if one is available. To return a specific number of rows, include a
@code{LIMIT} clause. It has the same syntax as for the @code{SELECT}
statement.
@xref{SELECT,  , @code{SELECT}}.

@code{HANDLER ... CLOSE} closes a table that was opened with
@code{HANDLER ... OPEN}.

Note: To use the @code{HANDLER} interface to refer to a table's
@code{PRIMARY KEY}, use the quoted identifier @code{`PRIMARY`}:

@example
HANDLER @var{tbl_name} READ `PRIMARY` > (...);
@end example

@code{HANDLER} is a somewhat low-level statement.  For example, it does not
provide consistency.  That is, @code{HANDLER ... OPEN} does @emph{not}
take a snapshot of the table, and does @emph{not} lock the table. This
means that after a @code{HANDLER ... OPEN} statement is issued, table data
can be modified (by this or any other thread) and these modifications might
appear only partially in @code{HANDLER ... NEXT} or @code{HANDLER ... PREV}
scans.

There are several reasons to use the @code{HANDLER} interface instead of
normal @code{SELECT} statements:

@itemize @bullet

@item
@code{HANDLER} is faster than @code{SELECT}:

@itemize @bullet

@item
A designated storage engine handler object is allocated for the
@code{HANDLER ...  OPEN}. The object is reused for the following
@code{HANDLER} statements for the table; it need not be reinitialized for
each one.

@item
There is less parsing involved.

@item
There is no optimizer or query-checking overhead.

@item
The table doesn't have to be locked between two handler requests.

@item
The handler interface doesn't have to provide a consistent look of the
data (for example, dirty reads are allowed), so the storage engine can
use optimizations that @code{SELECT} doesn't normally allow.

@end itemize

@item

@code{HANDLER} makes it much easier to port applications that use an
@code{ISAM}-like interface to MySQL.

@item
@code{HANDLER} allows you to traverse a database in a manner that is not
easy (or perhaps even impossible) to do with @code{SELECT}. The @code{HANDLER}
interface is a more natural way to look at data when working with
applications that provide an interactive user interface to the database.

@end itemize


@node INSERT, LOAD DATA, HANDLER, Data Manipulation
@subsection @code{INSERT} Syntax

@findex INSERT

@c example_for_help_topic INSERT INTO
@example
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] @var{tbl_name} [(@var{col_name},...)]
    VALUES (@{@var{expr} | DEFAULT@},...),(...),...
    [ ON DUPLICATE KEY UPDATE @var{col_name}=@var{expr}, ... ]
@end example
Or:
@example
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] @var{tbl_name}
    SET @var{col_name}=@{@var{expr} | DEFAULT@}, ...
    [ ON DUPLICATE KEY UPDATE @var{col_name}=@var{expr}, ... ]
@end example
Or:
@example
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] @var{tbl_name} [(@var{col_name},...)]
    SELECT ...
@end example

@c description_for_help_topic INSERT INTO  INSERT INTO LOW_PRIORITY HIGH_PRIORITY IGNORE DUPLICATE KEY UPDATE DELAYED DEFAULT
@code{INSERT} inserts new rows into an existing table.  The @code{INSERT ...
VALUES} and @code{INSERT ... SET} forms of the statement insert rows based
on explicitly specified values.  The @code{INSERT ... SELECT} form inserts
rows selected from another table or tables.  The @code{INSERT ... VALUES}
form with multiple value lists is supported in MySQL 3.22.5 or
later.  The @code{INSERT ... SET} syntax is supported in MySQL
3.22.10 or later.
@code{INSERT ... SELECT} is discussed further in
@xref{INSERT SELECT,  , @code{INSERT SELECT}}.
@c end_description_for_help_topic

@var{tbl_name} is the table into which rows should be inserted. The columns
for which the statement provides values can be specified as follows:

@itemize @bullet

@item
The column name list or the @code{SET} clause indicates the columns
explicitly.

@item
If you do not specify the column list for @code{INSERT ... VALUES} or
@code{INSERT ... SELECT}, values for every column in the table must be
provided in the @code{VALUES()} list or by the @code{SELECT}.  If you don't
know the order of the columns in the table, use @code{DESCRIBE @var{tbl_name}} to
find out.

@end itemize

Column values can be given in several ways:

@itemize @bullet

@item
@cindex default values

If you are not running in strict mode, any column not explicitly
given a value is set to its default (explicit or implicit) value.
For example, if you specify a column list that doesn't name all the columns in
the table, unnamed columns are set to their default values.  Default value
assignment is described in @ref{CREATE TABLE, , @code{CREATE TABLE}}.
@xref{constraint invalid data}.

If you want @code{INSERT} statements to generate an error unless you
explicitly specify values for all columns that don't have a default
value, you should use STRICT mode. @xref{Server SQL mode}.

@item
You can use the keyword @code{DEFAULT} to explicitly set a column to its
default value. (New in MySQL 4.0.3.)  This makes it easier to write
@code{INSERT} statements that assign values to all but a few columns,
because it allows you to avoid writing an incomplete @code{VALUES} list
that does not include a value for each column in the table.
Otherwise, you would have to write out the list of column names
corresponding to each value in the @code{VALUES} list.

As of MySQL 4.1.0, you can use @code{DEFAULT(@var{col_name})} as a more
general form that can be used in expressions to produce a column's
default value.

@item
If both the column list and the @code{VALUES} list are empty, @code{INSERT}
creates a row with each column set to its default value:

@example
mysql> INSERT INTO @var{tbl_name} () VALUES();
@end example

@item
You can specify an expression @var{expr} to provide a column value.
This might involve type conversion if the type of the expression does not
match the type of the column, and conversion of a given value can result in
different inserted values depending on the column type. For example, inserting
the string @code{'1999.0e-2'} into an @code{INT}, @code{FLOAT},
@code{DECIMAL(10,6)}, or @code{YEAR} column results in the values @code{1999},
@code{19.9921}, @code{19.992100}, and @code{1999}. The reason the value
stored in the @code{INT} and @code{YEAR} columns is @code{1999} is that the
string-to-integer conversion looks only at as much of the initial part of
the string as may be considered a valid integer or year. For the
floating-point and fixed-point columns, the string-to-floating-point
conversion considers the entire string as a valid floating-point value.

An expression @var{expr} can refer to any column that was set earlier in a
value list.  For example, you can do this because the value for @code{col2}
refers to @code{col1}, which has already been assigned:

@example
mysql> INSERT INTO @var{tbl_name} (@var{col1},@var{col2}) VALUES(15,@var{col1}*2);
@end example

But you cannot do this because the value for @code{col1} refers to
@code{col2}, which is assigned after @code{col1}:

@example
mysql> INSERT INTO @var{tbl_name} (@var{col1},@var{col2}) VALUES(@var{col2}*2,15);
@end example

One exception involves columns that contain @code{AUTO_INCREMENT} values.
Because the AUTO_INCREMENT value is generated after other value assignments,
any reference to an AUTO_INCREMENT column in the assignment will return a 0.

@end itemize

The @code{INSERT} statement supports the following modifiers:

@itemize @bullet

@item
If you specify the @code{DELAYED} keyword, the server puts the row or
rows to be inserted into a buffer, and the client issuing the @code{INSERT
DELAYED} statement then can continue on.  If the table is busy, the server
holds the rows.  When the table becomes free, it begins inserting rows,
checking periodically to see whether there are new read requests for the
table. If there are, the delayed row queue is suspended until the table
becomes free again.
@xref{INSERT DELAYED,  , @code{INSERT DELAYED}}.
@code{DELAYED} was added in MySQL 3.22.5.

@item
If you specify the @code{LOW_PRIORITY} keyword, execution of the
@code{INSERT} is delayed until no other clients are reading from the
table. This includes other clients that began reading while existing
clients are reading, and while the @code{INSERT LOW_PRIORITY} statement
is waiting. It is possible, therefore, for a client that issues an
@code{INSERT LOW_PRIORITY} statement to wait for a very long time (or
even forever) in a read-heavy environment.
(This is in contrast to @code{INSERT DELAYED}, which lets the client
continue at once.)  @xref{INSERT DELAYED,  , @code{INSERT DELAYED}}.  Note
that @code{LOW_PRIORITY} should normally not be used with @code{MyISAM}
tables because doing so disables concurrent inserts.
@xref{MyISAM storage engine,  , @code{MyISAM} storage engine}.
@code{LOW_PRIORITY} was added in MySQL 3.22.5.

@item
If you specify the @code{HIGH_PRIORITY} keyword, it overrides the
effect of the @code{--low-priority-updates} option if the server was
started with that option. It also causes concurrent inserts not to be
used. @code{HIGH_PRIORITY} was added in MySQL 3.23.11.

@item
The rows-affected value for an @code{INSERT} can be obtained using the
@code{mysql_affected_rows()} C API function.
@xref{mysql_affected_rows,  , @code{mysql_affected_rows()}}.

@item
If you specify the @code{IGNORE} keyword in an @code{INSERT} statement,
errors that occur while executing the statement are treated as warnings
instead. For example, without @code{IGNORE}, a row that duplicates an
existing @code{UNIQUE} index or @code{PRIMARY KEY} value in the table causes
a duplicate-key error and the statement is aborted. With @code{IGNORE},
the error is ignored and the row is not inserted.  Data conversions that
would trigger errors abort the statement if @code{IGNORE}
is not specified.  With @code{IGNORE}, invalid values are adjusted to
the closest value values and inserted; warnings are produced but the
statement does not abort.  You can determine with the @code{mysql_info()}
C API function how many rows were inserted into the table.

@end itemize

@c TODO: make ON DUPLICATE stuff a separate subsection?

If you specify the @code{ON DUPLICATE KEY UPDATE} clause (new in MySQL
4.1.0), and a row is inserted that would cause a duplicate value in a
@code{UNIQUE} index or @code{PRIMARY KEY}, an @code{UPDATE} of the old row
is performed. For example, if column @code{a} is declared as @code{UNIQUE}
and already contains the value @code{1}, the following two statements have
identical effect:

@example
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3)
    -> ON DUPLICATE KEY UPDATE c=c+1;

mysql> UPDATE table SET c=c+1 WHERE a=1;
@end example

The rows-affected value is 1 if the row is inserted as a new record and
2 if an existing record is updated.

@strong{Note}: If column @code{b} is unique too, the @code{INSERT} would be
equivalent to this @code{UPDATE} statement instead:

@example
mysql> UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;
@end example

If @code{a=1 OR b=2} matches several rows, only @emph{one} row
is updated! In general, you should try to avoid using the
@code{ON DUPLICATE KEY} clause on tables with multiple @code{UNIQUE} keys.

As of MySQL 4.1.1, you can use the @code{VALUES(col_name)} function in the
@code{UPDATE} clause to refer to column values from the @code{INSERT} part
of the @code{INSERT ... UPDATE} statement. In other words,
@code{VALUES(col_name)} in the @code{UPDATE} clause refers to the value of
@var{col_name} that would be inserted if no duplicate-key conflict
occurred. This function is especially useful in multiple-row inserts. The
@code{VALUES()} function is meaningful only in @code{INSERT ... UPDATE}
statements and returns @code{NULL} otherwise.

Example:

@example
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
    -> ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
@end example

That statement is identical to the following two statements:

@example
mysql> INSERT INTO table (a,b,c) VALUES (1,2,3)
    -> ON DUPLICATE KEY UPDATE c=3;
mysql> INSERT INTO table (a,b,c) VALUES (4,5,6)
    -> ON DUPLICATE KEY UPDATE c=9;
@end example

When you use @code{ON DUPLICATE KEY UPDATE}, the @code{DELAYED} option is
ignored.

@findex LAST_INSERT_ID()
@findex mysql_insert_id()

You can find the value used for an @code{AUTO_INCREMENT} column by using the
@code{LAST_INSERT_ID()} function. From within the C API, use the
@code{mysql_insert_id()} function.  However, note that the two functions do
not behave quite identically under all circumstances.
The behavior of @code{INSERT} statements with respect to @code{AUTO_INCREMENT}
columns is discussed further in @ref{Information functions} and
@ref{mysql_insert_id, , @code{mysql_insert_id()}}.

If you use an @code{INSERT ... VALUES} statement with multiple value lists
or @code{INSERT ... SELECT}, the statement returns an information string in
this format:

@example
Records: 100 Duplicates: 0 Warnings: 0
@end example

@code{Records} indicates the number of rows processed by the statement.
(This is not necessarily the number of rows actually inserted.
@code{Duplicates} can be non-zero.)
@code{Duplicates} indicates the number of rows that couldn't be inserted
because they would duplicate some existing unique index value.
@code{Warnings} indicates the number of attempts to insert column values that
were problematic in some way. Warnings can occur under any of the following
conditions:

@itemize @bullet
@item
Inserting @code{NULL} into a column that has been declared @code{NOT NULL}.
For multiple-row @code{INSERT} statements or @code{INSERT ... SELECT}
statements,
the column is set to the default value appropriate for the column type.
This is @code{0} for numeric types, the empty string (@code{''}) for
string types, and the ``zero'' value for date and time types.

@item
Setting a numeric column to a value that lies outside the column's range.
The value is clipped to the closest endpoint of the range.

@item
Assigning a value such as @code{'10.34 a'} to a numeric column.  The
trailing non-numeric text is stripped off and the remaining numeric part is
inserted.  If the string value has no leading numeric part, the column is
set to @code{0}.

@item
Inserting a string into a string column (@code{CHAR}, @code{VARCHAR}, @code{TEXT}, or
@code{BLOB}) that exceeds the column's maximum length.  The value is
truncated to the column's maximum length.

@item
Inserting a value into a date or time column that is illegal for the column
type.  The column is set to the appropriate zero value for the type.
@end itemize

@findex mysql_info()

If you are using the C API, the information string can be obtained by invoking
the @code{mysql_info()} function.
@xref{mysql_info, , @code{mysql_info()}}.

@findex REPLACE ... SELECT
@findex INSERT ... SELECT

@menu
* INSERT SELECT::               @code{INSERT ... SELECT} Syntax
* INSERT DELAYED::              @code{INSERT DELAYED} Syntax
@end menu


@node INSERT SELECT, INSERT DELAYED, INSERT, INSERT
@subsubsection @code{INSERT ... SELECT} Syntax

@c description_for_help_topic INSERT SELECT
@example
INSERT [LOW_PRIORITY] [IGNORE] [INTO] @var{tbl_name} [(@var{column_list})]
    SELECT ...
@end example

With @code{INSERT ... SELECT}, you can quickly insert many rows
into a table from one or many tables.
@c end_description_for_help_topic

For example:

@c example_for_help_topic INSERT SELECT
@example
INSERT INTO tbl_temp2 (fld_id)
    SELECT tbl_temp1.fld_order_id
    FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;
@end example

The following conditions hold for an @code{INSERT ... SELECT} statement:

@itemize @bullet
@item
Prior to MySQL 4.0.1, @code{INSERT ... SELECT} implicitly operates in
@code{IGNORE} mode.  As of MySQL 4.0.1, specify @code{IGNORE}
explicitly to ignore records that would cause duplicate-key violations.

@item
Do not use @code{DELAYED} with @code{INSERT ... SELECT}.

@item
Prior to MySQL 4.0.14,
the target table of the @code{INSERT} statement cannot appear in the
@code{FROM} clause of the @code{SELECT} part of the query.
This limitation is lifted in 4.0.14.
@c (The problem is that the @code{SELECT} possibly would
@c find records that were inserted earlier during the same run.  When using
@c subquery clauses, the situation could easily be very confusing.)

@item
@code{AUTO_INCREMENT} columns work as usual.

@item
To ensure that the binary log can be used to re-create the
original tables, MySQL will not allow concurrent inserts during
@code{INSERT ... SELECT}.

@item
Currently, you cannot insert into a table and select from the same table in a
subquery.

@end itemize

You can use @code{REPLACE} instead of @code{INSERT} to overwrite old rows.
@code{REPLACE} is the counterpart to @code{INSERT IGNORE} in the treatment
of new rows that contain unique key values that duplicate old rows:
The new rows are used to replace the old rows rather than being discarded.


@node INSERT DELAYED,  , INSERT SELECT, INSERT
@subsubsection @code{INSERT DELAYED} Syntax

@findex INSERT DELAYED
@findex DELAYED

@cindex INSERT DELAYED

@c example_for_help_topic INSERT DELAYED
@example
INSERT DELAYED ...
@end example

@c description_for_help_topic INSERT DELAYED  INSERT DELAYED
The @code{DELAYED} option for the @code{INSERT} statement is a
MySQL extension to standard SQL that is very useful if you have clients
that can't wait for the @code{INSERT} to complete.  This is a common
problem when you use MySQL for logging and you also
periodically run @code{SELECT} and @code{UPDATE} statements that take a
long time to complete.  @code{DELAYED} was introduced in MySQL
3.22.15.

When a client uses @code{INSERT DELAYED}, it gets an okay from the server at
once, and the row is queued to be inserted when the table is not in use by
any other thread.

Another major benefit of using @code{INSERT DELAYED} is that inserts
from many clients are bundled together and written in one block. This is much
faster than doing many separate inserts.

There are some constraints on the use of @code{DELAYED}:

@itemize @bullet

@item
@code{INSERT DELAYED} works only with @code{MyISAM} and @code{ISAM}
tables.
For @code{MyISAM} tables, if there are no free blocks in the middle of the
data file, concurrent @code{SELECT} and @code{INSERT} statements are supported.
Under these circumstances, you very seldom need to use @code{INSERT
DELAYED} with @code{MyISAM}.
@xref{MyISAM  storage engine,  , @code{MyISAM} storage engine}.

@item
The @code{DELAYED} keyword is silently ignored for @code{InnoDB} tables as of
MySQL 4.0.14. (For older versions, it caused an error).

@item
@code{INSERT DELAYED} should be used only for @code{INSERT} statements that
specify value lists. This is enforced as of MySQL 4.0.18.  The server ignores
@code{DELAYED} for @code{INSERT DELAYED ... SELECT} statements.

@item
The server ignores
@code{DELAYED} for @code{INSERT DELAYED ... ON DUPLICATE UPDATE} statements.

@item
Because the statement returns immediately before the rows are inserted,
you cannot use @code{LAST_INSERT_ID()} to get the @code{AUTO_INCREMENT}
value the statement might generate.

@item
@code{DELAYED} rows are not visible to @code{SELECT} statements until they
actually have been inserted.

@end itemize
@c end_description_for_help_topic

Note that currently the queued rows are held only in memory until they are
inserted into the table.  This means that if you terminate @command{mysqld}
forcibly (for example, with @code{kill -9}) or if @command{mysqld} dies
unexpectedly, any queued rows that have not been written to disk are lost!

The following describes in detail what happens when you use the
@code{DELAYED} option to @code{INSERT} or @code{REPLACE}.  In this
description, the ``thread'' is the thread that received an @code{INSERT
DELAYED} statement and ``handler'' is the thread that handles all
@code{INSERT DELAYED} statements for a particular table.

@itemize @bullet
@item
When a thread executes a @code{DELAYED} statement for a table, a handler
thread is created to process all @code{DELAYED} statements for the table, if
no such handler already exists.

@item
The thread checks whether the handler has acquired a @code{DELAYED}
lock already; if not, it tells the handler thread to do so.  The
@code{DELAYED} lock can be obtained even if other threads have a @code{READ}
or @code{WRITE} lock on the table.  However, the handler will wait for all
@code{ALTER TABLE} locks or @code{FLUSH TABLES} to ensure that the table
structure is up to date.

@item
The thread executes the @code{INSERT} statement, but instead of writing
the row to the table, it puts a copy of the final row into a queue that
is managed by the handler thread. Any syntax errors are noticed by the
thread and reported to the client program.

@item
The client cannot obtain from the server the number of duplicate records or
the @code{AUTO_INCREMENT} value for the resulting row, because the
@code{INSERT} returns before the insert operation has been completed.  (If
you use the C API, the @code{mysql_info()} function doesn't return anything
meaningful, for the same reason.)

@item
The binary log is updated by the handler thread when the row is inserted into
the table.  In case of multiple-row inserts, the binary log is updated when
the first row is inserted.

@item
After every @code{delayed_insert_limit} rows are written, the handler checks
whether any @code{SELECT} statements are still pending.  If so, it
allows these to execute before continuing.

@cindex delayed_insert_limit
@cindex timeout
@item
When the handler has no more rows in its queue, the table is unlocked.  If no
new @code{INSERT DELAYED} statements are received within
@code{delayed_insert_timeout} seconds, the handler terminates.

@item
If more than @code{delayed_queue_size} rows are pending already in a
specific handler queue, the thread requesting @code{INSERT DELAYED}
waits until there is room in the queue.  This is done to ensure that
the @command{mysqld} server doesn't use all memory for the delayed memory
queue.

@item
The handler thread shows up in the MySQL process list with
@code{delayed_insert} in the @code{Command} column.  It will be killed if
you execute a @code{FLUSH TABLES} statement or kill it with @code{KILL
thread_id}. However, before exiting, it will first store all queued rows into
the table. During this time it will not accept any new @code{INSERT}
statements from another thread. If you execute an @code{INSERT DELAYED}
statement after this, a new handler thread will be created.

Note that this means that @code{INSERT DELAYED} statements have higher
priority than normal @code{INSERT} statements if there is an @code{INSERT
DELAYED} handler already running!  Other update statements will have to wait
until the @code{INSERT DELAYED} queue is empty, someone terminates the handler
thread (with @code{KILL thread_id}), or someone executes @code{FLUSH TABLES}.

@item
The following status variables provide information about @code{INSERT
DELAYED} statements:

@multitable @columnfractions .45 .55
@item @strong{Status Variable} @tab @strong{Meaning}
@item @code{Delayed_insert_threads} @tab Number of handler threads
@item @code{Delayed_writes} @tab Number of rows written with @code{INSERT DELAYED}
@item @code{Not_flushed_delayed_rows} @tab Number of rows waiting to be written
@end multitable

You can view these variables by issuing a @code{SHOW STATUS} statement or
by executing a @command{mysqladmin extended-status} command.
@end itemize

Note that @code{INSERT DELAYED} is slower than a normal @code{INSERT} if the
table is not in use.  There is also the additional overhead for the server
to handle a separate thread for each table for which there are delayed rows.
This means that you should use @code{INSERT DELAYED} only when you are
really sure that you need it!


@node LOAD DATA, REPLACE, INSERT, Data Manipulation
@subsection @code{LOAD DATA INFILE} Syntax

@findex LOAD DATA INFILE

@c example_for_help_topic LOAD DATA
@example
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE '@var{file_name}.txt'
    [REPLACE | IGNORE]
    INTO TABLE @var{tbl_name}
    [FIELDS
        [TERMINATED BY '\t']
        [[OPTIONALLY] ENCLOSED BY '']
        [ESCAPED BY '\\' ]
    ]
    [LINES 
        [STARTING BY '']    
        [TERMINATED BY '\n']
    ]
    [IGNORE @var{number} LINES]
    [(@var{col_name},...)]
@end example

@c description_for_help_topic LOAD DATA  BY LOAD DATA LOW_PRIORITY CONCURRENT LOCAL INFILE REPLACE IGNORE FIELDS ENCLOSED TERMINATED ESCAPED LINES IMPORT CSV OPTIONALLY STARTING
The @code{LOAD DATA INFILE} statement reads rows from a text file into a
table at a very high speed.
For more information about the efficiency of @code{INSERT} versus
@code{LOAD DATA INFILE} and speeding up @code{LOAD DATA INFILE},
@ref{Insert speed}.

@cindex @command{mysqlimport}
You can also load data files by using the @command{mysqlimport} utility; it
operates by sending a @code{LOAD DATA INFILE} statement to the server.  The
@code{--local} option causes @command{mysqlimport} to read data files from the
client host.  You can specify the @code{--compress} option to get better
performance over slow networks if the client and server support the
compressed protocol.
@xref{mysqlimport,  , @command{mysqlimport}}.

If you specify the @code{LOW_PRIORITY} keyword, execution of the
@code{LOAD DATA} statement is delayed until no other clients are reading
from the table.

If you specify the @code{CONCURRENT} keyword with a @code{MyISAM} table that
satisfies the condition for concurrent inserts (that is, it contains no free
blocks in the middle),
then other threads can retrieve data from the table while @code{LOAD DATA}
is executing. Using this option affects the performance of @code{LOAD DATA}
a bit, even if no other thread is using the table at the same time.

If the @code{LOCAL} keyword is specified, it is
interpreted with respect to the client end of the connection:

@itemize @bullet

@item
If @code{LOCAL} is specified, the file is read by the client program on the
client host and sent to the server.

@item
If @code{LOCAL} is not specified, the
file must be located on the server host and is read directly by the server.

@end itemize

@code{LOCAL} is available in MySQL 3.22.6 or later.

For security reasons, when reading text files located on the server, the
files must either reside in the database directory or be readable by all.
Also, to use @code{LOAD DATA INFILE} on server files, you must have the
@code{FILE} privilege.
@c end_description_for_help_topic
@xref{Privileges provided}.

Using @code{LOCAL} is a bit slower than letting the server access the files
directly, because the contents of the file must be sent over the connection
by the client to the server.  On the other hand, you do not need the
@code{FILE} privilege to load local files.

As of MySQL 3.23.49 and MySQL 4.0.2 (4.0.13 on Windows), 
@code{LOCAL} works only if your server
and your client both have been enabled to allow it.  For example, if
@command{mysqld} was started with @code{--local-infile=0}, @code{LOCAL} will
not work.
@xref{LOAD DATA LOCAL,  , @code{LOAD DATA LOCAL}}.

If you need @code{LOAD DATA} to read from a pipe, you can use the
following technique (here we load the listing of the '/' directory into a
table):

@example
mkfifo /mysql/db/x/x
chmod 666 /mysql/db/x/x
find / -ls > /mysql/db/x/x
mysql -e "LOAD DATA INFILE 'x' INTO TABLE x" x
@end example

If you are using a version of MySQL older than 3.23.25,
you can use this technique only with @code{LOAD DATA LOCAL INFILE}.

@c old version
If you are using MySQL before Version 3.23.24, you can't read from a
FIFO with @code{LOAD DATA INFILE}.  If you need to read from a FIFO (for
example, the output from @code{gunzip}), use @code{LOAD DATA LOCAL INFILE}
instead.

When locating files on the server host, the server uses the following rules:

@itemize @bullet
@item
If an absolute pathname is given, the server uses the pathname as is.

@item
If a relative pathname with one or more leading components is given,
the server searches for the file relative to the server's data directory.

@item
If a filename with no leading components is given, the server looks for
the file in the database directory of the default database.
@end itemize

Note that these rules mean that a file named as @file{./myfile.txt} is read from
the server's data directory, whereas the same file named as @file{myfile.txt} is
read from the database directory of the default database.  For example,
the following @code{LOAD DATA} statement reads the file @file{data.txt}
from the database directory for @code{db1} because @code{db1} is the current
database, even though the statement explicitly loads the file into a
table in the @code{db2} database:

@example
mysql> USE db1;
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;
@end example

The @code{REPLACE} and @code{IGNORE} keywords control handling of input
records that duplicate existing records on unique key values.

If you specify @code{REPLACE}, input rows replace existing rows (in other
words, rows that have the same value for a primary or unique index as an
existing row). @xref{REPLACE,  , @code{REPLACE}}.

If you specify @code{IGNORE}, input rows that duplicate an existing row
on a unique key value are skipped.  If you don't specify either option,
the behavior depends on whether or not the @code{LOCAL} keyword is specified.
Without @code{LOCAL}, an error occurs when a duplicate key value is
found, and the rest of the text file is ignored.  With @code{LOCAL},
the default behavior is the same as if @code{IGNORE} is specified;
this is because the server has no way to stop transmission of the file
in the middle of the operation.

If you want to ignore foreign key constraints during the load operation, you
can issue a @code{SET FOREIGN_KEY_CHECKS=0} statement before executing
@code{LOAD DATA}.

If you use @code{LOAD DATA INFILE} on an empty @code{MyISAM} table, all
non-unique indexes are created in a separate batch (as for
@code{REPAIR TABLE}).  This normally makes @code{LOAD DATA INFILE} much faster
when you have many indexes.  Normally this is very fast, but in some
extreme cases, you can create the indexes even faster by turning them off
with @code{ALTER TABLE .. DISABLE KEYS} before loading the file into the
table and using @code{ALTER TABLE .. ENABLE KEYS} to re-create the indexes
after loading the file.
@xref{Insert speed}.

@code{LOAD DATA INFILE} is the complement of @code{SELECT ... INTO OUTFILE}.
@xref{SELECT, , @code{SELECT}}.
To write data from a table to a file, use @code{SELECT ... INTO OUTFILE}.
To read the file back into a table, use @code{LOAD DATA INFILE}.
The syntax of the @code{FIELDS} and @code{LINES} clauses is the same for
both statements.  Both clauses are optional, but @code{FIELDS}
must precede @code{LINES} if both are specified.

If you specify a @code{FIELDS} clause,
each of its subclauses (@code{TERMINATED BY}, @code{[OPTIONALLY] ENCLOSED
BY}, and @code{ESCAPED BY}) is also optional, except that you must
specify at least one of them.

If you don't specify a @code{FIELDS} clause, the defaults are the
same as if you had written this:

@example
FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
@end example

If you don't specify a @code{LINES} clause, the default
is the same as if you had written this:

@example
LINES TERMINATED BY '\n' STARTING BY ''
@end example

In other words, the defaults cause @code{LOAD DATA INFILE} to act as follows
when reading input:

@itemize @bullet
@item
Look for line boundaries at newlines.

@item
Do not skip over any line prefix.

@item
Break lines into fields at tabs.

@item
Do not expect fields to be enclosed within any quoting characters.

@item
Interpret occurrences of tab, newline, or @samp{\} preceded by
@samp{\} as literal characters that are part of field values.
@end itemize

Conversely, the defaults cause @code{SELECT ... INTO OUTFILE} to act as
follows when writing output:

@itemize @bullet
@item
Write tabs between fields.

@item
Do not enclose fields within any quoting characters.

@item
Use @samp{\} to escape instances of tab, newline, or @samp{\} that occur
within field values.

@item
Write newlines at the ends of lines.
@end itemize

Note that to write @code{FIELDS ESCAPED BY '\\'}, you must specify two
backslashes for the value to be read as a single backslash.

@strong{Note}: If you have generated the text file on a Windows system, you
might have to use @code{LINES TERMINATED BY '\r\n'} to read the file
properly, because Windows programs typically use two characters as a line
terminator. Some programs, such as @code{WordPad}, might use @code{\r} as a line
terminator when writing files.  To read such files, use @code{LINES
TERMINATED BY '\r'}.

If all the lines you want to read in have a common prefix that you want
to ignore, you can use @code{LINES STARTING BY 'prefix_string'} to skip
over the prefix (and anything before it). If a line doesn't include the
prefix, the entire line is skipped. @strong{Note} that
@code{prefix_string} may be in the middle of the line!

Example:
@example
mysql> LOAD DATA INFILE '/tmp/test.txt'
    -> INTO TABLE test LINES STARTING BY "xxx";
@end example

With this you can read in a file that contains something like:

@example
xxx"Row",1
something xxx"Row",2
@end example

And just get the data @code{("row",1)} and @code{("row",2)}.

The @code{IGNORE number LINES} option can be used to ignore lines at
the start of the file.  For example, you can use @code{IGNORE 1 LINES}
to skip over an initial header line containing column names:

@example
mysql> LOAD DATA INFILE '/tmp/test.txt'
    -> INTO TABLE test IGNORE 1 LINES;
@end example

When you use @code{SELECT ... INTO OUTFILE} in tandem with @code{LOAD
DATA INFILE} to write data from a database into a file and then read
the file back into the database later, the field- and line-handling
options for both statements must match.  Otherwise, @code{LOAD DATA
INFILE} will not interpret the contents of the file properly.  Suppose
that you use @code{SELECT ... INTO OUTFILE} to write a file with
fields delimited by commas:

@example
mysql> SELECT * INTO OUTFILE 'data.txt'
    ->          FIELDS TERMINATED BY ','
    ->          FROM table2;
@end example

To read the comma-delimited file back in, the correct statement would be:

@example
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2
    ->           FIELDS TERMINATED BY ',';
@end example

If instead you tried to read in the file with the statement shown here, it
wouldn't work because it instructs @code{LOAD DATA INFILE} to look for
tabs between fields:

@example
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE table2
    ->           FIELDS TERMINATED BY '\t';
@end example

The likely result is that each input line would be interpreted as
a single field.

@code{LOAD DATA INFILE} can be used to read files obtained from
external sources, too. For example, a file in dBASE format will have
fields separated by commas and enclosed within double quotes.  If lines in
the file are terminated by newlines, the statement shown here
illustrates the field- and line-handling options you would use to load
the file:

@example
mysql> LOAD DATA INFILE 'data.txt' INTO TABLE @var{tbl_name}
    ->           FIELDS TERMINATED BY ',' ENCLOSED BY '"'
    ->           LINES TERMINATED BY '\n';
@end example

Any of the field- or line-handling options can specify an empty string
(@code{''}).  If not empty, the @code{FIELDS [OPTIONALLY] ENCLOSED BY}
and @code{FIELDS ESCAPED BY} values must be a single character.  The
@code{FIELDS TERMINATED BY}, @code{LINES STARTING BY}, and @code{LINES
TERMINATED BY} values can be more than one character.  For example, to write
lines that are terminated by carriage return/linefeed pairs, or to read a
file containing such lines, specify a @code{LINES TERMINATED BY '\r\n'}
clause.

To read a file containing jokes that are separated by lines consisting of
of @code{%%}, you can do this

@example
mysql> CREATE TABLE jokes
    ->     (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->     joke TEXT NOT NULL);
mysql> LOAD DATA INFILE '/tmp/jokes.txt' INTO TABLE jokes
    ->     FIELDS TERMINATED BY ''
    ->     LINES TERMINATED BY '\n%%\n' (joke);
@end example

@code{FIELDS [OPTIONALLY] ENCLOSED BY} controls quoting of fields.  For
output (@code{SELECT ... INTO OUTFILE}), if you omit the word
@code{OPTIONALLY}, all fields are enclosed by the @code{ENCLOSED BY}
character.  An example of such output (using a comma as the field
delimiter) is shown here:

@example
"1","a string","100.20"
"2","a string containing a , comma","102.20"
"3","a string containing a \" quote","102.20"
"4","a string containing a \", quote and comma","102.20"
@end example

If you specify @code{OPTIONALLY}, the @code{ENCLOSED BY} character is
used only to enclose @code{CHAR} and @code{VARCHAR} fields:

@example
1,"a string",100.20
2,"a string containing a , comma",102.20
3,"a string containing a \" quote",102.20
4,"a string containing a \", quote and comma",102.20
@end example

Note that occurrences of the @code{ENCLOSED BY} character within a
field value are escaped by prefixing them with the @code{ESCAPED BY}
character.  Also note that if you specify an empty @code{ESCAPED BY}
value, it is possible to generate output that cannot be read properly by
@code{LOAD DATA INFILE}. For example, the preceding output just shown would
appear as follows if the escape character is empty.  Observe that the
second field in the fourth line contains a comma following the quote, which
(erroneously) appears to terminate the field:

@example
1,"a string",100.20
2,"a string containing a , comma",102.20
3,"a string containing a " quote",102.20
4,"a string containing a ", quote and comma",102.20
@end example

For input, the @code{ENCLOSED BY} character, if present, is stripped
from the ends of field values.  (This is true whether or not @code{OPTIONALLY}
is specified; @code{OPTIONALLY} has no effect on input interpretation.)
Occurrences of the @code{ENCLOSED BY} character preceded by the
@code{ESCAPED BY} character are interpreted as part of the current
field value.

If the field begins with the @code{ENCLOSED BY} character, instances
of that character are recognized as terminating a field value only
if followed by the field or line @code{TERMINATED BY} sequence.
To avoid ambiguity, occurrences of the @code{ENCLOSED BY} character
within a field value can be doubled and will be interpreted as a
single instance of the character.  For example, if @code{ENCLOSED
BY '"'} is specified, quotes are handled as shown here:

@example
"The ""BIG"" boss"  -> The "BIG" boss
The "BIG" boss      -> The "BIG" boss
The ""BIG"" boss    -> The ""BIG"" boss
@end example

@code{FIELDS ESCAPED BY} controls how to write or read special characters.
If the @code{FIELDS ESCAPED BY} character is not empty, it is used to prefix
the following characters on output:
@itemize @bullet
@item
The @code{FIELDS ESCAPED BY} character
@item
The @code{FIELDS [OPTIONALLY] ENCLOSED BY} character
@item
The first character of the @code{FIELDS TERMINATED BY} and
@code{LINES TERMINATED BY} values
@item
ASCII @code{0} (what is actually written following the escape character is
ASCII @samp{0}, not a zero-valued byte)
@end itemize

If the @code{FIELDS ESCAPED BY} character is empty, no characters are
escaped and @code{NULL} is output as @code{NULL}, not @code{\N}.  It is
probably not a good idea to specify an empty escape character,
particularly if field values in your data contain any of the characters
in the list just given.

For input, if the @code{FIELDS ESCAPED BY} character is not empty, occurrences
of that character are stripped and the following character is taken literally
as part of a field value.  The exceptions are an escaped @samp{0} or
@samp{N} (for example, @code{\0} or @code{\N} if the escape character is
@samp{\}).  These sequences are interpreted as ASCII NUL (a zero-valued
byte) and @code{NULL}.  The rules for @code{NULL} handling are described later
in this section.

For more information about @samp{\}-escape syntax,
see @ref{Literals}.

In certain cases, field- and line-handling options interact:

@itemize @bullet
@item
If @code{LINES TERMINATED BY} is an empty string and @code{FIELDS
TERMINATED BY} is non-empty, lines are also terminated with
@code{FIELDS TERMINATED BY}.
@item
If the @code{FIELDS TERMINATED BY} and @code{FIELDS ENCLOSED BY} values
are both empty (@code{''}), a fixed-row (non-delimited) format is used.
With fixed-row format, no delimiters are used between fields (but you
can still have a line terminator). Instead, column values are written
and read using the ``display'' widths of the columns.  For example, if a
column is declared as @code{INT(7)}, values for the column are written
using seven-character fields.  On input, values for the column are obtained
by reading seven characters.

@code{LINES TERMINATED BY} is still used to separate lines.  If a line
doesn't contain all fields, the rest of the columns are set to their
default values. If you don't have a line terminator, you should set this
to @code{''}.  In this case, the text file must contain all fields for
each row.

Fixed-row format also affects handling of @code{NULL} values, as described
later.
Note that fixed-size format will not work if you are using a multi-byte
character set.
@end itemize

Handling of @code{NULL} values varies according to the @code{FIELDS} and
@code{LINES} options in use:

@itemize @bullet
@item
For the default @code{FIELDS} and @code{LINES} values, @code{NULL} is
written as a field value of @code{\N} for output, and a field value of
@code{\N} is read as @code{NULL} for input (assuming that the @code{ESCAPED BY}
character is @samp{\}).

@item
If @code{FIELDS ENCLOSED BY} is not empty, a field containing the literal
word @code{NULL} as its value is read as a @code{NULL} value. This differs
from the word @code{NULL} enclosed within @code{FIELDS ENCLOSED BY}
characters, which is read as the string @code{'NULL'}.

@item
If @code{FIELDS ESCAPED BY} is empty, @code{NULL} is written as the word
@code{NULL}.

@item
With fixed-row format (which happens when @code{FIELDS TERMINATED BY} and
@code{FIELDS ENCLOSED BY} are both empty), @code{NULL} is written as an empty
string.  Note that this causes both @code{NULL} values and empty strings in
the table to be indistinguishable when written to the file because they are
both written as empty strings.  If you need to be able to tell the two apart
when reading the file back in, you should not use fixed-row format.
@end itemize

Some cases are not supported by @code{LOAD DATA INFILE}:
@itemize @bullet

@item
Fixed-size rows (@code{FIELDS TERMINATED BY} and @code{FIELDS ENCLOSED
BY} both empty) and @code{BLOB} or @code{TEXT} columns.

@item
If you specify one separator that is the same as or a prefix of another,
@code{LOAD DATA INFILE} won't be able to interpret the input properly.
For example, the following @code{FIELDS} clause would cause problems:

@example
FIELDS TERMINATED BY '"' ENCLOSED BY '"'
@end example

@item
If @code{FIELDS ESCAPED BY} is empty, a field value that contains an occurrence
of @code{FIELDS ENCLOSED BY} or @code{LINES TERMINATED BY}
followed by the @code{FIELDS TERMINATED BY} value will cause @code{LOAD
DATA INFILE} to stop reading a field or line too early.
This happens because @code{LOAD DATA INFILE} cannot properly determine
where the field or line value ends.
@end itemize

The following example loads all columns of the @code{persondata} table:

@example
mysql> LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;
@end example

By default, when no column list is provided at the end of the @code{LOAD
DATA INFILE} statement, input lines are expected to contain a field for each
table column.  If you want to load only some of a table's columns, specify a
column list:

@example
mysql> LOAD DATA INFILE 'persondata.txt'
    ->           INTO TABLE persondata (col1,col2,...);
@end example

You must also specify a column list if the order of the fields in the input
file differs from the order of the columns in the table.  Otherwise,
MySQL cannot tell how to match up input fields with table columns.

If an input line has too many fields, the extra fields are ignored and
the number of warnings is incremented.

If an input line has too few fields, the table columns for which input
fields are missing are set to their default values.  Default value assignment
is described in @ref{CREATE TABLE, , @code{CREATE TABLE}}.

An empty field value is interpreted differently than if the field value
is missing:

@itemize @bullet
@item
For string types, the column is set to the empty string.

@item
For numeric types, the column is set to @code{0}.

@item
For date and time types, the column is set to the appropriate ``zero''
value for the type.
@xref{Date and time types}.
@end itemize

These are the same values that result if you assign an empty
string explicitly to a string, numeric, or date or time type explicitly
in an @code{INSERT} or @code{UPDATE} statement.

@c TODO: with the new DEFAULT ... ON UPDATE syntax for declaring TIMESTAMP
@c columns, this should be amended to reflect that it's not necessarily
@c the *first* TIMESTAMP that is set to current date and time, it's the
@c one with DEFAULT NOW.

@code{TIMESTAMP} columns are set to the current date and time only if there
is a @code{NULL} value for the column (that is, @code{\N}), or (for the
first @code{TIMESTAMP} column only) if the @code{TIMESTAMP} column is
omitted from the field list when a field list is specified.

@code{LOAD DATA INFILE} regards all input as strings, so you can't use
numeric values for @code{ENUM} or @code{SET} columns the way you can with
@code{INSERT} statements.  All @code{ENUM} and @code{SET} values must be
specified as strings!

When the @code{LOAD DATA INFILE}
statement finishes, it returns an information string in the following format:

@example
Records: 1  Deleted: 0  Skipped: 0  Warnings: 0
@end example

@findex mysql_info()
If you are using the C API, you can get information about the statement by
calling the  @code{mysql_info()} function.
@xref{mysql_info, , @code{mysql_info()}}.

Warnings occur under the same circumstances as when values are inserted
via the @code{INSERT} statement (@pxref{INSERT, , @code{INSERT}}), except
that @code{LOAD DATA INFILE} also generates warnings when there are too few
or too many fields in the input row.  The warnings are not stored anywhere;
the number of warnings can be used only as an indication of whether everything went
well.

From MySQL 4.1.1 on, you can use @code{SHOW WARNINGS} to get a list of the
first @code{max_error_count} warnings as information about what went wrong.
@xref{SHOW WARNINGS,  , @code{SHOW WARNINGS}}.

Before MySQL 4.1.1, only a warning count is available to indicate that
something went wrong.  If you get warnings and want to know exactly why you
got them, one way to do this is to dump the table into another file using
@code{SELECT ... INTO OUTFILE} and compare the file to your original input
file.


@node REPLACE, SELECT, LOAD DATA, Data Manipulation
@subsection @code{REPLACE} Syntax

@findex REPLACE

@c example_for_help_topic REPLACE INTO
@example
REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] @var{tbl_name} [(@var{col_name},...)]
    VALUES (@{@var{expr} | DEFAULT@},...),(...),...
@end example
Or:
@example
REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] @var{tbl_name}
    SET @var{col_name}=@{@var{expr} | DEFAULT@}, ...
@end example
Or:
@example
REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] @var{tbl_name} [(@var{col_name},...)]
    SELECT ...
@end example

@c description_for_help_topic REPLACE INTO  DELAYED LOW_PRIORITY INTO VALUES SELECT SET
@code{REPLACE} works exactly like @code{INSERT}, except that if an old
record in the table has the same value as a new record for a @code{PRIMARY
KEY} or a @code{UNIQUE} index, the old record is deleted before the new
record is inserted.
@xref{INSERT, ,@code{INSERT}}.

Note that unless the table has a @code{PRIMARY KEY} or @code{UNIQUE} index,
using a @code{REPLACE} statement makes no sense. It becomes equivalent to
@code{INSERT}, because there is no index to be used to determine whether a new
row duplicates another.

Values for all columns are taken from the values specified in the
@code{REPLACE} statement.  Any missing columns are set to their default
values, just as happens for @code{INSERT}.  You can't refer to values from
the old row and use them in the new row.  It appeared that you could do this
in some old MySQL versions, but that was a bug that has been corrected.

To be able to use @code{REPLACE}, you must have @code{INSERT} and
@code{DELETE} privileges for the table.
@c end_description_for_help_topic

The @code{REPLACE} statement returns a count to indicate the number of rows
affected. This is the sum of the rows deleted and inserted. If the count is 1
for a single-row @code{REPLACE}, a row was inserted and no rows were deleted.
If the count is greater than 1, one or more old rows were deleted before the
new row was inserted. It is possible for a single row to replace more than one
old row if the table contains multiple unique indexes and the new row
duplicates values for different old rows in different unique indexes.

The affected-rows count makes it easy to determine whether @code{REPLACE}
only added a row or whether it also replaced any rows: Check whether the
count is 1 (added) or greater (replaced).

If you are using the C API, the affected-rows count can be obtained using the
@code{mysql_affected_rows()} function.

Currently, you cannot replace into a table and select from the same table in a
subquery.

Here follows in more detail the algorithm that is used
(it is also used with @code{LOAD DATA ... REPLACE}):

@enumerate
@item
Try to insert the new row into the table
@item
While the insertion fails because a duplicate-key error occurs for a
primary or unique key:
@enumerate
@item
Delete from the table the conflicting row that has the duplicate key value
@item
Try again to insert the new row into the table
@end enumerate
@end enumerate


@node SELECT, Subqueries, REPLACE, Data Manipulation
@subsection @code{SELECT} Syntax

@findex SELECT, LIMIT

@c help SELECT
@c example_for_help_topic SELECT
@example
SELECT
    [ALL | DISTINCT | DISTINCTROW ]
      [HIGH_PRIORITY]
      [STRAIGHT_JOIN]
      [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
      [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
    @var{select_expr}, ...
    [INTO OUTFILE '@var{file_name}' @var{export_options}
      | INTO DUMPFILE '@var{file_name}']
    [FROM @var{table_references}
      [WHERE @var{where_definition}]
      [GROUP BY @{@var{col_name} | @var{expr} | @var{position}@}
        [ASC | DESC], ... [WITH ROLLUP]]
      [HAVING @var{where_definition}]
      [ORDER BY @{@var{col_name} | @var{expr} | @var{position}@}
        [ASC | DESC] , ...]
      [LIMIT @{[@var{offset},] @var{row_count} | @var{row_count} OFFSET @var{offset}@}]
      [PROCEDURE @var{procedure_name}(@var{argument_list})]
      [FOR UPDATE | LOCK IN SHARE MODE]]
@end example
@c help end

@c description_for_help_topic SELECT  AS ASC DESC ORDER GROUP HAVING BY STRAIGHT_JOIN SQL_SMALL_RESULT SQL_BIG_RESULT SQL_BUFFER_RESULT SQL_CACHE SQL_NO_CACHE SQL_CALC_FOUND_ROWS HIGH_PRIORITY DISTINCT DISTINCTROW ALL INTO FROM OUTFILE DUMPFILE IGNORE JOIN LOCK IN SHARE MODE FOR UPDATE OFFSET LIMIT MEMORY PROCEDURE
@code{SELECT} is used to retrieve rows selected from one or more tables.
Support for @code{UNION} statements and subqueries is available as of MySQL
4.0 and 4.1, respectively.
See @ref{UNION,  , @code{UNION}} and @ref{Subqueries}.

@itemize @bullet
@item
Each @var{select_expr} indicates a column you want to retrieve.

@item
@var{table_references} indicates the table or tables from which to retrieve rows.
Its syntax is described in @ref{JOIN,  , @code{JOIN}}.

@item
@var{where_definition} consists of the keyword @code{WHERE} followed by
an expression that indicates the condition or conditions that rows
must satisfy to be selected.

@end itemize

@code{SELECT} can also be used to retrieve rows computed without reference to
any table.  
@c end_description_for_help_topic
For example:

@example
mysql> SELECT 1 + 1;
        -> 2
@end example

All clauses used must be given in exactly the order shown in the syntax
description. For example,
a @code{HAVING} clause must come after any @code{GROUP BY} clause and before
any @code{ORDER BY} clause.

@itemize @bullet

@item
@cindex aliases, on expressions
@cindex expression aliases
A @var{select_expr} can be given an alias using @code{AS alias_name}.
The alias is used as the expression's column name and can be used in
@code{GROUP BY},
@code{ORDER BY}, or @code{HAVING} clauses.  For example:

@example
mysql> SELECT CONCAT(last_name,', ',first_name) AS full_name
    -> FROM mytable ORDER BY full_name;
@end example

The @code{AS} keyword is optional when aliasing a @var{select_expr}.
The preceding example could have been written like this:

@example
mysql> SELECT CONCAT(last_name,', ',first_name) full_name
    -> FROM mytable ORDER BY full_name;
@end example

Because the @code{AS} is optional, a subtle problem can occur
if you forget the comma between two @var{select_expr} expressions: MySQL
interprets the second as an alias name. For example, in the following
statement, @code{columnb} is treated as an alias name:

@example
mysql> SELECT columna columnb FROM mytable;
@end example

@item
It is not allowable to use a column alias in a @code{WHERE} clause,
because the column value might not yet be determined when the
@code{WHERE} clause is executed.
@xref{Problems with alias}.

@item
@findex FROM
@findex AS
@findex USE INDEX
@findex USE KEY
@findex IGNORE INDEX
@findex IGNORE KEY
@findex FORCE INDEX
@findex FORCE KEY
The @code{FROM table_references} clause indicates the tables from which to
retrieve rows. If you name more than one table, you are performing a
join.  For information on join syntax, see @ref{JOIN, , @code{JOIN}}.
For each table specified, you can optionally specify an alias.

@example
@var{tbl_name} [[AS] @var{alias}]
    [[USE INDEX (@var{key_list})]
      | [IGNORE INDEX (@var{key_list})]
      | [FORCE INDEX (@var{key_list})]]
@end example

@cindex index hints
@cindex hints, index

The use of
@code{USE INDEX},
@code{IGNORE INDEX},
@code{FORCE INDEX}
to give the optimizer hints about how to choose indexes is described in
@ref{JOIN, , @code{JOIN}}.

In MySQL 4.0.14, you can use @code{SET max_seeks_for_key=@var{value}} as an
alternative way to force MySQL to prefer key scans instead of table scans.

@item
You can refer to a table within the current database as @var{tbl_name}
(within the current database), or as @var{db_name.tbl_name} to explicitly
specify a database.  You can refer to a column as @var{col_name},
@var{tbl_name.col_name}, or @var{db_name.tbl_name.col_name}.  You need not
specify a @var{tbl_name} or @var{db_name.tbl_name} prefix for a column
reference unless the reference would be ambiguous.  See @ref{Legal names}
for examples of ambiguity that require the more explicit column reference
forms.

@item
From MySQL 4.1.0 on, you are allowed to specify @code{DUAL} as a dummy
table name in situations where no tables are referenced:

@example
mysql> SELECT 1 + 1 FROM DUAL;
        -> 2
@end example

@code{DUAL} is purely a compatibility feature. Some other servers require
this syntax.

@item
@cindex aliases, for tables
@cindex table aliases
A table reference can be aliased using @code{@var{tbl_name} AS @var{alias_name}} or
@var{tbl_name alias_name}:

@example
mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2
    ->     WHERE t1.name = t2.name;
mysql> SELECT t1.name, t2.salary FROM employee t1, info t2
    ->     WHERE t1.name = t2.name;
@end example

@item
In the @code{WHERE} clause, you can use any of the functions that
MySQL supports, except for aggregate (summary) functions.
@xref{Functions}.

@item
@findex ORDER BY
Columns selected for output can be referred to in @code{ORDER BY} and
@code{GROUP BY} clauses using column names, column aliases, or column
positions.  Column positions are integers and begin with 1:

@example
mysql> SELECT college, region, seed FROM tournament
    ->     ORDER BY region, seed;
mysql> SELECT college, region AS r, seed AS s FROM tournament
    ->     ORDER BY r, s;
mysql> SELECT college, region, seed FROM tournament
    ->     ORDER BY 2, 3;
@end example

To sort in reverse order, add the @code{DESC} (descending) keyword to the
name of the column in the @code{ORDER BY} clause that you are sorting by.
The default is ascending order; this can be specified explicitly using
the @code{ASC} keyword.

Use of column positions is deprecated because the syntax has been removed from
the SQL standard.

@item
@cindex @code{GROUP BY}, extensions to standard SQL
If you use @code{GROUP BY}, output rows are sorted according to the
@code{GROUP BY} columns as if you had an @code{ORDER BY} for the same columns.
MySQL has extended the @code{GROUP BY} clause as of version 3.23.34 so that
you can also specify @code{ASC} and @code{DESC} after columns named in the
clause:

@example
SELECT a, COUNT(b) FROM test_table GROUP BY a DESC
@end example

@item
MySQL extends the use of @code{GROUP BY} to allow you to
select fields that are not mentioned in the @code{GROUP BY} clause.
If you are not getting the results you expect from your query, please
read the @code{GROUP BY} description.
@xref{Group by functions and modifiers}.

@item
As of MySQL 4.1.1, @code{GROUP BY} allows a @code{WITH ROLLUP} modifier.
@xref{GROUP-BY-Modifiers, , @code{GROUP BY} Modifiers}.

@item
The @code{HAVING} clause can refer to any column or alias named in a
@var{select_expr}. It is applied nearly last, just before items are
sent to the client, with no optimization.
(@code{LIMIT} is applied after @code{HAVING}.)

@item
Don't use @code{HAVING} for items that
should be in the @code{WHERE} clause.  For example, do not write this:

@example
mysql> SELECT @var{col_name} FROM @var{tbl_name} HAVING @var{col_name} > 0;
@end example

Write this instead:

@example
mysql> SELECT @var{col_name} FROM @var{tbl_name} WHERE @var{col_name} > 0;
@end example

@item
The @code{HAVING} clause can refer to aggregate functions, which the
@code{WHERE} clause cannot:

@example
mysql> SELECT user, MAX(salary) FROM users
    ->     GROUP BY user HAVING MAX(salary)>10;
@end example

However, that does not work in older MySQL servers (before version 3.22.5).
Instead, you can use a column alias in the select list and refer to the
alias in the @code{HAVING} clause:

@example
mysql> SELECT user, MAX(salary) AS max_salary FROM users
    ->     GROUP BY user HAVING max_salary>10;
@end example

@item
The @code{LIMIT} clause can be used to constrain the number of rows returned
by the @code{SELECT} statement.  @code{LIMIT} takes one or two numeric
arguments, which must be integer constants.

With two arguments, the first argument specifies the offset of the first row to
return, and the second specifies the maximum number of rows to return.
The offset of the initial row is 0 (not 1):

@example
mysql> SELECT * FROM table LIMIT 5,10;  # Retrieve rows 6-15
@end example

For
compatibility with PostgreSQL, MySQL also supports the
@code{LIMIT @var{row_count} OFFSET @var{offset}} syntax.

To retrieve all rows from a certain offset up to the end of the result set,
you can use some large number for the second parameter. This statement
retrieves all rows from the 96th row to the last:

@example
mysql> SELECT * FROM table LIMIT 95,18446744073709551615;
@end example

With one argument, the value specifies the number of rows to return from the
beginning of the result set:

@example
mysql> SELECT * FROM table LIMIT 5;     # Retrieve first 5 rows
@end example

In other words, @code{LIMIT n} is equivalent to @code{LIMIT 0,n}.

@item
@tindex /etc/passwd
The @code{SELECT ... INTO OUTFILE 'file_name'} form of @code{SELECT} writes
the selected rows to a file. The file is created on the server host, so you
must have the @code{FILE} privilege to use this syntax.  The
file cannot already exist, which among other things prevents files such as
@file{/etc/passwd} and database tables from being destroyed.

The @code{SELECT ... INTO OUTFILE} statement is intended primarily to let
you very quickly dump a table on the server machine. If you want to create
the resulting file on some client host other than the server host, you can't use
@code{SELECT ... INTO OUTFILE}. In that case, you should instead use some
command like @code{mysql -e "SELECT ..." > file_name} on the client host to generate the file.

@code{SELECT ...  INTO OUTFILE} is the complement of @code{LOAD DATA
INFILE}; the syntax for the @code{export_options} part of the statement
consists of the same @code{FIELDS} and @code{LINES} clauses that are used
with the @code{LOAD DATA INFILE} statement.
@xref{LOAD DATA, , @code{LOAD DATA}}.

@code{FIELDS ESCAPED BY} controls how to write special characters.
If the @code{FIELDS ESCAPED BY} character is not empty, it is used to prefix
the following characters on output:
@itemize @bullet
@item
The @code{FIELDS ESCAPED BY} character
@item
The @code{FIELDS [OPTIONALLY] ENCLOSED BY} character
@item
The first character of the @code{FIELDS TERMINATED BY} and
@code{LINES TERMINATED BY} values
@item
ASCII @code{0} (what is actually written following the escape character is
ASCII @samp{0}, not a zero-valued byte)
@end itemize

If the @code{FIELDS ESCAPED BY} character is empty, no characters are
escaped and @code{NULL} is output as @code{NULL}, not @code{\N}.  It is
probably not a good idea to specify an empty escape character,
particularly if field values in your data contain any of the characters
in the list just given.

The reason for the above is that you @emph{must} escape any @code{FIELDS
TERMINATED BY}, @code{ENCLOSED BY}, @code{ESCAPED BY}, or @code{LINES TERMINATED BY}
characters to reliably be able to read the file back. ASCII NUL is
escaped to make it easier to view with some pagers.

The resulting file doesn't have to conform to SQL syntax, so nothing
else need be escaped.

Here is an example that produces a file in the comma-separated values format
used by many programs:

@example
SELECT a,b,a+b INTO OUTFILE '/tmp/result.text'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM test_table;
@end example

@item
@findex DUMPFILE
If you use @code{INTO DUMPFILE} instead of @code{INTO OUTFILE}, MySQL writes
only one row into the file, without any column or line termination and
without performing any escape processing.  This is useful if you want to
store a @code{BLOB} value in a file.

@item
@strong{Note}: Any file created by @code{INTO OUTFILE} or @code{INTO
DUMPFILE} is writable by all users on the server host.  The reason for
this is that the MySQL server can't create a file that is owned by anyone
other than the user it's running as (you should never run @command{mysqld} as
@code{root}).  The file thus must be world-writable so that you can
manipulate its contents.

@item
A @code{PROCEDURE} clause names a procedure that should process the data
in the result set.  For an example, see @ref{procedure analyse}.

@item
If you use @code{FOR UPDATE} on a storage engine that uses page or row locks,
rows examined by the query are write-locked until the end of the current
transaction.  Using @code{IN SHARE MODE} sets a shared lock that prevents
other transactions from updating or deleting the examined rows.
@xref{InnoDB locking reads,  , @code{InnoDB} locking reads}.

@end itemize

Following the @code{SELECT} keyword, you can give a number of options
that affect the operation of the statement.

The @code{ALL}, @code{DISTINCT}, and @code{DISTINCTROW} options specify
whether duplicate rows should be returned. If none of these options are
given, the default is @code{ALL} (all matching rows are returned).
@code{DISTINCT} and @code{DISTINCTROW} are synonyms and specify that
duplicate rows in the result set should be removed.

@code{HIGH_PRIORITY}, @code{STRAIGHT_JOIN}, and options beginning with
@code{SQL_} are MySQL extensions to standard SQL.

@itemize @bullet

@item
@code{HIGH_PRIORITY} will give the @code{SELECT} higher priority than
a statement that updates a table.  You should use this only for queries
that are very fast and must be done at once.  A @code{SELECT HIGH_PRIORITY}
query that is issued while the table is locked for reading will run even if
there is already an update statement waiting for the table to be free.

@code{HIGH_PRIORITY} cannot be used with @code{SELECT} statements that
are part of a @code{UNION}.

@item
@cindex hints
@code{STRAIGHT_JOIN} forces the optimizer to join the tables in the order in
which they are listed in the @code{FROM} clause. You can use this to speed up
a query if the optimizer joins the tables in non-optimal order.
@xref{EXPLAIN, , @code{EXPLAIN}}.
@code{STRAIGHT_JOIN} also can be used in the @var{table_references} list.
@xref{JOIN, , @code{JOIN}}.

@item
@code{SQL_BIG_RESULT} can be used with @code{GROUP BY} or @code{DISTINCT}
to tell the optimizer that the result set will have many rows.  In this case,
MySQL will directly use disk-based temporary tables if needed.
MySQL will also, in this case, prefer sorting to using a
temporary table with a key on the @code{GROUP BY} elements.

@item
@code{SQL_BUFFER_RESULT} forces the result to be put into a temporary
table. This helps MySQL free the table locks early and helps
in cases where it takes a long time to send the result set to the client.

@item
@code{SQL_SMALL_RESULT} can be used
with @code{GROUP BY} or @code{DISTINCT} to tell the optimizer that the
result set will be small.  In this case, MySQL uses fast
temporary tables to store the resulting table instead of using sorting. In
MySQL 3.23 and up, this shouldn't normally be needed.

@item
@code{SQL_CALC_FOUND_ROWS} (available in MySQL 4.0.0 and up) tells MySQL
to calculate how many rows there would be in the result set, disregarding
any @code{LIMIT} clause.  The number of rows can then be retrieved with
@code{SELECT FOUND_ROWS()}.
@xref{Information functions}.

Before MySQL 4.1.0, this option does not work with
@code{LIMIT 0}, which is optimized to return instantly (resulting in a
row count of 0).
@xref{LIMIT optimization,  , @code{LIMIT} optimization}.

@item
@code{SQL_CACHE} tells MySQL to store the query result in the query cache if
you are using a @code{query_cache_type} value of @code{2} or @code{DEMAND}.
For a query that uses @code{UNION} or subqueries, this option takes effect
to be used in any @code{SELECT} of the query.
@xref{Query Cache}.

@item
@code{SQL_NO_CACHE} tells MySQL not to store the query result
in the query cache. @xref{Query Cache}.
For a query that uses @code{UNION} or subqueries, this
option takes effect to be used in any @code{SELECT} of the query.

@end itemize


@menu
* JOIN::                        @code{JOIN} Syntax
* UNION::                       @code{UNION} Syntax
@end menu

@node JOIN, UNION, SELECT, SELECT
@subsubsection @code{JOIN} Syntax

@findex JOIN
@findex INNER JOIN
@findex CROSS JOIN
@findex LEFT JOIN
@findex LEFT OUTER JOIN
@findex NATURAL LEFT JOIN
@findex NATURAL LEFT OUTER JOIN
@findex RIGHT JOIN
@findex RIGHT OUTER JOIN
@findex NATURAL RIGHT JOIN
@findex NATURAL RIGHT OUTER JOIN
@findex STRAIGHT_JOIN

@c description_for_help_topic JOIN  INNER CROSS LEFT OUTER NATURAL RIGHT STRAIGHT_JOIN USE INDEX AS IGNORE FORCE ON USING
MySQL supports the following @code{JOIN} syntaxes for the
@var{table_references} part of @code{SELECT} statements and multiple-table
@code{DELETE} and @code{UPDATE} statements:

@example
@var{table_reference}, @var{table_reference}
@var{table_reference} [INNER | CROSS] JOIN @var{table_reference} [@var{join_condition}]
@var{table_reference} STRAIGHT_JOIN @var{table_reference}
@var{table_reference} LEFT [OUTER] JOIN @var{table_reference} [@var{join_condition}]
@var{table_reference} NATURAL [LEFT [OUTER]] JOIN @var{table_reference}
@{ OJ @var{table_reference} LEFT OUTER JOIN @var{table_reference}
    ON @var{conditional_expr} @}
@var{table_reference} RIGHT [OUTER] JOIN @var{table_reference} [@var{join_condition}]
@var{table_reference} NATURAL [RIGHT [OUTER]] JOIN @var{table_reference}
@end example

@var{table_reference} is defined as:

@findex AS
@example
@var{tbl_name} [[AS] @var{alias}]
    [[USE INDEX (@var{key_list})]
      | [IGNORE INDEX (@var{key_list})]
      | [FORCE INDEX (@var{key_list})]]
@end example

@var{join_condition} is defined as:

@example
ON @var{conditional_expr} | USING (@var{column_list})
@end example
@c end_description_for_help_topic

You should generally not have any conditions in the @code{ON} part that are
used to restrict which rows you want in the result set, but rather specify
these conditions in the @code{WHERE} clause. There are exceptions to this rule.

Note that @code{INNER JOIN} syntax allows a @code{join_condition} only from
MySQL 3.23.17 on.  The same is true for @code{JOIN} and @code{CROSS JOIN} only
as of MySQL 4.0.11.

@cindex ODBC compatibility
@cindex compatibility, with ODBC
The @code{@{ OJ ... LEFT OUTER JOIN ...@}} syntax shown in the preceding list
exists only for compatibility with ODBC.

@itemize @bullet
@item
A table reference can be aliased using @code{@var{tbl_name} AS @var{alias_name}} or
@var{tbl_name alias_name}:

@example
mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2
    ->        WHERE t1.name = t2.name;
mysql> SELECT t1.name, t2.salary FROM employee t1, info t2
    ->        WHERE t1.name = t2.name;
@end example

@item
The @code{ON} conditional is any conditional expression of the form that can
be used in a @code{WHERE} clause.

@item
If there is no matching record for the right table in the @code{ON} or
@code{USING} part in a @code{LEFT JOIN}, a row with all columns set to
@code{NULL} is used for the right table.  You can use this fact to find
records in a table that have no counterpart in another table:

@c example_for_help_topic JOIN
@example
mysql> SELECT table1.* FROM table1
    ->        LEFT JOIN table2 ON table1.id=table2.id
    ->        WHERE table2.id IS NULL;
@end example

This example finds all rows in @code{table1} with an @code{id} value that is
not present in @code{table2} (that is, all rows in @code{table1} with no
corresponding row in @code{table2}).  This assumes that @code{table2.id} is
declared @code{NOT NULL}.
@xref{LEFT JOIN optimization,  , @code{LEFT JOIN} optimization}.

@item
The @code{USING} @code{(column_list)} clause names a list of columns that must
exist in both tables. The following two clauses are semantically identical:

@example
a LEFT JOIN b USING (c1,c2,c3)
a LEFT JOIN b ON a.c1=b.c1 AND a.c2=b.c2 AND a.c3=b.c3
@end example

@item
The @code{NATURAL [LEFT] JOIN} of two tables is defined to be
semantically equivalent to an @code{INNER JOIN} or a @code{LEFT JOIN}
with a @code{USING} clause that names all columns that exist in both
tables.

@item
@cindex hints
@code{INNER JOIN} and @code{,} (comma) are semantically equivalent in
the absence of a join condition: both will produce a Cartesian product
between the specified tables (that is, each and every row in the first table
will be joined onto all rows in the second table).

@item
@code{RIGHT JOIN} works analogously to @code{LEFT JOIN}.  To keep code
portable across databases, it's recommended to use @code{LEFT JOIN}
instead of @code{RIGHT JOIN}.

@item
@cindex hints
@code{STRAIGHT_JOIN} is identical to @code{JOIN}, except that the left table
is always read before the right table. This can be used for those (few)
cases for which the join optimizer puts the tables in the wrong order.

@end itemize

@cindex index hints
@cindex hints, index
@findex USE INDEX
@findex IGNORE INDEX
As of MySQL 3.23.12, you can give hints about which index MySQL
should use when retrieving information from a table.  By specifying
@code{USE INDEX (key_list)}, you can tell MySQL to use only one of the
possible indexes to find rows in the table.  The alternative syntax
@code{IGNORE INDEX (key_list)} can be used to tell MySQL to not use some
particular index.  These hints are useful if @code{EXPLAIN} shows that MySQL
is using the wrong index from the list of possible indexes.

@findex FORCE INDEX
From MySQL 4.0.9 on, you can also use @code{FORCE INDEX}. This acts likes
@code{USE INDEX (key_list)} but with the addition that a table scan
is assumed to be @emph{very} expensive.  In other words, a table scan will
only be used if there is no way to use one of the given indexes to
find rows in the table.

@findex USE KEY
@findex IGNORE KEY
@findex FORCE KEY
@code{USE KEY}, @code{IGNORE KEY}, and @code{FORCE KEY} are synonyms for
@code{USE INDEX}, @code{IGNORE INDEX}, and @code{FORCE INDEX}.

@strong{Note}: @code{USE INDEX}, @code{IGNORE INDEX}, and @code{FORCE INDEX}
only affect which indexes are used when MySQL decides how to find rows in
the table and how to do the join. They do not affect whether an index will
be used when resolving an @code{ORDER BY} or @code{GROUP BY}.

Some join examples:

@example
mysql> SELECT * FROM table1,table2 WHERE table1.id=table2.id;
mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id;
mysql> SELECT * FROM table1 LEFT JOIN table2 USING (id);
mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id
    ->          LEFT JOIN table3 ON table2.id=table3.id;
mysql> SELECT * FROM table1 USE INDEX (key1,key2)
    ->          WHERE key1=1 AND key2=2 AND key3=3;
mysql> SELECT * FROM table1 IGNORE INDEX (key3)
    ->          WHERE key1=1 AND key2=2 AND key3=3;
@end example

@xref{LEFT JOIN optimization, , @code{LEFT JOIN} optimization}.


@node UNION,  , JOIN, SELECT
@subsubsection @code{UNION} Syntax

@findex UNION

@c example_for_help_topic UNION
@example
SELECT ...
UNION [ALL | DISTINCT]
SELECT ...
  [UNION [ALL | DISTINCT]
   SELECT ...]
@end example

@c description_for_help_topic UNION  ALL
@code{UNION} is used to combine the result from many @code{SELECT}
statements into one result set.  @code{UNION} is available from MySQL 4.0.0
on.

Selected columns listed in corresponding positions of each @code{SELECT}
statement should have the same type. (For example, the first column selected
by the first statement should have the same type as the first column selected
by the other statements.) The column names used in
the first @code{SELECT} statement are used as the column names for the
results returned.
@c end_description_for_help_topic

The @code{SELECT} statements are normal select statements, but with the
following restrictions:

@itemize @bullet
@item
Only the last @code{SELECT} statement can have @code{INTO OUTFILE}.
@item
@code{HIGH_PRIORITY} cannot be used with @code{SELECT} statements that
are part of a @code{UNION}. If you specify it for the first @code{SELECT},
it has no effect. If you specify it for any subsequent @code{SELECT}
statements, a syntax error results.
@end itemize

If you don't use the keyword @code{ALL} for the @code{UNION}, all
returned rows will be unique, as if you had done a @code{DISTINCT} for
the total result set.  If you specify @code{ALL}, you will get all
matching rows from all the used @code{SELECT} statements.

The @code{DISTINCT} keyword is an optional word (introduced in MySQL 4.0.17).
It does nothing, but is allowed in the syntax as required by the SQL standard.

Before MySQL 4.1.2, you cannot mix @code{UNION ALL} and @code{UNION
DISTINCT} in the same query.  If you use @code{ALL} for one
@code{UNION}, it is used for all of them. As of MySQL 4.1.2, mixed
@code{UNION} types are treated such that a @code{DISTINCT} union overrides
any @code{ALL} union to its left. A @code{DISTINCT} union can be produced
explicitly by using @code{UNION DISTINCT} or implicitly by using @code{UNION}
with no following @code{DISTINCT} or @code{ALL} keyword.

If you want to use an @code{ORDER BY} or @code{LIMIT} clause to sort or limit
the entire @code{UNION} result, parenthesize the individual @code{SELECT}
statements and place the @code{ORDER BY} or @code{LIMIT} after the last one.
The following example uses both clauses:

@example
(SELECT a FROM @var{tbl_name} WHERE a=10 AND B=1)
UNION
(SELECT a FROM @var{tbl_name} WHERE a=11 AND B=2)
ORDER BY a LIMIT 10;
@end example

This kind of @code{ORDER BY} cannot use column references that include a
table name (that is, names in @var{tbl_name.col_name} format). Instead,
provide a column alias in the first @code{SELECT} statement and refer to the
alias in the @code{ORDER BY}, or else refer to the column in the @code{ORDER
BY} using its column position.  (An alias is preferable because use of
column positions is deprecated.)

To apply @code{ORDER BY} or @code{LIMIT} to an individual @code{SELECT},
place the clause inside the parentheses that enclose the @code{SELECT}:

@example
(SELECT a FROM @var{tbl_name} WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM @var{tbl_name} WHERE a=11 AND B=2 ORDER BY a LIMIT 10);
@end example

@c this is also written in the "known bugs" section
The types and lengths of the columns in the result set of a @code{UNION}
take into account the values retrieved by all the @code{SELECT} statements.
Before MySQL 4.1.1, a limitation of @code{UNION} is that only the values from
the first @code{SELECT} are used to determine result column types and lengths.
This could result in value truncation if, for example, the first
@code{SELECT} retrieves shorter values than the second @code{SELECT}:

@example
mysql> SELECT REPEAT('a',1) UNION SELECT REPEAT('b',10);
+---------------+
| REPEAT('a',1) |
+---------------+
| a             |
| b             |
+---------------+
@end example

That limitation has been removed as of MySQL 4.1.1:

@example
mysql> SELECT REPEAT('a',1) UNION SELECT REPEAT('b',10);
+---------------+
| REPEAT('a',1) |
+---------------+
| a             |
| bbbbbbbbbb    |
+---------------+
@end example


@node Subqueries, TRUNCATE, SELECT, Data Manipulation
@subsection Subquery Syntax

@cindex subselects
@cindex subqueries
@cindex subquery
@cindex nested queries
@cindex nested query
@cindex nesting queries

A subquery is a @code{SELECT} statement inside another statement.

Starting with MySQL 4.1, all subquery forms and operations that the SQL
standard requires are supported, as well as a few features that are
MySQL-specific.

With MySQL versions prior to 4.1, it was necessary to work around or avoid
the use of subqueries. In many cases, subqueries can successfully be
rewritten using joins and other methods.
@xref{Rewriting subqueries}.

Here is an example of a subquery:

@example
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
@end example

In this example, @code{SELECT * FROM t1 ...} is the @emph{outer query}
(or @emph{outer statement}), and @code{(SELECT column1 FROM t2)} is the
@emph{subquery}.
We say that the subquery is @emph{nested} in the outer query, and in fact
it's possible to nest subqueries within other subqueries, to a great depth.
A subquery must always appear within parentheses.

The main advantages of subqueries are:

@itemize @bullet
@item
They allow queries that are @emph{structured} so that it's possible to
isolate each part of a statement.
@item
They provide alternative ways to perform operations that would otherwise
require complex joins and unions.
@item
They are, in many people's opinion, readable.
Indeed, it was the innovation of subqueries that gave people the original
idea of calling the early SQL ``Structured Query Language.''
@end itemize

Here is an example statement that shows the major points about subquery
syntax as specified by the SQL standard and supported in MySQL:

@example
DELETE FROM t1
WHERE s11 > ANY
 (SELECT COUNT(*) /* no hint */ FROM t2
 WHERE NOT EXISTS
  (SELECT * FROM t3
   WHERE ROW(5*t2.s1,77)=
    (SELECT 50,11*s1 FROM t4 UNION SELECT 50,77 FROM
     (SELECT * FROM t5) AS t5)));
@end example

A subquery can return a scalar (a single value), a single row, a single
column, or a table (one or more rows of one or more columns).  These are called
scalar, column, row, and table subqueries.  Subqueries that return a
particular kind of result often can be used only in certain contexts, as
described in the following sections.

There are few restrictions on the type of statements in which subqueries can
be used:

@itemize @bullet
@item
A subquery's outer statement can be any one of:
@code{SELECT}, @code{INSERT}, @code{UPDATE}, @code{DELETE},
@code{SET}, or @code{DO}.
@item
A subquery can contain any of the keywords or clauses that an ordinary
@code{SELECT} can contain:
@code{DISTINCT}, @code{GROUP BY}, @code{ORDER BY}, @code{LIMIT},
joins, index hints, @code{UNION} constructs, comments, functions, and so on.
@end itemize

One restriction is that currently you cannot modify a table and select from
the same table in a subquery. This applies to statements such as
@code{DELETE}, @code{INSERT}, @code{REPLACE}, and @code{UPDATE}.


@menu
* Scalar subqueries::           The Subquery as Scalar Operand
* Comparisons using subqueries::  Comparisons Using Subqueries
* ANY IN SOME subqueries::      Subqueries with @code{ANY}, @code{IN}, and @code{SOME}
* ALL subqueries::              Subqueries with @code{ALL}
* Row subqueries::              Row Subqueries
* EXISTS and NOT EXISTS subqueries::  @code{EXISTS} and @code{NOT EXISTS}
* Correlated subqueries::       Correlated Subqueries
* Unnamed views::               Subqueries in the @code{FROM} clause
* Subquery errors::             Subquery Errors
* Optimizing subqueries::       Optimizing Subqueries
* Rewriting subqueries::        Rewriting Subqueries as Joins for Earlier MySQL Versions
@end menu

@node Scalar subqueries, Comparisons using subqueries, Subqueries, Subqueries
@subsubsection The Subquery as Scalar Operand

In its simplest form, a subquery is a scalar subquery that returns a single
value.  A scalar subquery is a simple operand, and you can use it wherever a
single column value or literal is legal, and you can expect it to have those
characteristics that all operands have: a data type, a length, an indication
whether it can be @code{NULL}, and so on.  For example:

@example
CREATE TABLE t1 (s1 INT, s2 CHAR(5) NOT NULL);
INSERT INTO t1 VALUES(100, 'abcde');
SELECT (SELECT s2 FROM t1);
@end example

The subquery in this @code{SELECT} returns a single value (@code{'abcde'})
that has a data type of @code{CHAR}, a length of 5, a character set and
collation equal to the defaults in effect at @code{CREATE TABLE} time, and
an indication that the value in the column can be @code{NULL}. In fact,
almost all subqueries can be @code{NULL}. If the table used in the example
were empty, the value of the subquery would be @code{NULL}.

When you see examples in the following sections that contain the rather
spartan construct @code{(SELECT column1 FROM t1)}, imagine that your own
code will contain much more diverse and complex constructions.

For example, suppose that we make two tables:

@example
CREATE TABLE t1 (s1 INT);
INSERT INTO t1 VALUES (1);
CREATE TABLE t2 (s1 INT);
INSERT INTO t2 VALUES (2);
@end example

Then perform a @code{SELECT}:

@example
SELECT (SELECT s1 FROM t2) FROM t1;
@end example

The result will be @code{2} because there is a row in @code{t2} containing a
column @code{s1} that has a value of @code{2}.

A scalar subquery can be part of an expression.  Don't forget the
parentheses, even if the subquery is an operand that provides an argument
for a function.  For example:

@example
SELECT UPPER((SELECT s1 FROM t1)) FROM t2;
@end example


@node Comparisons using subqueries, ANY IN SOME subqueries, Scalar subqueries, Subqueries
@subsubsection Comparisons Using Subqueries

The most common use of a subquery is in the form:

@example
@var{non_subquery_operand} @var{comparison_operator} (@var{subquery})
@end example

Where @var{comparison_operator} is one of these operators:
@example
=  >  <  >=  <=  <>
@end example

For example:
@example
... 'a' = (SELECT column1 FROM t1)
@end example

At one time the only legal place for a subquery was on the right side of a
comparison, and you might still find some old DBMSs that insist on this.

Here is an example of a common-form subquery comparison that you cannot do
with a join. It finds all the values in table @code{t1} that are equal to a
maximum value in table @code{t2}:

@example
SELECT column1 FROM t1
       WHERE column1 = (SELECT MAX(column2) FROM t2);
@end example

Here is another example, which again is impossible with a join because it
involves aggregating for one of the tables. It finds all rows in table
@code{t1} containing a value that occurs twice in a given column:

@example
SELECT * FROM t1 AS t
    WHERE 2 = (SELECT COUNT(*) FROM t1 WHERE t1.id = t.id);
@end example

For a comparison performed with one of these comparison operators, the
subquery must return a scalar, with the exception that @code{=} can be used
with row subqueries.
@xref{Row subqueries}.


@node ANY IN SOME subqueries, ALL subqueries, Comparisons using subqueries, Subqueries
@subsubsection Subqueries with @code{ANY}, @code{IN}, and @code{SOME}

Syntax:
@example
@var{operand} @var{comparison_operator} ANY (@var{subquery})
@var{operand} IN (@var{subquery})
@var{operand} @var{comparison_operator} SOME (@var{subquery})
@end example

The @code{ANY} keyword, which must follow a comparison operator, means
``return @code{TRUE} if the comparison is @code{TRUE} for @code{ANY} of the
values in the column that the subquery returns.''
For example:

@example
SELECT s1 FROM t1 WHERE s1 > ANY (SELECT s1 FROM t2);
@end example

Suppose that there is a row in table @code{t1} containing @code{(10)}.
The expression is @code{TRUE} if table @code{t2} contains @code{(21,14,7)}
because there is a value @code{7} in @code{t2} that is less than @code{10}.
The expression is @code{FALSE} if table @code{t2} contains @code{(20,10)},
or if table @code{t2} is empty.  The expression is @code{UNKNOWN} if table
@code{t2} contains @code{(NULL,NULL,NULL)}.

The word @code{IN} is an alias for @code{= ANY}. Thus these two statements
are the same:

@example
SELECT s1 FROM t1 WHERE s1 = ANY (SELECT s1 FROM t2);
SELECT s1 FROM t1 WHERE s1 IN    (SELECT s1 FROM t2);
@end example

However, @code{NOT IN} is not an alias for @code{<> ANY}, but for
@code{<> ALL}. See @ref{ALL subqueries,  , @code{ALL} subqueries}.

The word @code{SOME} is an alias for @code{ANY}. Thus these two statements
are the same:

@example
SELECT s1 FROM t1 WHERE s1 <> ANY  (SELECT s1 FROM t2);
SELECT s1 FROM t1 WHERE s1 <> SOME (SELECT s1 FROM t2);
@end example

Use of the word @code{SOME} is rare, but this example shows why it might be
useful. To most people's ears, the English phrase ``a is not equal to any
b'' means ``there is no b which is equal to a,'' but that isn't what is
meant by the SQL syntax. Using @code{<> SOME} instead helps ensure that
everyone understands the true meaning of the query.


@node ALL subqueries, Row subqueries, ANY IN SOME subqueries, Subqueries
@subsubsection Subqueries with @code{ALL}

Syntax:
@example
@var{operand} @var{comparison_operator} ALL (@var{subquery})
@end example

The word @code{ALL}, which must follow a comparison operator, means
``return @code{TRUE} if the comparison is @code{TRUE} for @code{ALL} of
the values in the column that the subquery returns.''
For example:

@example
SELECT s1 FROM t1 WHERE s1 > ALL (SELECT s1 FROM t2);
@end example

Suppose that there is a row in table @code{t1} containing @code{(10)}.
The expression is @code{TRUE} if table @code{t2} contains @code{(-5,0,+5)}
because @code{10} is greater than all three values in @code{t2}.
The expression is @code{FALSE} if table @code{t2} contains
@code{(12,6,NULL,-100)} because there is a single value @code{12} in table @code{t2}
that is greater than @code{10}.
The expression is @code{UNKNOWN} if table @code{t2} contains @code{(0,NULL,1)}.

Finally, if table @code{t2} is empty, the result is @code{TRUE}.
You might think the result should be @code{UNKNOWN}, but
sorry, it's @code{TRUE}. So, rather oddly, the following statement
is @code{TRUE} when table @code{t2} is empty:

@example
SELECT * FROM t1 WHERE 1 > ALL (SELECT s1 FROM t2);
@end example

But this statement is @code{UNKNOWN} when table @code{t2} is empty:

@example
SELECT * FROM t1 WHERE 1 > (SELECT s1 FROM t2);
@end example

In addition, the following statement is @code{UNKNOWN} when table @code{t2}
is empty:

@example
SELECT * FROM t1 WHERE 1 > ALL (SELECT MAX(s1) FROM t2);
@end example

In general, @emph{tables with @code{NULL} values} and @emph{empty tables} are
@emph{edge cases}. When writing subquery code, always consider whether
you have taken those two possibilities into account.

@code{NOT IN} is an alias for @code{<> ALL}. Thus these two statements
are the same:

@example
SELECT s1 FROM t1 WHERE s1 <> ALL (SELECT s1 FROM t2);
SELECT s1 FROM t1 WHERE s1 NOT IN (SELECT s1 FROM t2);
@end example


@node Row subqueries, EXISTS and NOT EXISTS subqueries, ALL subqueries, Subqueries
@subsubsection Row Subqueries

The discussion to this point has been of scalar or column subqueries, that is,
subqueries that return a single value or a column of values.
A @emph{row subquery} is a subquery variant that returns a
single row and can thus return more than one column value.
Here are two examples:

@example
SELECT * FROM t1 WHERE (1,2) = (SELECT column1, column2 FROM t2);
SELECT * FROM t1 WHERE ROW(1,2) = (SELECT column1, column2 FROM t2);
@end example

The queries here are both @code{TRUE} if table @code{t2} has
a row where @code{column1 = 1} and @code{column2 = 2}.

The expressions @code{(1,2)} and @code{ROW(1,2)} are sometimes called
@emph{row constructors}. The two are equivalent.
They are legal in other contexts, too. For example, the following two
statements are semantically equivalent (although currently only the second one
can be optimized):

@example
SELECT * FROM t1 WHERE (column1,column2) = (1,1);
SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1;
@end example

The normal use of row constructors, though, is for comparisons with
subqueries that return two or more columns. For example, the following query answers
the request, ``find all rows in table @code{t1} that also exist in table
@code{t2}'':

@example
SELECT column1,column2,column3
       FROM t1
       WHERE (column1,column2,column3) IN
             (SELECT column1,column2,column3 FROM t2);
@end example


@node EXISTS and NOT EXISTS subqueries, Correlated subqueries, Row subqueries, Subqueries
@subsubsection @code{EXISTS} and @code{NOT EXISTS}

If a subquery returns any rows at all, then @code{EXISTS subquery} is
@code{TRUE}, and @code{NOT EXISTS subquery} is @code{FALSE}.
For example:

@example
SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
@end example

Traditionally, an @code{EXISTS} subquery starts with @code{SELECT *}, but it
could begin with @code{SELECT 5} or @code{SELECT column1} or anything at
all. MySQL ignores the @code{SELECT} list in such a subquery, so it
doesn't matter.

For the preceding example, if @code{t2} contains any rows, even rows with
nothing but @code{NULL} values, then the @code{EXISTS} condition is
@code{TRUE}. This is actually an unlikely example, since almost always a
@code{[NOT] EXISTS} subquery will contain correlations.
Here are some more realistic examples:

@itemize @bullet
@item
What kind of store is present in one or more cities?
@example
SELECT DISTINCT store_type FROM Stores
  WHERE EXISTS (SELECT * FROM Cities_Stores
                WHERE Cities_Stores.store_type = Stores.store_type);
@end example

@item
What kind of store is present in no cities?
@example
SELECT DISTINCT store_type FROM Stores
  WHERE NOT EXISTS (SELECT * FROM Cities_Stores
                    WHERE Cities_Stores.store_type = Stores.store_type);
@end example

@item
What kind of store is present in all cities?
@example
SELECT DISTINCT store_type FROM Stores S1
  WHERE NOT EXISTS (
    SELECT * FROM Cities WHERE NOT EXISTS (
      SELECT * FROM Cities_Stores
       WHERE Cities_Stores.city = Cities.city
       AND Cities_Stores.store_type = Stores.store_type));
@end example

@end itemize

The last example is a double-nested @code{NOT EXISTS} query. That is, it has a
@code{NOT EXISTS} clause within a @code{NOT EXISTS} clause. Formally, it
answers the question ``does a city exist with a store that is not in
@code{Stores}?'' But it's easier to say that a nested @code{NOT EXISTS} answers
the question ``is x TRUE for all y?''


@node Correlated subqueries, Unnamed views, EXISTS and NOT EXISTS subqueries, Subqueries
@subsubsection Correlated Subqueries

A @emph{correlated subquery} is a subquery that contains a reference to a
table that also appears in the outer query.
For example:

@example
SELECT * FROM t1 WHERE column1 = ANY
       (SELECT column1 FROM t2 WHERE t2.column2 = t1.column2);
@end example

Notice that the subquery contains a reference to a column
of @code{t1}, even though the subquery's @code{FROM} clause doesn't mention
a table @code{t1}. So, MySQL looks outside the subquery, and finds @code{t1} in the
outer query.

Suppose that table @code{t1} contains a row where @code{column1 = 5} and
@code{column2 = 6}; meanwhile, table @code{t2} contains a row where
@code{column1 = 5} and @code{column2 = 7}. The simple expression
@code{... WHERE column1 = ANY (SELECT column1 FROM t2)} would be
@code{TRUE}, but in this example, the @code{WHERE} clause within the
subquery is @code{FALSE} (because @code{(5,6)} is not equal to @code{(5,7)}),
so the subquery as a whole is @code{FALSE}.

@strong{Scoping rule:} MySQL evaluates from inside to outside.
For example:

@example
SELECT column1 FROM t1 AS x
  WHERE x.column1 = (SELECT column1 FROM t2 AS x
    WHERE x.column1 = (SELECT column1 FROM t3
      WHERE x.column2 = t3.column1));
@end example

In this statement, @code{x.column2} must be a column in table @code{t2} because
@code{SELECT column1 FROM t2 AS x ...} renames @code{t2}. It is not a
column in table @code{t1} because @code{SELECT column1 FROM t1 ...} is an
outer query that is @emph{farther out}.

For subqueries in @code{HAVING} or @code{ORDER BY} clauses, MySQL also
looks for column names in the outer select list.

For certain cases, a correlated subquery is optimized. For example:

@example
@var{val} IN (SELECT @var{key_val} FROM @var{tbl_name} WHERE @var{correlated_condition})
@end example

Otherwise, they are inefficient and likely to be slow. Rewriting the query
as a join might improve performance.


@node Unnamed views, Subquery errors, Correlated subqueries, Subqueries
@subsubsection Subqueries in the @code{FROM} clause

@cindex derived tables
@cindex unnamed views

Subqueries are legal in a @code{SELECT} statement's @code{FROM} clause.
The syntax that you'll actually see is:

@example
SELECT ... FROM (@var{subquery}) AS @var{name} ...
@end example

The @code{AS @var{name}} clause is mandatory, because every table in a
@code{FROM} clause must have a name. Any columns in the @var{subquery}
select list must have unique names. You can find this syntax described
elsewhere in this manual, where the term used is ``derived tables.''

@c TODO: figure out what the "elsewhere" in previous sentence refers to.

For illustration, assume that you have this table:
@example
CREATE TABLE t1 (s1 INT, s2 CHAR(5), s3 FLOAT);
@end example

Here's how to use a subquery in the @code{FROM} clause, using
the example table:

@example
INSERT INTO t1 VALUES (1,'1',1.0);
INSERT INTO t1 VALUES (2,'2',2.0);
SELECT sb1,sb2,sb3
       FROM (SELECT s1 AS sb1, s2 AS sb2, s3*2 AS sb3 FROM t1) AS sb
       WHERE sb1 > 1;
@end example

Result: @code{2, '2', 4.0}.

Here's another example: Suppose that you want to know the average of a
set of sums for a grouped table. This won't work:

@example
SELECT AVG(SUM(column1)) FROM t1 GROUP BY column1;
@end example

But this query will provide the desired information:

@example
SELECT AVG(sum_column1)
       FROM (SELECT SUM(column1) AS sum_column1
             FROM t1 GROUP BY column1) AS t1;
@end example

Notice that the column name used within the subquery
@code{(sum_column1)} is recognized in the outer query.

Subqueries in the @code{FROM} clause can return a scalar, column, row, or
table.  At the moment, subqueries in the @code{FROM} clause cannot be
correlated subqueries.

Subqueries in the @code{FROM} clause will be executed even for the
@code{EXPLAIN} statement (that is, derived temporary tables will be built).
This occurs because upper level queries need information about all tables
during optimization phase.


@node Subquery errors, Optimizing subqueries, Unnamed views, Subqueries
@subsubsection Subquery Errors

There are some new error returns that apply only to subqueries.
This section groups them together because reviewing them will help
remind you of some points.

@itemize @bullet
@item
Unsupported subquery syntax:

@example
ERROR 1235 (ER_NOT_SUPPORTED_YET)
SQLSTATE = 42000
Message = "This version of MySQL doesn't yet support
'LIMIT & IN/ALL/ANY/SOME subquery'"
@end example

This means that statements of the following form will not work, although this
happens only in some early versions, such as MySQL 4.1.1:

@example
SELECT * FROM t1 WHERE s1 IN (SELECT s2 FROM t2 ORDER BY s1 LIMIT 1)
@end example

@item
Incorrect number of columns from subquery:

@example
ERROR 1241 (ER_OPERAND_COL)
SQLSTATE = 21000
Message = "Operand should contain 1 column(s)"
@end example

This error will occur in cases like this:

@example
SELECT (SELECT column1, column2 FROM t2) FROM t1;
@end example

It's okay to use a subquery that returns multiple columns, if the purpose
is comparison. @xref{Row subqueries}.
But in other contexts, the subquery must be a scalar operand.

@item
Incorrect number of rows from subquery:

@example
ERROR 1242 (ER_SUBSELECT_NO_1_ROW)
SQLSTATE = 21000
Message = "Subquery returns more than 1 row"
@end example

This error will occur for statements such as the following one,
but only when there is more than one row in @code{t2}:

@example
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
@end example

That means this
error might occur in code that had been working for years, because somebody
happened to make a change that affected the number of rows that the
subquery can return. Remember that if the object is to find any number of
rows, not just one, then the correct statement would look like this:

@example
SELECT * FROM t1 WHERE column1 = ANY (SELECT column1 FROM t2);
@end example

@item
Incorrectly used table in subquery:

@example
Error 1093 (ER_UPDATE_TABLE_USED)
SQLSTATE = HY000
Message = "You can't specify target table 'x'
for update in FROM clause"
@end example

This error will occur in cases like this:

@example
UPDATE t1 SET column2 = (SELECT MAX(column1) FROM t1);
@end example

It's okay to use a subquery for assignment within an
@code{UPDATE} statement, since subqueries are legal in @code{UPDATE}
and @code{DELETE} statements as well as in @code{SELECT} statements.
However, you cannot use the same table, in this case table @code{t1}, for
both the subquery's @code{FROM} clause and the update target.

@end itemize

Usually, failure of a subquery causes the entire statement to fail.


@node Optimizing subqueries, Rewriting subqueries, Subquery errors, Subqueries
@subsubsection Optimizing Subqueries

Development is ongoing, so no optimization tip is reliable for the long
term. Some interesting tricks that you might want to play with are:

@itemize @bullet
@item
Use subquery clauses that affect the number or order of the rows in the
subquery. For example:

@example
SELECT * FROM t1 WHERE t1.column1 IN
  (SELECT column1 FROM t2 ORDER BY column1);
SELECT * FROM t1 WHERE t1.column1 IN
  (SELECT DISTINCT column1 FROM t2);
SELECT * FROM t1 WHERE EXISTS
  (SELECT * FROM t2 LIMIT 1);
@end example

@item
Replace a join with a subquery. For example, use this query:

@example
SELECT DISTINCT column1 FROM t1 WHERE t1.column1 IN (
  SELECT column1 FROM t2);
@end example

Instead of this query:

@example
SELECT DISTINCT t1.column1 FROM t1, t2
  WHERE t1.column1 = t2.column1;
@end example

@item
Move clauses from outside to inside the subquery. For example, use this
query:

@example
SELECT * FROM t1
  WHERE s1 IN (SELECT s1 FROM t1 UNION ALL SELECT s1 FROM t2);
@end example

Instead of this query:

@example
SELECT * FROM t1
  WHERE s1 IN (SELECT s1 FROM t1) OR s1 IN (SELECT s1 FROM t2);
@end example

For another example, use this query:

@example
SELECT (SELECT column1 + 5 FROM t1) FROM t2;
@end example

Instead of this query:

@example
SELECT (SELECT column1 FROM t1) + 5 FROM t2;
@end example

@item
Use a row subquery instead of a correlated subquery. For example, use this
query:

@example
SELECT * FROM t1
  WHERE (column1,column2) IN (SELECT column1,column2 FROM t2);
@end example

Instead of this query:

@example
SELECT * FROM t1
  WHERE EXISTS (SELECT * FROM t2 WHERE t2.column1=t1.column1
  AND t2.column2=t1.column2);
@end example

@item
Use @code{NOT (a = ANY (...))} rather than @code{a <> ALL (...)}.

@item
Use @code{x = ANY (table containing (1,2))} rather than
@code{x=1 OR x=2}.

@item
Use @code{= ANY} rather than @code{EXISTS}.
@end itemize

These tricks might cause programs to go faster or slower. Using MySQL
facilities like the @code{BENCHMARK()} function, you can get an idea about
what helps in your own situation. Don't worry too much about transforming
to joins except for compatibility with older versions of MySQL before 4.1
that do not support subqueries.

Some optimizations that MySQL itself makes are:

@itemize @bullet
@item
MySQL executes non-correlated subqueries only once. Use @code{EXPLAIN}
to make sure that a given subquery really is non-correlated.

@item
MySQL rewrites @code{IN}/@code{ALL}/@code{ANY}/@code{SOME} subqueries
in an attempt to take advantage of the possibility that the select-list
columns in the subquery are indexed.

@c TODO: what join type is this?

@item
MySQL replaces subqueries of the following form
with an index-lookup function, which @code{EXPLAIN} will describe as a
special join type:

@example
... IN (SELECT @var{indexed_column} FROM @var{single_table} ...)
@end example

@item
MySQL enhances expressions of the following form
with an expression involving @code{MIN()} or @code{MAX()}, unless @code{NULL}
values or empty sets are involved:

@example
value @{ALL|ANY|SOME@} @{> | < | >= | <=@} (non-correlated subquery)
@end example

For example, this @code{WHERE} clause:

@example
WHERE 5 > ALL (SELECT x FROM t)
@end example

might be treated by the optimizer like this:

@example
WHERE 5 > (SELECT MAX(x) FROM t)
@end example

@end itemize

There is a chapter titled ``How MySQL Transforms Subqueries''
in the MySQL Internals Manual. You can obtain this document by downloading the
MySQL source package and looking for a file named @file{internals.texi} in the
@file{Docs} directory.


@node Rewriting subqueries,  , Optimizing subqueries, Subqueries
@subsubsection Rewriting Subqueries as Joins for Earlier MySQL Versions

Before MySQL 4.1, only nested queries of the form
@code{INSERT ... SELECT ...} and @code{REPLACE ... SELECT ...}
are supported.
The @code{IN()} construct can be used in other contexts to test membership in
a set of values.

It is often possible to rewrite a query without a subquery:

@example
SELECT * FROM t1 WHERE id IN (SELECT id FROM t2);
@end example

This can be rewritten as:

@example
SELECT DISTINCT t1.* FROM t1, t2 WHERE t1.id=t2.id;
@end example

The queries:
@example
SELECT * FROM t1 WHERE id NOT IN (SELECT id FROM t2);
SELECT * FROM t1 WHERE NOT EXISTS (SELECT id FROM t2 WHERE t1.id=t2.id);
@end example

Can be rewritten as:

@example
SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id
                                       WHERE table2.id IS NULL;
@end example

A @code{LEFT [OUTER] JOIN} can be faster than an equivalent subquery
because the server might be able to optimize it better---a fact that is
not specific to MySQL Server alone.
Prior to SQL-92, outer joins did not exist, so subqueries were the only way
to do certain things in those bygone days. Today, MySQL Server and many
other modern database systems offer a whole range of outer join types.

For more complicated subqueries, you can often create temporary tables
to hold the subquery.  In some cases, however, this option will not
work. The most frequently encountered of these cases arises with
@code{DELETE} statements, for which standard SQL does not support joins
(except in subqueries).  For this situation, there are three options
available:

@itemize @bullet
@item
The first option is to upgrade to MySQL 4.1, which does support
subqueries in @code{DELETE} statements.

@item
The second option is to use a procedural programming language (such as
Perl or PHP) to submit a @code{SELECT} query to obtain the primary keys
for the records to be deleted, and then use these values to construct
the @code{DELETE} statement (@code{DELETE FROM ... WHERE key_col IN (key1,
key2, ...)}).

@item
The third option is to use interactive SQL to construct a set of
@code{DELETE} statements automatically, using the MySQL
extension @code{CONCAT()} (in lieu of the standard @code{||} operator).
For example:

@example
SELECT
  CONCAT('DELETE FROM tab1 WHERE pkid = ', "'", tab1.pkid, "'", ';')
  FROM tab1, tab2
 WHERE tab1.col1 = tab2.col2;
@end example

You can place this query in a script file, use the file as input to one
instance of the @command{mysql} program, and use the program output
as input to a second instance of @command{mysql}:

@example
shell> mysql --skip-column-names mydb < myscript.sql | mysql mydb
@end example
@end itemize

MySQL Server 4.0 supports multiple-table @code{DELETE} statements that can be used to
efficiently delete rows based on information from one table or even
from many tables at the same time.
Multiple-table @code{UPDATE} statements are also supported as of MySQL 4.0.


@node TRUNCATE, UPDATE, Subqueries, Data Manipulation
@subsection @code{TRUNCATE} Syntax

@findex TRUNCATE

@c example_for_help_topic TRUNCATE TABLE
@example
TRUNCATE TABLE @var{tbl_name}
@end example

@c description_for_help_topic TRUNCATE TABLE
@code{TRUNCATE TABLE} empties a table completely.
Logically, this is equivalent to a @code{DELETE} statement that deletes all
rows, but there are practical differences under some circumstances.

For @code{InnoDB}, @code{TRUNCATE TABLE} is mapped to
@code{DELETE}, so there is no difference. For other storage engines,
@code{TRUNCATE TABLE} differs from @code{DELETE FROM ...}
in the following ways from MySQL 4.0 and up:

@itemize @bullet
@item
Truncate operations drop and re-create the table, which is much faster
than deleting rows one by one.
@item
Truncate operations are not transaction-safe; you will get an error if
you have an active transaction or an active table lock.
@item
The number of deleted rows is not returned.
@item
As long as the table definition file @file{@var{tbl_name}.frm} is
valid, the table can be re-created as an empty table with @code{TRUNCATE
TABLE}, even if the data or index files have become corrupted.
@item
The table handler does not remember the last used @code{AUTO_INCREMENT}
value, but starts counting from the beginning.  This is true even for
@code{MyISAM}, which normally does not reuse sequence values.
@end itemize

In MySQL 3.23, @code{TRUNCATE TABLE} is mapped to
@code{COMMIT; DELETE FROM @var{tbl_name}}, so it behaves like @code{DELETE}.
@xref{DELETE,  , @code{DELETE}}.

@code{TRUNCATE TABLE} is an Oracle SQL extension.
This statement was added in MySQL 3.23.28, although from 3.23.28
to 3.23.32, the keyword @code{TABLE} must be omitted.
@c end_description_for_help_topic


@node UPDATE,  , TRUNCATE, Data Manipulation
@subsection @code{UPDATE} Syntax

@findex UPDATE

@c example_for_help_topic UPDATE
Single-table syntax:
@example
UPDATE [LOW_PRIORITY] [IGNORE] @var{tbl_name}
    SET @var{col_name1}=@var{expr1} [, @var{col_name2}=@var{expr2} ...]
    [WHERE @var{where_definition}]
    [ORDER BY ...]
    [LIMIT @var{row_count}]
@end example

Multiple-table syntax:

@example
UPDATE [LOW_PRIORITY] [IGNORE] @var{tbl_name} [, @var{tbl_name} ...]
    SET @var{col_name1}=@var{expr1} [, @var{col_name2}=@var{expr2} ...]
    [WHERE @var{where_definition}]
@end example

@c description_for_help_topic UPDATE  BY LOW_PRIORITY IGNORE SET ORDER LIMIT WHERE
The @code{UPDATE} statement updates columns in existing table rows with
new values.  The @code{SET} clause indicates which columns to modify
and the values they should be given.  The @code{WHERE} clause, if given,
specifies which rows should be updated.  Otherwise, all rows are updated. If
the @code{ORDER BY} clause is specified, the rows will be updated in the
order that is specified. The @code{LIMIT} clause places a limit on the
number of rows that can be updated.

The @code{UPDATE} statement supports the following modifiers:

@itemize @bullet

@item
If you specify the @code{LOW_PRIORITY} keyword, execution of the
@code{UPDATE} is delayed until no other clients are reading from the table.

@item
If you specify the @code{IGNORE} keyword, the update statement will not
abort even if errors occur during the update.  Rows for which duplicate-key
conflicts occur are not updated. Rows for which columns are updated to
values that would cause data conversion errors are updated to the closet
valid values instead.
@c end_description_for_help_topic

@end itemize

If you access a column from @var{tbl_name} in an expression,
@code{UPDATE} uses the current value of the column.  For example, the
following statement sets the @code{age} column to one more than its
current value:

@example
mysql> UPDATE persondata SET age=age+1;
@end example

@code{UPDATE} assignments are evaluated from left to right.  For example, the
following statement doubles the @code{age} column, then increments it:

@example
mysql> UPDATE persondata SET age=age*2, age=age+1;
@end example

If you set a column to the value it currently has, MySQL notices
this and doesn't update it.

If you update a column that has been declared @code{NOT NULL} by
setting to @code{NULL}, the column is set to the default value appropriate
for the column type and the warning count is incremented.  The default
value is @code{0} for numeric types, the empty string (@code{''})
for string types, and the ``zero'' value for date and time types.

@findex mysql_info()
@code{UPDATE} returns the number of rows that were actually changed.
In MySQL 3.22 or later, the @code{mysql_info()} C API function
returns the number of rows that were matched and updated and the number of
warnings that occurred during the @code{UPDATE}.

Starting from MySQL 3.23, you can use @code{LIMIT @var{row_count}} to
restrict the scope of the @code{UPDATE}. A @code{LIMIT} clause works as
follows:

@itemize @bullet
@item
Before MySQL 4.0.13, @code{LIMIT} is a rows-affected restriction.
The statement stops as soon as it has changed @var{row_count} rows that
satisfy the @code{WHERE} clause.

@item
From 4.0.13 on, @code{LIMIT} is a rows-matched restriction.  The statement
stops as soon as it has found @var{row_count} rows that satisfy the
@code{WHERE} clause, whether or not they actually were changed.

@end itemize

If an @code{UPDATE} statement includes an @code{ORDER BY} clause, the rows
are updated in the order specified by the clause.
@code{ORDER BY} can be used from MySQL 4.0.0.

Starting with MySQL 4.0.4, you can also perform @code{UPDATE}
operations that cover multiple tables:

@example
UPDATE items,month SET items.price=month.price
WHERE items.id=month.id;
@end example

The example shows an inner join using the comma operator, but
multiple-table @code{UPDATE} statements can use any type of
join allowed in @code{SELECT} statements, such as @code{LEFT JOIN}.

Note: You cannot use @code{ORDER BY} or @code{LIMIT} with multiple-table
@code{UPDATE}.

Before MySQL 4.0.18, you need the @code{UPDATE} privilege for all
tables used in a multiple-table @code{UPDATE}, even if they were not
updated.  As of MySQL 4.0.18, you need only the @code{SELECT} privilege for
any columns that are read but not modified.

If you use a multiple-table @code{UPDATE} statement involving
@code{InnoDB} tables for which there are foreign key constraints,
the MySQL optimizer might process tables in an order that differs from
that of their parent/child relationship. In this case, the statement will
fail and roll back. Instead, update a single table and rely on the
@code{ON UPDATE} capabilities that @code{InnoDB} provides to cause the
other tables to be modified accordingly.

Currently, you cannot update a table and select from the same table in a
subquery.


@node Data Definition, Basic User Commands, Data Manipulation, SQL Syntax
@section Data Definition Statements
@c help_category Data Definition
@menu
* ALTER DATABASE::              @code{ALTER DATABASE} Syntax
* ALTER TABLE::                 @code{ALTER TABLE} Syntax
* ALTER VIEW::                  @code{ALTER VIEW} Syntax
* CREATE DATABASE::             @code{CREATE DATABASE} Syntax
* CREATE INDEX::                @code{CREATE INDEX} Syntax
* CREATE TABLE::                @code{CREATE TABLE} Syntax
* CREATE VIEW::                 @code{CREATE VIEW} Syntax
* DROP DATABASE::               @code{DROP DATABASE} Syntax
* DROP INDEX::                  @code{DROP INDEX} Syntax
* DROP TABLE::                  @code{DROP TABLE} Syntax
* DROP VIEW::                   @code{DROP VIEW} Syntax
* RENAME TABLE::                @code{RENAME TABLE} Syntax
@end menu


@node ALTER DATABASE, ALTER TABLE, Data Definition, Data Definition
@subsection @code{ALTER DATABASE} Syntax

@findex ALTER DATABASE
@findex ALTER SCHEMA
@cindex altering, database
@cindex database, altering
@cindex altering, schema
@cindex schema, altering

@c example_for_help_topic ALTER DATABASE
@example
ALTER @{DATABASE | SCHEMA@} [@var{db_name}]
    @var{alter_specification} [, @var{alter_specification}] ...

@var{alter_specification}:
    [DEFAULT] CHARACTER SET @var{charset_name}
  | [DEFAULT] COLLATE @var{collation_name}
@end example

@c description_for_help_topic ALTER DATABASE  CHARACTER SET SCHEMA

@code{ALTER DATABASE} allows you to change the overall characteristics of a
database.  These characteristics are stored in the @file{db.opt} file in the
database directory.
To use @code{ALTER DATABASE}, you need the @code{ALTER} privilege on the
database.
@c end_description_for_help_topic

The @code{CHARACTER SET} clause changes the default database character set.
The @code{COLLATE} clause changes the default database collation.
Character set and collation names are discussed in
@ref{Charset}.

@c It's really 4.1.0, but with a different syntax than in 4.1.1.
@c (COLLATE is not supported.)
@code{ALTER DATABASE} was added in MySQL 4.1.1.
Beginning with MySQL 4.1.8, the database name can be omitted.
The statement applies to the default database in this case.
@code{ALTER SCHEMA} can be used as of MySQL 5.0.2.

@node ALTER TABLE, ALTER VIEW, ALTER DATABASE, Data Definition
@subsection @code{ALTER TABLE} Syntax

@findex ALTER TABLE
@cindex changing, table
@cindex table, changing

@c example_for_help_topic ALTER TABLE
@example
ALTER [IGNORE] TABLE @var{tbl_name}
    @var{alter_specification} [, @var{alter_specification}] ...

@var{alter_specification}:
    ADD [COLUMN] @var{column_definition} [FIRST | AFTER @var{col_name} ]
  | ADD [COLUMN] (@var{column_definition},...)
  | ADD INDEX [@var{index_name}] [@var{index_type}] (@var{index_col_name},...)
  | ADD [CONSTRAINT [@var{symbol}]]
        PRIMARY KEY [@var{index_type}] (@var{index_col_name},...)
  | ADD [CONSTRAINT [@var{symbol}]]
        UNIQUE [@var{index_name}] [@var{index_type}] (@var{index_col_name},...)
  | ADD [FULLTEXT|SPATIAL] [@var{index_name}] (@var{index_col_name},...)
  | ADD [CONSTRAINT [@var{symbol}]]
        FOREIGN KEY [@var{index_name}] (@var{index_col_name},...)
        [@var{reference_definition}]
  | ALTER [COLUMN] @var{col_name} @{SET DEFAULT @var{literal} | DROP DEFAULT@}
  | CHANGE [COLUMN] @var{old_col_name} @var{column_definition}
        [FIRST|AFTER @var{col_name}]
  | MODIFY [COLUMN] @var{column_definition} [FIRST | AFTER @var{col_name}]
  | DROP [COLUMN] @var{col_name}
  | DROP PRIMARY KEY
  | DROP INDEX @var{index_name}
  | DROP FOREIGN KEY @var{fk_symbol}
  | DISABLE KEYS
  | ENABLE KEYS
  | RENAME [TO] @var{new_tbl_name}
  | ORDER BY @var{col_name}
  | CONVERT TO CHARACTER SET @var{charset_name} [COLLATE @var{collation_name}]
  | [DEFAULT] CHARACTER SET @var{charset_name} [COLLATE @var{collation_name}]
  | DISCARD TABLESPACE
  | IMPORT TABLESPACE
  | @var{table_options}
@end example

@c description_for_help_topic ALTER TABLE  ADD ALTER AFTER AVG_ROW_LENGTH BY COLUMN FIRST INDEX PRIMARY KEY KEYS UNIQUE FULLTEXT SPATIAL CONSTRAINT DROP DISABLE ENABLE RENAME ORDER MODIFY CHANGE DEFAULT SET FOREIGN IGNORE ENGINE TYPE
@code{ALTER TABLE} allows you to change the structure of an existing table.
For example, you can add or delete columns, create or destroy indexes, change
the type of existing columns, or rename columns or the table itself.  You can
also change the comment for the table and type of the table.
@c end_description_for_help_topic

The syntax for many of the allowable alterations is similar to clauses of the
@code{CREATE TABLE} statement.
@xref{CREATE TABLE, , @code{CREATE TABLE}}.

Some operations may result in warnings if attempted on a table for which
the storage engine does not support the operation. In MySQL 4.1 and up,
these warnings can be displayed with @code{SHOW WARNINGS}.
@xref{SHOW WARNINGS,  , @code{SHOW WARNINGS}}.

If you use @code{ALTER TABLE} to change a column specification but
@code{DESCRIBE @var{tbl_name}} indicates that your column was not changed, it is
possible that MySQL ignored your modification for one of the reasons
described in @ref{Silent column changes}.  For example, if you try to change
a @code{VARCHAR} column to @code{CHAR}, MySQL will still use
@code{VARCHAR} if the table contains other variable-length columns.

@code{ALTER TABLE} works by making a temporary copy of the original table.
The alteration is performed on the copy, then the original table is deleted
and the new one is renamed.  While @code{ALTER TABLE} is executing, the
original table is readable by other clients. Updates and writes to the
table are stalled until the new table is ready, then are automatically
redirected to the new table without any failed updates.

Note that if you use any other option to @code{ALTER TABLE} than
@code{RENAME}, MySQL always creates a temporary table, even if the data
wouldn't strictly need to be copied (such as when you change the name of a
column). We plan to fix this in the future, but because @code{ALTER TABLE}
is not a statement that is normally used frequently, this isn't high on our
TODO list.  For @code{MyISAM} tables, you can speed up the index re-creation
operation (which is the slowest part of the alteration process) by setting
the @code{myisam_sort_buffer_size} system variable to a high value.

@itemize @bullet
@item
To use @code{ALTER TABLE}, you need @code{ALTER}, @code{INSERT},
and @code{CREATE} privileges for the table.

@item
@code{IGNORE} is a MySQL extension to standard SQL.
It controls how @code{ALTER TABLE} works if there are duplicates on
unique keys in the new table.
If @code{IGNORE} isn't specified, the copy is aborted and rolled back if
duplicate-key errors occur.
If @code{IGNORE} is specified, then for rows with duplicates on a unique
key, only the first row is used. The others are deleted.

@item
You can issue multiple @code{ADD}, @code{ALTER}, @code{DROP}, and
@code{CHANGE} clauses in a single @code{ALTER TABLE} statement. This is a
MySQL extension to standard SQL, which allows only one of each clause
per @code{ALTER TABLE} statement. For example, to drop multiple columns in a single statement: 

@example
mysql> ALTER TABLE t2 DROP COLUMN c, DROP COLUMN d;
@end example

@item
@code{CHANGE @var{col_name}}, @code{DROP @var{col_name}}, and @code{DROP
INDEX} are MySQL extensions to standard SQL.

@item
@code{MODIFY} is an Oracle extension to @code{ALTER TABLE}.

@item
The word @code{COLUMN} is purely optional and can be omitted.

@item
If you use @code{ALTER TABLE @var{tbl_name} RENAME TO @var{new_tbl_name}} without any other
options, MySQL simply renames any files that correspond to the table
@var{tbl_name}.  There is no need to create a temporary table.
(You can also use the @code{RENAME TABLE} statement to rename tables.
@xref{RENAME TABLE,, @code{RENAME TABLE}}.)

@item
@var{column_definition} clauses use the same syntax for @code{ADD} and
@code{CHANGE} as for @code{CREATE TABLE}.  Note that this syntax includes
the column name, not just the column type.
@xref{CREATE TABLE, , @code{CREATE TABLE}}.

@item
You can rename a column using a @code{CHANGE @var{old_col_name} @var{column_definition}}
clause.  To do so, specify the old and new column names and the type that
the column currently has.  For example, to rename an @code{INTEGER} column
from @code{a} to @code{b}, you can do this:

@example
mysql> ALTER TABLE t1 CHANGE a b INTEGER;
@end example

If you want to change a column's type but not the name, @code{CHANGE}
syntax still requires an old and new column name, even if they are the same.
For example:

@example
mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
@end example

However, as of MySQL 3.22.16a, you can also use @code{MODIFY}
to change a column's type without renaming it:

@example
mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
@end example

@item
If you use @code{CHANGE} or @code{MODIFY} to shorten a column for which
an index exists on part of the column (for example, if you have an index
on the first 10 characters of a @code{VARCHAR} column), you cannot make
the column shorter than the number of characters that are indexed.

@item
When you change a column type using @code{CHANGE} or @code{MODIFY}, MySQL
tries to convert existing column values to the new type as well as possible.

@item
In MySQL 3.22 or later, you can use @code{FIRST} or
@code{AFTER @var{col_name}} to add a column at a specific position
within a table row. The default is to add the column last.
From MySQL 4.0.1 on, you can also use @code{FIRST} and
@code{AFTER} in @code{CHANGE} or @code{MODIFY} operations.

@findex ALTER COLUMN
@cindex changing, column
@cindex column, changing
@cindex changing, field
@cindex field, changing
@item
@code{ALTER COLUMN} specifies a new default value for a column
or removes the old default value.
If the old default is removed and the column can be @code{NULL}, the new
default is @code{NULL}. If the column cannot be @code{NULL}, MySQL
assigns a default value, as described in
@ref{CREATE TABLE, , @code{CREATE TABLE}}.

@findex DROP INDEX
@cindex deleting, index
@cindex index, deleting
@item
@code{DROP INDEX} removes an index. This is a MySQL extension to
standard SQL. @xref{DROP INDEX,  , @code{DROP INDEX}}.

@item
If columns are dropped from a table, the columns are also removed from any
index of which they are a part.  If all columns that make up an index are
dropped, the index is dropped as well.

@item
If a table contains only one column, the column cannot be dropped.
If what you intend is to remove the table, use @code{DROP TABLE} instead.

@item
@findex DROP PRIMARY KEY
@cindex deleting, primary key
@cindex primary key, deleting
@code{DROP PRIMARY KEY} drops the primary index. (Prior to MySQL 4.1.2,
if no primary index exists, @code{DROP PRIMARY KEY} drops the first
@code{UNIQUE} index in the table.
MySQL marks the first @code{UNIQUE} key as the @code{PRIMARY KEY}
if no @code{PRIMARY KEY} was specified explicitly.)

@findex UNIQUE
@findex PRIMARY KEY
If you add a @code{UNIQUE INDEX} or @code{PRIMARY KEY} to a table, it
is stored before any non-unique index so that MySQL can detect
duplicate keys as early as possible.

@findex ORDER BY
@item
@code{ORDER BY} allows you to create the new table with the rows in a
specific order.  Note that the table will not remain in this order after
inserts and deletes.  This option is mainly useful when you know that you
are mostly going to query the rows in a certain order; by using this option
after big changes to the table, you might be able to get higher performance.
In some cases, it might make sorting easier for MySQL if the table is in
order by the column that you want to order it by later.

@findex ALTER TABLE
@cindex changing, table
@cindex table, changing
@item
If you use @code{ALTER TABLE} on a @code{MyISAM} table, all non-unique
indexes are created in a separate batch (as for @code{REPAIR TABLE}).
This should make @code{ALTER TABLE} much faster when you have many indexes.

As of MySQL 4.0, this feature can be activated explicitly.  @code{ALTER
TABLE ... DISABLE KEYS} tells MySQL to stop updating non-unique indexes for a
@code{MyISAM} table.  @code{ALTER TABLE ... ENABLE KEYS} then should be used
to re-create missing indexes. MySQL does this with a special algorithm that
is much faster than inserting keys one by one, so disabling keys before
performing bulk insert operations should give a considerable speedup. Using 
@code{ALTER TABLE ... DISABLE KEYS} will require the @code{INDEX} privilege
in addition to the privileges mentioned earlier.

@item
@cindex foreign keys
@cindex references
The @code{FOREIGN KEY} and @code{REFERENCES} clauses are supported by the
@code{InnoDB} storage engine, which implements
@code{ADD [CONSTRAINT [@var{symbol}]] FOREIGN KEY (...) REFERENCES ... (...)}.
@xref{InnoDB foreign key constraints,  , @code{InnoDB} foreign key constraints}.
For other storage engines, the clauses are parsed but ignored.
The @code{CHECK} clause is parsed but ignored by all storage engines.
@xref{CREATE TABLE,  , @code{CREATE TABLE}}.
The reason for accepting but ignoring syntax clauses is for compatibility,
to make it easier to port code from other SQL servers, and to run applications
that create tables with references.
@xref{Differences from ANSI}.

@item
@findex DROP FOREIGN KEY
@cindex deleting, foreign key
@cindex foreign key, deleting
Starting from MySQL 4.0.13, @code{InnoDB} supports the use of @code{ALTER
TABLE} to drop foreign keys:

@example
ALTER TABLE @var{yourtablename} DROP FOREIGN KEY @var{fk_symbol};
@end example

For more information, see
@ref{InnoDB foreign key constraints,  , @code{InnoDB} foreign key constraints}.

@item
@code{ALTER TABLE} ignores the @code{DATA DIRECTORY} and @code{INDEX
DIRECTORY} table options.

@item
@findex CONVERT TO
From MySQL 4.1.2 on,
if you want to change all character columns (@code{CHAR}, @code{VARCHAR},
@code{TEXT}) to a new character set, use a statement like this:

@example
ALTER TABLE @var{tbl_name} CONVERT TO CHARACTER SET @var{charset_name};
@end example

This is useful, for example, after upgrading from MySQL 4.0.x to 4.1.x.
@xref{Charset-upgrading}.

@strong{Warning:} The preceding operation will convert column values between
the character sets. This is @emph{not} what you want if you have a column in
one character set (like @code{latin1}) but the stored values actually use
some other, incompatible character set (like @code{utf8}). In this case,
you have to do the following for each such column:

@example
ALTER TABLE t1 CHANGE c1 c1 BLOB;
ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;
@end example

The reason this works is that there is no conversion when you convert
to or from @code{BLOB} columns.

To change only the @emph{default} character set for a table, use this
statement:

@example
ALTER TABLE @var{tbl_name} DEFAULT CHARACTER SET @var{charset_name};
@end example

The word @code{DEFAULT} is optional.
The default character set is the character set that is used if
you don't specify the character set for a new column you add to a table
(for example, with @code{ALTER TABLE ... ADD column}).

@strong{Warning:} From MySQL 4.1.2 and up, @code{ALTER TABLE ... DEFAULT
CHARACTER SET} and @code{ALTER TABLE ... CHARACTER SET} are equivalent and
change only the default table character set. In MySQL 4.1 releases before
4.1.2, @code{ALTER TABLE ...  DEFAULT CHARACTER SET} changes the default
character set, but @code{ALTER TABLE ...  CHARACTER SET} (without
@code{DEFAULT}) changes the default character set @emph{and also} converts
all columns to the new character set.


@item
@findex DISCARD TABLESPACE
@findex IMPORT TABLESPACE
For an @code{InnoDB} table that is created with its own tablespace in an
@file{.ibd} file, that file can be discarded and imported. To discard the
@file{.ibd} file, use this statement:

@example
ALTER TABLE @var{tbl_name} DISCARD TABLESPACE;
@end example

This deletes the current @file{.ibd} file, so be sure that you have a backup
first. Attempting to access the table while the tablespace file is discarded
results in an error.

To import the backup @file{.ibd} file back into the table, copy it into the
database directory, then issue this statement:

@example
ALTER TABLE @var{tbl_name} IMPORT TABLESPACE;
@end example

@xref{Multiple tablespaces}.

@item
@findex mysql_info()
With the @code{mysql_info()} C API function, you can find out how many
records were copied, and (when @code{IGNORE} is used) how many records were
deleted due to duplication of unique key values.
@xref{mysql_info,  , @code{mysql_info()}}.

@end itemize

Here are some examples that show uses of @code{ALTER TABLE}.
Begin with a table @code{t1} that is created as shown here:

@example
mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10));
@end example

To rename the table from @code{t1} to @code{t2}:

@example
mysql> ALTER TABLE t1 RENAME t2;
@end example

To change column @code{a} from @code{INTEGER} to @code{TINYINT NOT NULL}
(leaving the name the same), and to change column @code{b} from
@code{CHAR(10)} to @code{CHAR(20)} as well as renaming it from @code{b} to
@code{c}:

@example
mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);
@end example

To add a new @code{TIMESTAMP} column named @code{d}:

@example
mysql> ALTER TABLE t2 ADD d TIMESTAMP;
@end example

To add indexes on column @code{d} and on column @code{a}:

@example
mysql> ALTER TABLE t2 ADD INDEX (d), ADD INDEX (a);
@end example

To remove column @code{c}:

@example
mysql> ALTER TABLE t2 DROP COLUMN c;
@end example

To add a new @code{AUTO_INCREMENT} integer column named @code{c}:

@example
mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT,
    ->     ADD PRIMARY KEY (c);
@end example

Note that we indexed @code{c} (as a @code{PRIMARY KEY}), because
@code{AUTO_INCREMENT} columns must be indexed, and also that we declare
@code{c} as @code{NOT NULL}, because primary key columns cannot be
@code{NULL}.

When you add an @code{AUTO_INCREMENT} column, column values are filled in
with sequence numbers for you automatically.  For @code{MyISAM} tables,
you can set the first
sequence number by executing @code{SET INSERT_ID=@var{value}} before
@code{ALTER TABLE} or by using the @code{AUTO_INCREMENT=@var{value}} table option.
@xref{SET OPTION,  , @code{SET OPTION}}.

From MySQL 5.0.3, you can use the @code{ALTER TABLE ...
AUTO_INCREMENT=@var{value}} table option for @code{InnoDB} tables
to set the sequence number for new rows if the value is greater than the
maximum value in the @code{AUTO_INCREMENT} column.  If the value is less
than the maximum column value, no error message is given and the current
sequence value is not changed.

With @code{MyISAM} tables, if you don't change the @code{AUTO_INCREMENT}
column, the sequence number will not be affected. If you drop an
@code{AUTO_INCREMENT} column and then add another @code{AUTO_INCREMENT}
column, the numbers are resequenced beginning with 1.

@xref{ALTER TABLE problems,  , @code{ALTER TABLE} problems}.


@node ALTER VIEW, CREATE DATABASE, ALTER TABLE, Data Definition
@subsection @code{ALTER VIEW} Syntax

@findex ALTER VIEW

@c example_for_help_topic ALTER VIEW
@example
ALTER [ALGORITHM = @{UNDEFINED | MERGE | TEMPTABLE@}]
    VIEW @var{view_name} [(@var{column_list})]
    AS @var{select_statement}
    [WITH [CASCADED | LOCAL] CHECK OPTION]
@end example

@c description_for_help_topic ALTER VIEW  ALTER VIEW
This statement changes the definition of an existing view.
The syntax is similar to that for @code{CREATE VIEW}.
@xref{CREATE VIEW,  , @code{CREATE VIEW}}.
@c end_description_for_help_topic

This statement was added in MySQL 5.0.1.


@node CREATE DATABASE, CREATE INDEX, ALTER VIEW, Data Definition
@subsection @code{CREATE DATABASE} Syntax

@findex CREATE DATABASE
@findex CREATE SCHEMA
@cindex creating, database
@cindex database, creating
@cindex creating, schema
@cindex schema, creating

@c example_for_help_topic CREATE DATABASE
@example
CREATE @{DATABASE | SCHEMA@} [IF NOT EXISTS] @var{db_name}
    [@var{create_specification} [, @var{create_specification}] ...]

@var{create_specification}:
    [DEFAULT] CHARACTER SET @var{charset_name}
  | [DEFAULT] COLLATE @var{collation_name}
@end example

@c description_for_help_topic CREATE DATABASE  CREATE DATABASE SCHEMA IF EXISTS NOT
@code{CREATE DATABASE} creates a database with the given name.  
To use @code{CREATE DATABASE}, you need the @code{CREATE} privilege on the
database.
@c end_description_for_help_topic

Rules for
allowable database names are given in @ref{Legal names}.  An error occurs if
the database already exists and you didn't specify @code{IF NOT EXISTS}.

As of MySQL 4.1.1, @code{create_specification} options can be given to
specify database characteristics.  Database characteristics are stored in
the @file{db.opt} file in the database directory.  The @code{CHARACTER SET}
clause specifies the default database character set.  The @code{COLLATE}
clause specifies the default database collation.  Character set and
collation names are discussed in @ref{Charset}.

Databases in MySQL are implemented as directories containing files
that correspond to tables in the database.  Because there are no tables in a
database when it is initially created, the @code{CREATE DATABASE} statement
only creates a directory under the MySQL data directory (and the @file{db.opt}
file, for MySQL 4.1.1 and up).

@code{CREATE SCHEMA} can be used as of MySQL 5.0.2.

@cindex @command{mysqladmin}
You can also use the @command{mysqladmin} program to create databases.
@xref{mysqladmin,  , @command{mysqladmin}}.


@node CREATE INDEX, CREATE TABLE, CREATE DATABASE, Data Definition
@subsection @code{CREATE INDEX} Syntax

@findex CREATE INDEX

@cindex indexes
@cindex indexes, multiple-part
@cindex multiple-part index

@c example_for_help_topic CREATE INDEX
@example
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX @var{index_name} [@var{index_type}]
    ON @var{tbl_name} (@var{index_col_name},...)

@var{index_col_name}:
    @var{col_name} [(@var{length})] [ASC | DESC]
@end example

@c description_for_help_topic CREATE INDEX  BTREE RTREE INDEX CREATE FULLTEXT SPATIAL
In MySQL 3.22 or later, @code{CREATE INDEX} is mapped to an
@code{ALTER TABLE} statement to create indexes.
@xref{ALTER TABLE, , @code{ALTER TABLE}}.
The @code{CREATE INDEX} statement doesn't do anything prior
to MySQL 3.22.
@c end_description_for_help_topic

Normally, you create all indexes on a table at the time the table itself
is created with @code{CREATE TABLE}.
@xref{CREATE TABLE, , @code{CREATE TABLE}}.
@code{CREATE INDEX} allows you to add indexes to existing tables.

A column list of the form @code{(col1,col2,...)} creates a multiple-column
index.  Index values are formed by concatenating the values of the given
columns.

For @code{CHAR} and @code{VARCHAR} columns, indexes can be created that
use only part of a column, using @code{@var{col_name}(@var{length})} syntax to index
a prefix consisting of the first @var{length} characters of each column
value. @code{BLOB} and @code{TEXT} columns also can be indexed, but a prefix
length @emph{must} be given.

The statement shown here creates an index using the first 10 characters
of the @code{name} column:

@example
CREATE INDEX part_of_name ON customer (name(10));
@end example

Because most names usually differ in the first 10 characters, this index should
not be much slower than an index created from the entire @code{name} column.
Also, using partial columns for indexes can make the index file much smaller,
which could save a lot of disk space and might also speed up @code{INSERT}
operations!

Prefixes can be up to 255 bytes long (or 1000 bytes for @code{MyISAM}
and @code{InnoDB} tables as of MySQL 4.1.2).  Note that prefix limits
are measured in bytes, whereas the prefix length in @code{CREATE INDEX}
statements is interpreted as number of characters.  Take this into account
when specifying a prefix length for a column that uses a multi-byte
character set.

Note that you can add an index on a column that can have @code{NULL}
values only if you are using MySQL 3.23.2 or newer and are using the
@code{MyISAM}, @code{InnoDB}, or @code{BDB} table type.  You can only add an
index on a @code{BLOB} or @code{TEXT} column if you are using
MySQL 3.23.2 or newer and are using the @code{MyISAM} or @code{BDB}
table type, or MySQL 4.0.14 or newer and the @code{InnoDB} table type.

An @var{index_col_name} specification can end with @code{ASC} or @code{DESC}.
These keywords are allowed for future extensions for specifying ascending
or descending index value storage.  Currently they are parsed but ignored;
index values are always stored in ascending order.

For more information about how MySQL uses indexes, see
@ref{MySQL indexes, , MySQL indexes}.

@code{FULLTEXT} indexes can index only @code{CHAR}, @code{VARCHAR}, and
@code{TEXT} columns, and only in @code{MyISAM} tables. @code{FULLTEXT} indexes
are available in MySQL 3.23.23 or later.
@ref{Fulltext Search}.

@code{SPATIAL} indexes can index only spatial columns,
and only in @code{MyISAM} tables. @code{SPATIAL} indexes
are available in MySQL 4.1 or later. Spatial column types are described in
@ref{Spatial extensions in MySQL}.


@node CREATE TABLE, CREATE VIEW, CREATE INDEX, Data Definition
@subsection @code{CREATE TABLE} Syntax

@findex CREATE TABLE

@menu
* Silent column changes::       Silent Column Specification Changes
@end menu

@c example_for_help_topic CREATE TABLE
@example
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] @var{tbl_name}
    [(@var{create_definition},...)]
    [@var{table_options}] [@var{select_statement}]
@end example

Or:

@example
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] @var{tbl_name}
    [(] LIKE @var{old_tbl_name} [)];

@var{create_definition}:
    @var{column_definition}
  | [CONSTRAINT [@var{symbol}]] PRIMARY KEY [@var{index_type}] (@var{index_col_name},...)
  | KEY [@var{index_name}] [@var{index_type}] (@var{index_col_name},...)
  | INDEX [@var{index_name}] [@var{index_type}] (@var{index_col_name},...)
  | [CONSTRAINT [@var{symbol}]] UNIQUE [INDEX]
        [@var{index_name}] [@var{index_type}] (@var{index_col_name},...)
  | [FULLTEXT|SPATIAL] [INDEX] [@var{index_name}] (@var{index_col_name},...)
  | [CONSTRAINT [@var{symbol}]] FOREIGN KEY
        [@var{index_name}] (@var{index_col_name},...) [@var{reference_definition}]
  | CHECK (@var{expr})

@var{column_definition}:
    @var{col_name} @var{type} [NOT NULL | NULL] [DEFAULT @var{default_value}]
        [AUTO_INCREMENT] [[PRIMARY] KEY] [COMMENT '@var{string}']
        [@var{reference_definition}]

@var{type}:
    TINYINT[(@var{length})] [UNSIGNED] [ZEROFILL]
  | SMALLINT[(@var{length})] [UNSIGNED] [ZEROFILL]
  | MEDIUMINT[(@var{length})] [UNSIGNED] [ZEROFILL]
  | INT[(@var{length})] [UNSIGNED] [ZEROFILL]
  | INTEGER[(@var{length})] [UNSIGNED] [ZEROFILL]
  | BIGINT[(@var{length})] [UNSIGNED] [ZEROFILL]
  | REAL[(@var{length},@var{decimals})] [UNSIGNED] [ZEROFILL]
  | DOUBLE[(@var{length},@var{decimals})] [UNSIGNED] [ZEROFILL]
  | FLOAT[(@var{length},@var{decimals})] [UNSIGNED] [ZEROFILL]
  | DECIMAL(@var{length},@var{decimals}) [UNSIGNED] [ZEROFILL]
  | NUMERIC(@var{length},@var{decimals}) [UNSIGNED] [ZEROFILL]
  | DATE
  | TIME
  | TIMESTAMP
  | DATETIME
  | CHAR(@var{length}) [BINARY | ASCII | UNICODE]
  | VARCHAR(@var{length}) [BINARY]
  | TINYBLOB
  | BLOB
  | MEDIUMBLOB
  | LONGBLOB
  | TINYTEXT
  | TEXT
  | MEDIUMTEXT
  | LONGTEXT
  | ENUM(@var{value1},@var{value2},@var{value3},...)
  | SET(@var{value1},@var{value2},@var{value3},...)
  | @var{spatial_type}

@var{index_col_name}:
    @var{col_name} [(@var{length})] [ASC | DESC]

@var{reference_definition}:
    REFERENCES @var{tbl_name} [(@var{index_col_name},...)]
               [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE]
               [ON DELETE @var{reference_option}]
               [ON UPDATE @var{reference_option}]

@var{reference_option}:
    RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT

@var{table_options}: @var{table_option} [@var{table_option}] ...

@var{table_option}:
    @{ENGINE|TYPE@} = @{BDB|HEAP|ISAM|InnoDB|MERGE|MRG_MYISAM|MYISAM@}
  | AUTO_INCREMENT = @var{value}
  | AVG_ROW_LENGTH = @var{value}
  | CHECKSUM = @{0 | 1@}
  | COMMENT = '@var{string}'
  | MAX_ROWS = @var{value}
  | MIN_ROWS = @var{value}
  | PACK_KEYS = @{0 | 1 | DEFAULT@}
  | PASSWORD = '@var{string}'
  | DELAY_KEY_WRITE = @{0 | 1@}
  | ROW_FORMAT = @{ DEFAULT | DYNAMIC | FIXED | COMPRESSED @}
  | RAID_TYPE = @{ 1 | STRIPED | RAID0 @}
        RAID_CHUNKS = @var{value}
        RAID_CHUNKSIZE = @var{value}
  | UNION = (@var{tbl_name}[,@var{tbl_name}]...)
  | INSERT_METHOD = @{ NO | FIRST | LAST @}
  | DATA DIRECTORY = '@var{absolute path to directory}'
  | INDEX DIRECTORY = '@var{absolute path to directory}'
  | [DEFAULT] CHARACTER SET @var{charset_name} [COLLATE @var{collation_name}]

@var{select_statement:}
    [IGNORE | REPLACE] [AS] SELECT ...   (@var{Some legal select statement})
@end example

@c description_for_help_topic CREATE TABLE  ENGINE TYPE KEY CREATE DATA ACTION AVG_ROW_LENGTH BERKELEYDB BDB BY CASCADE CHECK CHECKSUM COMMENT CONSTRAINT COMPRESSED FIXED DYNAMIC DEFAULT DELAY_KEY_WRITE DELETE DIRECTORY INDEX FIRST FOREIGN RAID_TYPE RAID_CHUNKS RAID_CHUNKSIZE ROW_FORMAT FULL FULLTEXT HEAP INNOBASE INNODB ISAM INSERT_METHOD MAX_ROWS MIN_ROWS PACK_KEYS PARTIAL RAID0 STRIPED MERGE MRG_MYISAM MYISAM NO REFERENCES SERIAL
@code{CREATE TABLE} creates a table with the given name.
You must have the @code{CREATE} privilege for the table.

Rules for allowable table names are given in @ref{Legal names}.  
By default, the table is created in the current database.  
An error occurs if the table already exists, if there is no current database,
or if the database does not exist.
@c end_description_for_help_topic

In MySQL 3.22 or later, the table name can be specified as
@var{db_name.tbl_name} to create the table in a specific database.
This works whether or not there is a current database.
If you use quoted identifiers, quote the database and table names
separately. For example, @code{`mydb`.`mytbl`} is legal, but
@code{`mydb.mytbl`} is not.

From MySQL 3.23 on, you can use the @code{TEMPORARY} keyword when
creating a table. A @code{TEMPORARY} table is visible only to the
current connection, and is dropped automatically when the
connection is closed.  This means that two different
connections can use the same temporary table name without conflicting
with each other or with an existing non-@code{TEMPORARY} table of the same
name. (The existing table is hidden until the temporary table is dropped.)
From MySQL 4.0.2 on, you must have the @code{CREATE TEMPORARY TABLES}
privilege to be able to create temporary tables.

In MySQL 3.23 or later, you can use the keywords
@code{IF NOT EXISTS} so that an error does not occur if the table already
exists.  Note that there is no verification that the existing table has a
structure identical to that indicated by the @code{CREATE TABLE} statement.

MySQL represents each table by an @file{.frm} table format
(definition) file in the database directory. The storage engine for the table
might create other files as well.
In the case of @code{MyISAM} tables, the storage engine creates three files
for a table named @var{tbl_name}:

@multitable @columnfractions .30 .70
@item @strong{File} @tab @strong{Purpose}
@item @code{@var{tbl_name}.frm} @tab Table format (definition) file
@item @code{@var{tbl_name}.MYD} @tab Data file
@item @code{@var{tbl_name}.MYI} @tab Index file
@end multitable

The files created by each storage engine to represent tables are described in
@ref{Storage engines}.

For general information on the properties of the various column types, see
@ref{Column types}.
For information about spatial column types, see
@ref{Spatial extensions in MySQL}.

@itemize @bullet
@item
If neither @code{NULL} nor @code{NOT NULL} is specified, the column
is treated as though @code{NULL} had been specified.

@item
An integer column can have the additional attribute @code{AUTO_INCREMENT}.
When you insert a value of @code{NULL} (recommended) or @code{0} into an
indexed
@code{AUTO_INCREMENT} column, the column is set to the next sequence value.
Typically this is @code{@var{value}+1}, where
@var{value} is the largest value for the column currently in the table.
@code{AUTO_INCREMENT} sequences begin with @code{1}.
@xref{mysql_insert_id, , @code{mysql_insert_id()}}.

As of MySQL 4.1.1, specifying the @code{NO_AUTO_VALUE_ON_ZERO} flag for the
@code{--sql-mode} server option or the @code{sql_mode} system variable allows
you to store @code{0} in @code{AUTO_INCREMENT} columns as @code{0} without
generating a new sequence value.
@xref{Server options}.

@strong{Note}: There can be only one @code{AUTO_INCREMENT} column per
table, it must be indexed, and it cannot have a @code{DEFAULT} value.
As of MySQL 3.23, an @code{AUTO_INCREMENT} column will work properly
only if it contains only positive values. Inserting a
negative number is regarded as inserting a very large positive number.
This is done to avoid precision problems when numbers ``wrap'' over from
positive to negative and also to ensure that you don't accidentally
get an @code{AUTO_INCREMENT} column that contains @code{0}.

For @code{MyISAM} and @code{BDB} tables, you can specify an
@code{AUTO_INCREMENT} secondary column in a multiple-column key.
@xref{example-AUTO_INCREMENT,  , example-@code{AUTO_INCREMENT}}.

@cindex ODBC compatibility
@cindex compatibility, with ODBC
To make MySQL compatible with some ODBC applications, you can find the
@code{AUTO_INCREMENT} value for the last inserted row with the following query:

@example
SELECT * FROM @var{tbl_name} WHERE @var{auto_col} IS NULL
@end example

@item
As of MySQL 4.1, character column definitions can include a @code{CHARACTER
SET} attribute to specify the character set and, optionally, a collation
for the column. For details, see @ref{Charset}.

@example
CREATE TABLE t (c CHAR(20) CHARACTER SET utf8 COLLATE utf8_bin);
@end example

Also as of 4.1, MySQL interprets length specifications in character column
definitions in characters. (Earlier versions interpret them in bytes.)

@item
@code{NULL} values are handled differently for @code{TIMESTAMP} columns than
for other column types.  You cannot store a literal @code{NULL} in a
@code{TIMESTAMP} column; setting the column to @code{NULL} sets it to the
current date and time.  Because @code{TIMESTAMP} columns behave this way, the
@code{NULL} and @code{NOT NULL} attributes do not apply in the normal way and
are ignored if you specify them.

On the other hand, to make it easier for MySQL clients to use
@code{TIMESTAMP} columns, the server reports that such columns can be
assigned @code{NULL} values (which is true), even though @code{TIMESTAMP}
never actually will contain a @code{NULL} value.  You can see this when you
use @code{DESCRIBE @var{tbl_name}} to get a description of your table.

Note that setting a @code{TIMESTAMP} column to @code{0} is not the same
as setting it to @code{NULL}, because @code{0} is a valid @code{TIMESTAMP}
value.

@item
@cindex default values
@cindex default values, implicit
@cindex implicit default values
@findex DEFAULT value clause
The @code{DEFAULT} clause specifies a default value for a column.
With one exception, the default value must be a constant; it cannot be
a function or an expression.  This means, for example, that you cannot
set the default for a date column to be the value of a function such as
@code{NOW()} or @code{CURRENT_DATE}. The exception is that you can specify
@code{CURRENT_TIMESTAMP} as the default for a @code{TIMESTAMP} column as
of MySQL 4.1.2.
@xref{TIMESTAMP 4.1,  , @code{TIMESTAMP} 4.1}.

Prior to MySQL 5.0.2, if a column definition includes no explicit
@code{DEFAULT} value, MySQL determines the default value as follows:

If the column can take @code{NULL} as a value, the column is defined with
an explicit @code{DEFAULT NULL} clause.

If the column cannot take @code{NULL} as the value, MySQL defines the
column with an explicit @code{DEFAULT} clause, using the implicit default
value for the column data type. Implicit defaults are defined as follows:

@itemize @minus
@item
For numeric types other than those declared with the @code{AUTO_INCREMENT}
attribute, the default is @code{0}.  For an @code{AUTO_INCREMENT} column, the
default value is the next value in the sequence.

@item
For date and time types other than @code{TIMESTAMP}, the default is the
appropriate ``zero'' value for the type.  For the first @code{TIMESTAMP}
column in a table, the default value is the current date and time.
@xref{Date and time types}.

@item
For string types other than @code{ENUM}, the default value is the empty
string.  For @code{ENUM}, the default is the first enumeration value.
@end itemize

@code{BLOB} and @code{TEXT} columns cannot be assigned a default value.

As of MySQL 5.0.2, if a column definition includes no explicit
@code{DEFAULT} value, MySQL determines the default value as follows:

If the column can take @code{NULL} as a value, the column is defined with
an explicit @code{DEFAULT NULL} clause.  This is the same as before 5.0.2.

If the column cannot take @code{NOT NULL} as the value, MySQL defines
the column with no explicit @code{DEFAULT} clause.  For data entry, if an
@code{INSERT} or @code{REPLACE} statement includes no value for the column,
MySQL handles the column according to to the SQL mode in effect at the time:

@itemize @bullet

@item
If strict mode is not enabled, MySQL sets the column to the implicit value
for the column data type.

@item
If strict mode is enabled, an error occurs for
transactional tables and the statement is rolled back. For non-transactional
tables, an error occurs unless the row is the second or subsequent row of
a multiple-row statement, in which case a warning occurs.

@end itemize

@c TODO: uncomment the following stuff when Bug #5986 gets fixed

@c Suppose a table @code{t} is defined as follows:
@c 
@c @example
@c CREATE TABLE t (i INT NOT NULL);
@c @end example
@c 
@c In this case, @code{i} has no explicit default, so all of the following
@c statements produce an error in strict mode and no row is inserted:
@c 
@c @example
@c INSERT INTO t VALUES();
@c INSERT INTO t VALUES(DEFAULT);
@c INSERT INTO t VALUES(DEFAULT(i));
@c @end example

@xref{Server SQL mode}.

For a given table, you can use the @code{SHOW CREATE TABLE} statement to
see which columns have an explicit @code{DEFAULT} clause.

@item
@cindex column comments
A comment for a column can be specified with the @code{COMMENT} option.
The comment is displayed by the
@code{SHOW CREATE TABLE} and @code{SHOW FULL COLUMNS} statements.
This option is operational as of MySQL 4.1.
(It is allowed but ignored in earlier versions.)

@item
From MySQL 4.1.0 on, the attribute @code{SERIAL} can be used as an alias
for @code{BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE}. This is a
compatibility feature.

@item
@code{KEY} is normally a synonym for @code{INDEX}.  From MySQL 4.1, the key
attribute @code{PRIMARY KEY} can also be specified as just @code{KEY} when
given in a column definition. This was implemented for compatibility with
other database systems.

@item
In MySQL, a @code{UNIQUE} index is one in which all values in the index
must be distinct.  An error occurs if you try to add a new row with a key
that matches an existing row.  The exception to this is that if a column
in the index is allowed to contain @code{NULL} values, it can contain
multiple @code{NULL} values.  This exception does not apply to @code{BDB}
tables, for which indexed columns allow only a single @code{NULL}.

@item
@tindex PRIMARY KEY
A @code{PRIMARY KEY} is a unique @code{KEY} where all key columns must be
defined as @code{NOT NULL}. If they are not explicitly declared as @code{NOT
NULL}, MySQL will declare them so implicitly (and silently).  A table can
have only one @code{PRIMARY KEY}.  If you don't have a @code{PRIMARY KEY}
and an application asks for the @code{PRIMARY KEY} in your tables, MySQL
returns the first @code{UNIQUE} index that has no @code{NULL} columns as
the @code{PRIMARY KEY}.

@item
In the created table, a @code{PRIMARY KEY} is placed first, followed
by all @code{UNIQUE} indexes, and then the non-unique indexes.  This helps the
MySQL optimizer to prioritize which index to use and also more quickly
to detect duplicated @code{UNIQUE} keys.

@item
A @code{PRIMARY KEY} can be a multiple-column index.  However, you cannot
create a multiple-column index using the @code{PRIMARY KEY} key attribute in a
column specification.  Doing so will mark only that single column as primary.
You must use a separate @code{PRIMARY KEY(index_col_name, ...)} clause.


@item
If a @code{PRIMARY KEY} or @code{UNIQUE} index consists of only one column
that has an integer type, you can also refer to the column as @code{_rowid}
in @code{SELECT} statements (new in MySQL 3.23.11).

@item
In MySQL, the name of a @code{PRIMARY KEY} is @code{PRIMARY}.  For other
indexes, if you don't assign a name, the index is assigned the same name as
the first indexed column, with an optional suffix (@code{_2}, @code{_3},
@code{...}) to make it unique.  You can see index names for a table using
@code{SHOW INDEX FROM @var{tbl_name}}.
@xref{SHOW INDEX,  , @code{SHOW INDEX}}.

@item
From MySQL 4.1.0 on, some storage engines allow you to specify an index
type when creating an index.  The syntax for the @var{index_type}
specifier is @code{USING type_name}. The allowable @code{type_name}
values supported by different storage engines are shown in the following
table. Where multiple index types are listed, the first one is the
default when no @var{index_type} specifier is given.

@multitable @columnfractions .20 .50
@item @strong{Storage Engine} @tab @strong{Allowable Index Types}
@item @code{MyISAM} @tab @code{BTREE}
@item @code{InnoDB} @tab @code{BTREE}
@item @code{MEMORY/HEAP} @tab @code{HASH}, @code{BTREE}
@end multitable

Example:

@example
CREATE TABLE lookup
    (id INT, INDEX USING BTREE (id))
    ENGINE = MEMORY;
@end example

@code{TYPE type_name} can be used as a synonym for @code{USING type_name}
to specify an index type.  However, @code{USING} is the preferred form.
Also, the index name name that precedes the index type in the index
specification syntax is not optional with @code{TYPE}. This is because,
unlike @code{USING}, @code{TYPE} is not a reserved word and thus is
interpreted as an index name.

If you specify an index type that is not legal for a storage engine,
but there is another index type available that the engine can use without
affecting query results, the engine will use the available type.

@item
@cindex @code{NULL} values, and indexes
@cindex indexes, and @code{NULL} values
Only the @code{MyISAM}, @code{InnoDB}, @code{BDB}, and (as of MySQL 4.0.2)
@code{MEMORY} storage engines support indexes on columns that can have
@code{NULL} values. In other cases, you must declare indexed columns
as @code{NOT NULL} or an error results.

@item
With @code{@var{col_name}(@var{length})} syntax in an index specification, you can create
an index that uses only the first @var{length} characters of a @code{CHAR}
or @code{VARCHAR} column. Indexing only a prefix of column values like this
can make the index file much smaller.
@xref{Indexes}.

@cindex @code{BLOB} columns, indexing
@cindex indexes, and @code{BLOB} columns
@cindex @code{TEXT} columns, indexing
@cindex indexes, and @code{TEXT} columns
The @code{MyISAM} and (as of MySQL 4.0.14) @code{InnoDB} storage engines also
support indexing on @code{BLOB} and @code{TEXT} columns.  When indexing
a @code{BLOB} or @code{TEXT} column, you @emph{must} specify a prefix
length for the index. For example:

@example
CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
@end example

Prefixes can be up to 255 bytes long (or 1000 bytes for @code{MyISAM}
and @code{InnoDB} tables as of MySQL 4.1.2).  Note that prefix limits
are measured in bytes, whereas the prefix length in @code{CREATE TABLE}
statements is interpreted as number of characters.  Take this into account
when specifying a prefix length for a column that uses a multi-byte
character set.

@item
An @var{index_col_name} specification can end with @code{ASC} or @code{DESC}.
These keywords are allowed for future extensions for specifying ascending
or descending index value storage.  Currently they are parsed but ignored;
index values are always stored in ascending order.

@item
When you use @code{ORDER BY} or @code{GROUP BY} with a @code{TEXT} or
@code{BLOB} column, the server sorts values using only the initial number of
bytes indicated by the @code{max_sort_length} system variable.
@xref{BLOB,  , @code{BLOB}}.

@item
In MySQL 3.23.23 or later, you can create special
@code{FULLTEXT} indexes. They are used for full-text search. Only the
@code{MyISAM} table type supports @code{FULLTEXT} indexes. They can be created
only from @code{CHAR}, @code{VARCHAR}, and @code{TEXT} columns.
Indexing always happens over the entire column; partial indexing is not
supported and any prefix length is ignored if specified. See @ref{Fulltext Search} for details of operation.

@item
In MySQL 4.1 or later, you can create special @code{SPATIAL} indexes on
spatial column types. Spatial types are supported only for @code{MyISAM}
tables and indexed columns must be declared as @code{NOT NULL}.  See
@ref{Spatial extensions in MySQL}.

@item
In MySQL 3.23.44 or later, @code{InnoDB} tables support checking of
foreign key constraints. @xref{InnoDB,  , @code{InnoDB}}. Note that the
@code{FOREIGN KEY} syntax in @code{InnoDB} is more restrictive than
the syntax presented for the @code{CREATE TABLE} statement at the beginning of
this section: The columns of the referenced
table must always be explicitly named.
@code{InnoDB} supports both @code{ON DELETE} and @code{ON UPDATE}
actions on foreign keys as of MySQL 3.23.50 and 4.0.8, respectively.
For the precise syntax, see
@ref{InnoDB foreign key constraints,  , @code{InnoDB} foreign key constraints}.

For other storage engines, MySQL Server parses the @code{FOREIGN KEY}
and @code{REFERENCES} syntax in @code{CREATE TABLE} statements,
but without further action being taken.
The @code{CHECK} clause is parsed but ignored by all storage engines.
 @xref{ANSI diff Foreign Keys}.

@item
For @code{MyISAM} and @code{ISAM} tables,
each @code{NULL} column takes one bit extra, rounded up to the nearest byte.
The maximum record length in bytes can be calculated as follows:

@example
row length = 1
             + (@var{sum of column lengths})
             + (@var{number of NULL columns} + @var{delete_flag} + 7)/8
             + (@var{number of variable-length columns})
@end example

@var{delete_flag} is 1 for tables with static record format. Static
tables use a bit in the row record for a flag that indicates whether
the row has been deleted.  @var{delete_flag} is 0 for dynamic tables
because the flag is stored in the dynamic row header.

These calculations do not apply for @code{InnoDB} tables, for which
storage size is no different for @code{NULL} columns than for @code{NOT
NULL} columns.

@end itemize

The @code{table_options} part of the @code{CREATE TABLE} syntax can be used
in MySQL 3.23 and above.

The @code{ENGINE} and @code{TYPE} options specify the storage engine for the
table.  @code{ENGINE} was added in MySQL 4.0.18 (for 4.0) and 4.1.2 (for 4.1).
It is the preferred option name as of those versions, and @code{TYPE} has
become deprecated.  @code{TYPE} will be supported throughout the 4.x series,
but likely will be removed in MySQL 5.1.

The @code{ENGINE} and @code{TYPE} options take the following values:

@multitable @columnfractions .25 .70
@item @strong{Storage Engine} @tab @strong{Description}
@item @code{BDB} @tab Transaction-safe tables with page locking. @xref{BDB storage engine,  , @code{BDB} storage engine}.
@item @code{BerkeleyDB} @tab An alias for @code{BDB}.
@item @code{HEAP} @tab The data for this table is stored only in memory.  @xref{MEMORY storage engine,  , @code{MEMORY} storage engine}.
@item @code{ISAM} @tab The original MySQL storage engine. @xref{ISAM storage engine,  , @code{ISAM} storage engine}.
@item @code{InnoDB} @tab Transaction-safe tables with row locking and foreign keys.  @xref{InnoDB,  , @code{InnoDB}}.
@item @code{MEMORY} @tab An alias for @code{HEAP}. (Actually, as of MySQL 4.1, @code{MEMORY} is the preferred term.)
@item @code{MERGE} @tab A collection of @code{MyISAM} tables used as one table. @xref{MERGE storage engine,  , @code{MERGE} storage engine}.
@item @code{MRG_MyISAM} @tab An alias for @code{MERGE}.
@item @code{MyISAM} @tab The binary portable storage engine that is the improved replacement for @code{ISAM}. @xref{MyISAM storage engine, , @code{MyISAM} storage engine}.
@end multitable

@xref{Storage engines}.

If a storage engine is specified that is not available,
MySQL uses @code{MyISAM} instead.
For example, if a table definition includes the @code{ENGINE=BDB} option but the
MySQL server does not support @code{BDB} tables, the table is created
as a @code{MyISAM} table.  This makes it possible to have a replication
setup where you have transactional tables on the master but tables created
on the slave are non-transactional (to get more speed).  In MySQL 4.1.1, a
warning occurs if the storage engine specification is not honored.

The other table options are used to optimize the behavior of the
table. In most cases, you don't have to specify any of them.
The options work for all storage engines unless otherwise indicated:

@table @code

@item AUTO_INCREMENT
The initial @code{AUTO_INCREMENT} value for the table. This works for
@code{MyISAM} only. To set the first auto-increment value for an @code{InnoDB}
table, insert a dummy row with a value one less than the desired value after
creating the table, and then delete the dummy row.

In MySQL 5.0.3 or later the initial @code{AUTO_INCREMENT} value for the table
works also for the @code{InnoDB} table.

@item AVG_ROW_LENGTH
An approximation of the average row length for your table. You need to
set this only for large tables with variable-size records.

When you create a @code{MyISAM} table, MySQL uses the product of the
@code{MAX_ROWS} and @code{AVG_ROW_LENGTH} options to decide how big the
resulting table will be.  If you don't specify either option, the maximum
size for a table will be 4GB (or 2GB if your operating system only supports
2GB tables). The reason for this is just to keep down the pointer sizes to
make the index smaller and faster if you don't really need big files.  If
you want all your tables to be able to grow above the 4GB limit and are
willing to have your smaller tables slightly slower and larger than
necessary, you may increase the default pointer size by setting the
@code{myisam_data_pointer_size} system variable, which was added in MySQL
4.1.2.
@xref{Server system variables, @code{myisam_data_pointer_size}}.

@item CHECKSUM
Set this to 1 if you want MySQL to maintain a live checksum for all rows
(that is, a checksum that MySQL updates automatically as the table changes).
This makes the table a little slower to update, but also makes it easier to
find corrupted tables.  The @code{CHECKSUM TABLE} statement reports the
checksum.  (@code{MyISAM} only.)

@item COMMENT
A comment for your table, up to 60 characters long.

@item MAX_ROWS
The maximum number of rows you plan to store in the table.

@item MIN_ROWS
The minimum number of rows you plan to store in the table.

@item PACK_KEYS
Set this option to 1 if you want to have smaller indexes.  This usually
makes updates slower and reads faster.
Setting the option to 0 disables all packing of keys. Setting it to
@code{DEFAULT} (MySQL 4.0) tells the storage engine to only pack long
@code{CHAR}/@code{VARCHAR} columns.
(@code{MyISAM} and @code{ISAM} only.)

If you don't use @code{PACK_KEYS}, the default is to only pack strings,
not numbers.  If you use @code{PACK_KEYS=1}, numbers will be packed as well.

When packing binary number keys, MySQL uses prefix compression:

@itemize @bullet
@item
Every key needs one extra byte to indicate how many bytes of the previous
key are the same for the next key.

@item
The pointer to the row is stored in high-byte-first order directly after
the key, to improve compression.

@end itemize

This means that if you have many equal keys on two consecutive rows,
all following ``same'' keys will usually only take two bytes (including the
pointer to the row).  Compare this to the ordinary case where the following
keys will take @code{storage_size_for_key + pointer_size} (where the pointer
size is usually 4). Conversely,
you will get a big benefit from prefix compression only if you have many
numbers that are the same.  If all keys are totally different, you will
use one byte more per key, if the key isn't a key that can have @code{NULL}
values. (In this case, the packed key length will be stored in the same
byte that is used to mark if a key is @code{NULL}.)

@item PASSWORD
Encrypt the @file{.frm} file with a password.  This option doesn't do anything in the standard MySQL version.

@item DELAY_KEY_WRITE
Set this to 1 if you want to delay key updates for the table until the table
is closed. (@code{MyISAM} only.)

@item ROW_FORMAT
Defines how the rows should be stored. Currently this option works only with
@code{MyISAM} tables. The option value can @code{FIXED} or @code{DYNAMIC} for
static or variable-length row format. @command{myisampack} sets the type to
@code{COMPRESSED}.
@xref{MyISAM table formats,  , @code{MyISAM} table formats}.

@item RAID_TYPE
@cindex RAID, table type
@cindex tables, RAID
The @code{RAID_TYPE} option can help you to exceed the 2GB/4GB limit for
the @code{MyISAM} data file (not the index file) on operating systems that
don't support big files. This option is unnecessary and not recommended for
filesystems that support big files.

You can get more speed from the I/O bottleneck by putting @code{RAID}
directories on different physical disks.  For now, the only allowed
@code{RAID_TYPE} is @code{STRIPED}. @code{1} and @code{RAID0} are aliases
for @code{STRIPED}.

If you specify the @code{RAID_TYPE} option for a @code{MyISAM} table,
specify the @code{RAID_CHUNKS} and @code{RAID_CHUNKSIZE} options as well.
The maximum @code{RAID_CHUNKS} value is 255.
@code{MyISAM} will create @code{RAID_CHUNKS} subdirectories named @file{00},
@file{01}, @file{02}, ... @file{09}, @file{0a}, @file{0b}, ...
in the database directory.  In each of these directories, @code{MyISAM}
will create a file @file{@var{tbl_name}.MYD}.  When writing data to the data file,
the @code{RAID} handler maps the first @code{RAID_CHUNKSIZE*1024} bytes to
the first file, the next @code{RAID_CHUNKSIZE*1024} bytes to the next file,
and so on.

@code{RAID_TYPE} works on any operating system, as long as you have built
MySQL with the @code{--with-raid} option to @command{configure}. To determine
whether a server supports @code{RAID} tables, use @code{SHOW VARIABLES LIKE
'have_raid'} to see whether the variable value is @code{YES}.

@item UNION
@code{UNION} is used when you want to use a collection of identical
tables as one. This works only with @code{MERGE} tables.
@xref{MERGE storage engine, , @code{MERGE} storage engine}.

For the moment, you must have @code{SELECT}, @code{UPDATE}, and
@code{DELETE} privileges for the tables you map to a @code{MERGE} table.
Originally, all used tables had to be in the same database
as the @code{MERGE} table itself. This restriction has been lifted as of
MySQL 4.1.1.

@item INSERT_METHOD
If you want to insert data in a @code{MERGE} table, you have to specify with
@code{INSERT_METHOD} into which table the row should be inserted.
@code{INSERT_METHOD} is an option useful for @code{MERGE} tables only. 
This option was introduced in MySQL 4.0.0.
@xref{MERGE storage engine,  , @code{MERGE} storage engine}.

@item DATA DIRECTORY
@itemx INDEX DIRECTORY
By using @code{DATA DIRECTORY='@var{directory}'} or @code{INDEX
DIRECTORY='@var{directory}'} you can specify where the @code{MyISAM} storage engine should
put a table's data file and index file.  Note that the directory should be a full
path to the directory (not a relative path).

These options work only for @code{MyISAM} tables from MySQL 4.0 on, when
you are not using the @code{--skip-symbolic-links} option. Your operating
system must also have a working, thread-safe @code{realpath()} call.
@xref{Symbolic links to tables}.

@end table

@cindex copying tables
@cindex tables, copying

As of MySQL 3.23, you can create one table from another by adding a
@code{SELECT} statement at the end of the @code{CREATE TABLE} statement:

@example
CREATE TABLE @var{new_tbl} SELECT * FROM @var{orig_tbl};
@end example

MySQL will create new column for all elements
in the @code{SELECT}.  For example:

@example
mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,
    ->        PRIMARY KEY (a), KEY(b))
    ->        TYPE=MyISAM SELECT b,c FROM test2;
@end example

This creates a @code{MyISAM} table with three columns, @code{a}, @code{b},
and @code{c}.  Notice that the columns from the @code{SELECT} statement
are appended to the right side of the table, not overlapped onto it.
Take the following example:

@example
mysql> SELECT * FROM foo;
+---+
| n |
+---+
| 1 |
+---+

mysql> CREATE TABLE bar (m INT) SELECT n FROM foo;
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM bar;
+------+---+
| m    | n |
+------+---+
| NULL | 1 |
+------+---+
1 row in set (0.00 sec)
@end example

For each row in table @code{foo}, a row is inserted in @code{bar} with
the values from @code{foo} and default values for the new columns.

If any errors occur while copying the data to the table, it is
automatically dropped and not created.

@code{CREATE TABLE ... SELECT} will not automatically create any indexes
for you.  This is done intentionally to make the statement as flexible as
possible.  If you want to have indexes in the created table, you should
specify these before the @code{SELECT} statement:

@example
mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;
@end example

Some conversion of column types might occur. For example, the
@code{AUTO_INCREMENT} attribute is not preserved, and @code{VARCHAR}
columns can become @code{CHAR} columns.

When creating a table with @code{CREATE ... SELECT}, make sure to alias any
function calls or expressions in the query. If you do not, the @code{CREATE}
statement might fail or result in undesirable column names.

@example
CREATE TABLE artists_and_works
SELECT artist.name, COUNT(work.artist_id) AS number_of_works
FROM artist LEFT JOIN work ON artist.id = work.artist_id
GROUP BY artist.id;
@end example

As of MySQL 4.1, you can explicitly specify the type for a generated column:

@example
CREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar;
@end example

In MySQL 4.1, you can also use @code{LIKE} to create an empty table based on the
definition of another table, including any column attributes and
indexes the original table has:

@example
CREATE TABLE @var{new_tbl} LIKE @var{orig_tbl};
@end example

@code{CREATE TABLE ... LIKE} does not copy any @code{DATA DIRECTORY} or
@code{INDEX DIRECTORY} table options that were specified for the original
table, or any foreign key definitions.

You can precede the @code{SELECT} by @code{IGNORE} or @code{REPLACE}
to indicate how to handle records that duplicate unique key values.
With @code{IGNORE}, new records that duplicate an existing record on a
unique key value are discarded.  With @code{REPLACE}, new records replace
records that have the same unique key value.  If neither @code{IGNORE}
nor @code{REPLACE} is specified, duplicate unique key values result in
an error.

To ensure that the update log/binary log can be used to re-create the
original tables, MySQL will not allow concurrent inserts during
@code{CREATE TABLE ... SELECT}.


@node Silent column changes,  , CREATE TABLE, CREATE TABLE
@subsubsection Silent Column Specification Changes

@cindex silent column changes

In some cases, MySQL silently changes column specifications from
those given in a @code{CREATE TABLE} or @code{ALTER TABLE} statement:

@itemize @bullet
@item
@code{VARCHAR} columns with a length less than four are changed to
@code{CHAR}.

@item
If any column in a table has a variable length, the entire row becomes
variable-length as a result.  Therefore, if a table contains any
variable-length columns (@code{VARCHAR}, @code{TEXT}, or @code{BLOB}),
all @code{CHAR} columns longer than three characters are changed to
@code{VARCHAR} columns.  This doesn't affect how you use the columns in
any way; in MySQL, @code{VARCHAR} is just a different way to
store characters.  MySQL performs this conversion because it
saves space and makes table operations faster.  @xref{Storage engines}.

@item
From MySQL 4.1.0 on, a @code{CHAR} or @code{VARCHAR} column with a
length specification greater than 255 is converted to the smallest @code{TEXT}
type that can hold values of the given length.
For example, @code{VARCHAR(500)} is converted to @code{TEXT}, and
@code{VARCHAR(200000)} is converted to @code{MEDIUMTEXT}.
This is a compatibility feature.

@item
@code{TIMESTAMP} display sizes are discarded from MySQL 4.1 on, due
to changes made to the @code{TIMESTAMP} column type in that version.
Before MySQL 4.1, @code{TIMESTAMP} display sizes must be even and in the
range from 2 to 14.  If you specify a display size of 0 or greater than
14, the size is coerced to 14.  Odd-valued sizes in the range from 1 to
13 are coerced to the next higher even number.

@item
You cannot store a literal @code{NULL} in a @code{TIMESTAMP} column; setting
it to @code{NULL} sets it to the current date and time.  Because
@code{TIMESTAMP} columns behave this way, the @code{NULL} and @code{NOT NULL}
attributes do not apply in the normal way and are ignored if you specify
them.  @code{DESCRIBE @var{tbl_name}} always reports that a @code{TIMESTAMP}
column can be assigned @code{NULL} values.

@item
Columns that are part of a @code{PRIMARY KEY} are made @code{NOT NULL} even if
not declared that way.

@item
Starting from MySQL 3.23.51, trailing spaces are automatically deleted from
@code{ENUM} and @code{SET} member values when the table is created.

@item
MySQL maps certain column types used by other SQL database vendors
to MySQL types.  @xref{Other-vendor column types}.

@item
If you include a @code{USING} clause to specify an index type that is not
legal for a storage engine, but there is another index type available that
the engine can use without affecting query results, the engine will use the
available type.

@end itemize

To see whether MySQL used a column type other
than the one you specified, issue a @code{DESCRIBE} or @code{SHOW
CREATE TABLE} statement after creating or altering your table.

@cindex @command{myisampack}
Certain other column type changes can occur if you compress a table
using @command{myisampack}. @xref{Compressed format}.


@node CREATE VIEW, DROP DATABASE, CREATE TABLE, Data Definition
@subsection @code{CREATE VIEW} Syntax

@cindex views
@cindex views, updatable
@findex CREATE VIEW

@c VIEWS-TODO: add ALGORITHM syntax if implemented, point out that
@c you can update base table through the view, discuss what privileges
@c apply and when, what happens if you change or drop the base table,
@c etc., etc., etc.

@c example_for_help_topic CREATE VIEW
@example
CREATE [OR REPLACE] [ALGORITHM = @{UNDEFINED | MERGE | TEMPTABLE@}]
    VIEW @var{view_name} [(@var{column_list})]
    AS @var{select_statement}
    [WITH [CASCADED | LOCAL] CHECK OPTION]
@end example

@c description_for_help_topic CREATE VIEW
This statement creates a new view, or replaces an existing one if the
@code{OR REPLACE} clause is given. The @var{select_statement} is a
@code{SELECT} statement that provides the definition of the view.
The optional column list can be given to define explicit names for the
view columns.

@c TODO: need to describe ALGORITHM clause

The @code{WITH CHECK OPTION} clause can be given for an updatable view to
prevent inserts or updates to rows except those for which the @code{WHERE}
clause in the @var{select_statement} is true.
@c end_description_for_help_topic

A view can be created from many kinds of @code{SELECT} statements.
For example, the @code{SELECT} can refer to a single table, a join of
multiple tables, or a @code{UNION}.  The @code{SELECT} need not even
refer to any tables. The following example defines a view that
selects two columns from another table, as well as an expression calculated
from those columns:

@example
mysql> CREATE TABLE t (qty INT, price INT);
mysql> INSERT INTO t VALUES(3, 50);
mysql> CREATE VIEW v AS SELECT qty, price, qty*price AS value FROM t;
mysql> SELECT * FROM v;
+------+-------+-------+
| qty  | price | value |
+------+-------+-------+
|    3 |    50 |   150 |
+------+-------+-------+
@end example

By default, the view is in the current database. To create
the view explicitly in a given database, specify the name as
@var{db_name.view_name} when you create it.

@example
mysql> CREATE VIEW test.v AS SELECT * FROM t;
@end example

In a @code{WITH CHECK OPTION} clause for an updatable view, the @code{LOCAL}
and @code{CASCADED} keywords determine the scope of check testing when the
view is defined in terms of another view.  @code{LOCAL} keyword restricts
the @code{CHECK OPTION} only to the view being defined.  @code{CASCADED}
causes the checks for underlying views to be evaluated as well.  When neither
keyword is given, the default is @code{CASCADED}. Consider the definitions
for the following table and set of views:

@example
mysql> CREATE TABLE t1 (a INT);
mysql> CREATE VIEW v1 AS SELECT * FROM t1 WHERE a < 2
    -> WITH CHECK OPTION;
mysql> CREATE VIEW v2 AS SELECT * FROM v1 WHERE a > 0
    -> WITH LOCAL CHECK OPTION;
mysql> CREATE VIEW v3 AS SELECT * FROM v1 WHERE a > 0
    -> WITH CASCADED CHECK OPTION;
@end example

Here the @code{v2} and @code{v3} views are defined in terms of another view,
@code{v1}. @code{v2} has a @code{LOCAL} check option, so inserts are tested
only against the @code{v2} check.  @code{v3} has a @code{CASCADED} check
option, so inserts are tested not only against its own check, but against
those of underlying views. The following statements illustrate these
differences:

@example
ql> INSERT INTO v2 VALUES (2);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO v3 VALUES (2);
ERROR 1369 (HY000): CHECK OPTION failed 'test.v3'
@end example

The @code{CREATE VIEW} statement was added in MySQL 5.0.1.  The @code{WITH
CHECK OPTION} clause was implemented in MySQL 5.0.2.


@node DROP DATABASE, DROP INDEX, CREATE VIEW, Data Definition
@subsection @code{DROP DATABASE} Syntax

@findex DROP DATABASE
@findex DROP SCHEMA
@cindex deleting, database
@cindex database, deleting
@cindex deleting, schema
@cindex schema, deleting

@c example_for_help_topic DROP DATABASE
@example
DROP @{DATABASE | SCHEMA@} [IF EXISTS] @var{db_name}
@end example

@c description_for_help_topic DROP DATABASE  DROP DATABASE SCHEMA EXISTS IF
@code{DROP DATABASE} drops all tables in the database and deletes the
database.  Be @emph{very} careful with this statement!
To use @code{DROP DATABASE}, you need the @code{DROP} privilege on the
database.

In MySQL 3.22 or later, you can use the keywords @code{IF EXISTS}
to prevent an error from occurring if the database doesn't exist.

@code{DROP SCHEMA} can be used as of MySQL 5.0.2.
@c end_description_for_help_topic

If you use @code{DROP DATABASE} on a symbolically linked
database, both the link and the original database are deleted.

As of MySQL 4.1.2, @code{DROP DATABASE} returns the number of tables that
were removed.  This corresponds to the number of @file{.frm} files removed.

The @code{DROP DATABASE} statement removes from the given database directory
those files and directories that MySQL itself may create during normal
operation:

@itemize @bullet

@item
All files with these extensions:

@multitable @columnfractions .10 .10 .10 .10
@item @code{.BAK}  @tab @code{.DAT}  @tab @code{.HSH}  @tab @code{.ISD}
@item @code{.ISM}  @tab @code{.ISM}  @tab @code{.MRG}  @tab @code{.MYD}
@item @code{.MYI}  @tab @code{.db}   @tab @code{.frm}  @tab
@end multitable

@item
All subdirectories with names that consist of two hex digits
@code{00}-@code{ff}. These are subdirectories used for @code{RAID} tables.

@item
The @file{db.opt} file, if it exists.

@end itemize

If other files or directories remain in the database directory after MySQL
removes those just listed, the database directory cannot be removed. In this
case, you must remove any remaining files or directories manually and issue
the @code{DROP DATABASE} statement again.

@cindex @command{mysqladmin}
You can also drop databases with @command{mysqladmin}.
@xref{mysqladmin,  , @command{mysqladmin}}.


@node DROP INDEX, DROP TABLE, DROP DATABASE, Data Definition
@subsection @code{DROP INDEX} Syntax

@findex DROP INDEX
@cindex deleting, index
@cindex index, deleting

@c example_for_help_topic DROP INDEX
@example
DROP INDEX @var{index_name} ON @var{tbl_name}
@end example

@c description_for_help_topic DROP INDEX  DROP INDEX
@code{DROP INDEX} drops the index named @var{index_name} from the table
@var{tbl_name}.  In MySQL 3.22 or later, @code{DROP INDEX} is mapped to an
@code{ALTER TABLE} statement to drop the index.  @xref{ALTER TABLE, ,
@code{ALTER TABLE}}.  @code{DROP INDEX} doesn't do anything prior to MySQL
3.22.
@c end_description_for_help_topic


@node DROP TABLE, DROP VIEW, DROP INDEX, Data Definition
@subsection @code{DROP TABLE} Syntax

@findex DROP TABLE
@cindex deleting, table
@cindex table, deleting

@c example_for_help_topic DROP TABLE
@example
DROP [TEMPORARY] TABLE [IF EXISTS]
    @var{tbl_name} [, @var{tbl_name}] ...
    [RESTRICT | CASCADE]
@end example

@c description_for_help_topic DROP TABLE  DROP TABLE EXISTS IF TEMPORARY RESTRICT CASCADE
@code{DROP TABLE} removes one or more tables. You must have the @code{DROP}
privilege for each table. All table data and the table
definition are @emph{removed}, so @emph{be careful} with this statement!

In MySQL 3.22 or later, you can use the keywords @code{IF EXISTS}
to prevent an error from occurring for tables that don't exist.  As of
MySQL 4.1, a @code{NOTE} is generated for each non-existent table when
using @code{IF EXISTS}.
@xref{SHOW WARNINGS,  , @code{SHOW WARNINGS}}.

@code{RESTRICT} and @code{CASCADE} are allowed to make porting easier.
For the moment, they do nothing.

@strong{Note}: @code{DROP TABLE} automatically commits the current
active transaction, unless you are using MySQL 4.1 or higher and the
@code{TEMPORARY} keyword.
@c end_description_for_help_topic

The @code{TEMPORARY} keyword is ignored in MySQL 4.0.  As of 4.1, it has the
following effect:

@itemize @bullet
@item
The statement drops only @code{TEMPORARY} tables.
@item
The statement doesn't end a running transaction.
@item
No access rights are checked.  (A @code{TEMPORARY} table is visible only
only to the client that created it, so no check is necessary.)
@end itemize

Using @code{TEMPORARY} is a good way to ensure that you don't accidentally
drop a non-@code{TEMPORARY} table.


@node DROP VIEW, RENAME TABLE, DROP TABLE, Data Definition
@subsection @code{DROP VIEW} Syntax

@findex DROP VIEW

@c example_for_help_topic DROP VIEW
@example
DROP VIEW [IF EXISTS]
    @var{view_name} [, @var{view_name}] ...
    [RESTRICT | CASCADE]
@end example

@c description_for_help_topic DROP VIEW  DROP VIEW IF EXISTS RESTRICT CASCADE
@code{DROP VIEW} removes one or more views. You must have the @code{DROP}
privilege for each view.

You can use the keywords @code{IF EXISTS} to prevent an error from occurring
for views that don't exist.  When this clause is given, a @code{NOTE} is
generated for each non-existent view.
@xref{SHOW WARNINGS,  , @code{SHOW WARNINGS}}.

@code{RESTRICT} and @code{CASCADE}, if given, are parsed and ignored.
@c end_description_for_help_topic

This statement was added in MySQL 5.0.1.


@node RENAME TABLE,  , DROP VIEW, Data Definition
@subsection @code{RENAME TABLE} Syntax

@findex RENAME TABLE

@c description_for_help_topic RENAME TABLE
@example
RENAME TABLE @var{tbl_name} TO @var{new_tbl_name}
    [, @var{tbl_name2} TO @var{new_tbl_name2}] ...
@end example

This statement renames one or more tables.  It was added in MySQL 3.23.23.

The rename operation is done atomically, which means that no other thread
can access any of the tables while the rename is running. For example,
if you have an existing table @code{old_table}, you can create another
table @code{new_table} that has the same structure but is empty, and then
replace the existing table with the empty one as follows:
@c end_description_for_help_topic

@c example_for_help_topic RENAME TABLE
@example
CREATE TABLE @var{new_table} (...);
RENAME TABLE @var{old_table} TO @var{backup_table}, @var{new_table} TO @var{old_table};
@end example

If the statement renames more than one table, renaming operations are done
from left to right. If you want to swap two table names, you can do so
like this (assuming that no table named @code{tmp_table} currently exists):

@example
RENAME TABLE @var{old_table} TO @var{tmp_table},
             @var{new_table} TO @var{old_table},
             @var{tmp_table} TO @var{new_table};
@end example

As long as two databases are on the same filesystem you can also rename
a table to move it from one database to another:

@example
RENAME TABLE @var{current_db.tbl_name} TO @var{other_db.tbl_name;}
@end example

When you execute @code{RENAME}, you can't have any locked tables or
active transactions.  You must also have the @code{ALTER} and @code{DROP}
privileges on the original table, and the @code{CREATE} and @code{INSERT}
privileges on the new table.

If MySQL encounters any errors in a multiple-table rename, it
will do a reverse rename for all renamed tables to get everything back
to the original state.

@node Basic User Commands, Transactional Commands, Data Definition, SQL Syntax
@section MySQL Utility Statements

@menu
* DESCRIBE::                    @code{DESCRIBE} Syntax (Get Information About Columns)
* USE::                         @code{USE} Syntax
@end menu


@node DESCRIBE, USE, Basic User Commands, Basic User Commands
@subsection @code{DESCRIBE} Syntax (Get Information About Columns)

@findex DESC
@findex DESCRIBE

@c help_category Administration
@c description_for_help_topic DESCRIBE  DESC
@example
@{DESCRIBE | DESC@} @var{tbl_name} [@var{col_name} | @var{wild}]
@end example

@code{DESCRIBE} provides information about a table's columns.  It is a
shortcut for @code{SHOW COLUMNS FROM}.
@c end_description_for_help_topic
@xref{SHOW COLUMNS,  ,  @code{SHOW COLUMNS}}.

@var{col_name} can be a column name, or a string containing the SQL
@samp{%} and @samp{_} wildcard characters to obtain output only for the
columns with names matching the string. There is no need to enclose the
string in quotes unless it contains spaces or other special characters.

@example
mysql> DESCRIBE city;
+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| Id         | int(11)  |      | PRI | NULL    | auto_increment |
| Name       | char(35) |      |     |         |                |
| Country    | char(3)  |      | UNI |         |                |
| District   | char(20) | YES  | MUL |         |                |
| Population | int(11)  |      |     | 0       |                |
+------------+----------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
@end example

The @code{Null} column indicates whether NULL values can be stored, 
with YES displayed when NULL values are allowed. 

The @code{Key} column indicates whether the field is indexed. A value of @code{PRI}
indicates that the field is part of the table's primary key. @code{UNI} indicates that
the field is part of a a @code{UNIQUE} index. The @code{MUL} value 
indicates that multiple occurences of a given value allowed within the field. 

A field can be designated as @code{MUL} even if a @code{UNIQUE} index is used if 
@code{NULL} values are allowed, as multiple rows in a @code{UNIQUE} index can hold 
a @code{NULL} value if the column is not declared @code{NOT NULL}. Another cause 
for @code{MUL} on a @code{UNIQUE} index is when two columns form a composite 
@code{UNIQUE} index; while the combination of the columns will be unique, each 
column can still hold multiple occurences of a given value. Note that in a composite index only the leftmost field of the index will have an entry in the @code{Key} column.

The @code{Default} column indicates the default value that is assigned to the field.

The @code{Extra} column contains any additional information that is available about
a given field. In our example the @code{Extra} column indicates that our @code{Id} column
was created with the @code{AUTO_INCREMENT} keyword. 

If the column types are different from what you expect them to be based on a
@code{CREATE TABLE} statement, note that MySQL sometimes
changes column types.  @xref{Silent column changes}.

@cindex Oracle compatibility
@cindex compatibility, with Oracle
The @code{DESCRIBE} statement is provided for Oracle compatibility.

The @code{SHOW CREATE TABLE} and @code{SHOW TABLE STATUS} statements also
provide information about tables.
@xref{SHOW, , @code{SHOW}}.


@node USE,  , DESCRIBE, Basic User Commands
@subsection @code{USE} Syntax

@findex USE

@example
USE @var{db_name}
@end example

The @code{USE @var{db_name}} statement tells MySQL to use the @var{db_name}
database as the default (current) database for subsequent statements.
The database remains the default until the end of the session or until
another @code{USE} statement is issued:

@example
mysql> USE db1;
mysql> SELECT COUNT(*) FROM mytable;   # selects from db1.mytable
mysql> USE db2;
mysql> SELECT COUNT(*) FROM mytable;   # selects from db2.mytable
@end example

Making a particular database current by means of the @code{USE} statement
does not preclude you from accessing tables in other databases.  The following example
accesses the @code{author} table from the @code{db1} database and the
@code{editor} table from the @code{db2} database:

@example
mysql> USE db1;
mysql> SELECT author_name,editor_name FROM author,db2.editor
    ->        WHERE author.editor_id = db2.editor.editor_id;
@end example

@cindex Sybase compatibility
@cindex compatibility, with Sybase
The @code{USE} statement is provided for Sybase compatibility.


@node Transactional Commands, Database Administration, Basic User Commands, SQL Syntax
@section MySQL Transactional and Locking Statements

@menu
* COMMIT::                      @code{START TRANSACTION}, @code{COMMIT}, and @code{ROLLBACK} Syntax
* Cannot roll back::            Statements That Cannot Be Rolled Back
* Implicit commit::             Statements That Cause an Implicit Commit
* Savepoints::                  @code{SAVEPOINT} and @code{ROLLBACK TO SAVEPOINT} Syntax
* LOCK TABLES::                 @code{LOCK TABLES} and @code{UNLOCK TABLES} Syntax
* SET TRANSACTION::             @code{SET TRANSACTION} Syntax
@end menu

@c help_category Transactions

@node COMMIT, Cannot roll back, Transactional Commands, Transactional Commands
@subsection @code{START TRANSACTION}, @code{COMMIT}, and @code{ROLLBACK} Syntax

@findex START TRANSACTION
@findex BEGIN
@findex COMMIT
@findex ROLLBACK

@c description_for_help_topic START TRANSACTION  START TRANSACTION BEGIN WORK COMMIT ROLLBACK SET AUTOCOMMIT
By default, MySQL runs with autocommit mode enabled. This means that
as soon as you execute a statement that updates (modifies) a table,
MySQL stores the update on disk.

If you are using transaction-safe tables (like @code{InnoDB} or @code{BDB}),
you can disable autocommit mode with the following statement:

@example
SET AUTOCOMMIT=0;
@end example

After disabling autocommit mode by setting the @code{AUTOCOMMIT} variable to
zero, you must use @code{COMMIT} to store your changes to disk or
@code{ROLLBACK} if you want to ignore the changes you have made since
the beginning of your transaction.

If you want to disable autocommit mode for a single series of
statements, you can use the @code{START TRANSACTION} statement:
@c end_description_for_help_topic

@c example_for_help_topic START TRANSACTION
@example
START TRANSACTION;
SELECT @@A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summary=@@A WHERE type=1;
COMMIT;
@end example

With @code{START TRANSACTION}, autocommit remains disabled until you end the
transaction with @code{COMMIT} or @code{ROLLBACK}. The autocommit mode then
reverts to its previous state.

@code{BEGIN} and @code{BEGIN WORK} can be used instead of @code{START
TRANSACTION} to initiate a transaction.  @code{START TRANSACTION} was
added in MySQL 4.0.11.  This is standard SQL syntax and is the recommended way
to start an ad-hoc transaction.  @code{BEGIN} and @code{BEGIN WORK} are
available from MySQL 3.23.17 and 3.23.19, respectively.

As of MySQL 4.1.8, you can begin a transaction like this:

@example
START TRANSACTION WITH CONSISTENT SNAPSHOT;
@end example

The @code{WITH CONSISTENT SNAPSHOT} clause starts a consistent read for
storage engines that are capable of it.  Currently, this applies only
to @code{InnoDB}.  The effect is the same as issuing a @code{START
TRANSACTION} followed by a @code{SELECT} from any @code{InnoDB} table.
@xref{InnoDB consistent read}.

Beginning a transaction causes an implicit @code{UNLOCK TABLES} to be
performed.

Note that if you are not using transaction-safe tables, any changes are
stored at once, regardless of the status of autocommit mode.

If you issue a @code{ROLLBACK} statement after updating a non-transactional
table within a transaction, an @code{ER_WARNING_NOT_COMPLETE_ROLLBACK}
warning occurs.  Changes to transaction-safe tables will be rolled back, but
not changes to non-transaction-safe tables.

If you are using @code{START TRANSACTION} or @code{SET AUTOCOMMIT=0}, you
should use the MySQL binary log for backups instead of the
older update log.  Transactions are stored in the binary log
in one chunk, upon @code{COMMIT}. Transactions that are
rolled back are not logged.
(Exception: Modifications to non-transactional tables cannot be rolled
back.  If a transaction that is rolled back includes modifications
to non-transactional tables, the entire transaction is logged with a
@code{ROLLBACK} statement at the end to ensure that the modifications to
those tables are replicated. This is true as of MySQL 4.0.15.)
@xref{Binary log}.

You can change the isolation level for transactions with
@code{SET TRANSACTION ISOLATION LEVEL}.
@xref{SET TRANSACTION,  , @code{SET TRANSACTION}}.


@node Cannot roll back, Implicit commit, COMMIT, Transactional Commands
@subsection Statements That Cannot Be Rolled Back

Some statements cannot be rolled back.  In general, these include data
definition language (DDL) statements, such as those that create or drop
databases, or those that create, drop, or alter tables.

You should design your transactions not to include such statements.
If you issue a statement early in a transaction that cannot be rolled back,
and then another statement later fails, the full effect of the transaction
cannot be rolled back by issuing a @code{ROLLBACK} statement.


@node Implicit commit, Savepoints, Cannot roll back, Transactional Commands
@subsection Statements That Cause an Implicit Commit

Each of the following statements (and any synonyms for them) implicitly end
a transaction, as if you had done a @code{COMMIT} before executing the
statement:

@multitable @columnfractions .25 .25 .25
@item @code{ALTER TABLE}    @tab @code{BEGIN}       @tab @code{CREATE INDEX}
@item @code{DROP DATABASE}  @tab @code{DROP INDEX}  @tab @code{DROP TABLE}
@item @code{LOAD MASTER DATA} @tab @code{LOCK TABLES} @tab @code{RENAME TABLE}
@item @code{SET AUTOCOMMIT=1} @tab @code{START TRANSACTION} @tab @code{TRUNCATE TABLE}
@end multitable

@code{UNLOCK TABLES} also ends a transaction if any tables currently are
locked.  Prior to MySQL 4.0.13, @code{CREATE TABLE} ends a transaction if
the binary update log is enabled.

Transactions cannot be nested. This is a consequence of the implicit
@code{COMMIT} performed for any current transaction when you issue a
@code{START TRANSACTION} statement or one of its synonyms.


@node Savepoints, LOCK TABLES, Implicit commit, Transactional Commands
@subsection @code{SAVEPOINT} and @code{ROLLBACK TO SAVEPOINT} Syntax

@findex SAVEPOINT
@findex ROLLBACK TO SAVEPOINT

@c help_category Transactions
@c description_for_help_topic SAVEPOINT  ROLLBACK TO SAVEPOINT
@example
SAVEPOINT identifier
ROLLBACK TO SAVEPOINT identifier
@end example

Starting from MySQL 4.0.14 and 4.1.1, @code{InnoDB} supports the SQL statements
@code{SAVEPOINT} and @code{ROLLBACK TO SAVEPOINT}.
@c end_description_for_help_topic

The @code{SAVEPOINT} statement sets a named transaction savepoint with a name
of @code{identifier}.  If the current transaction already has a savepoint
with the same name, the old savepoint is deleted and a new one is set.

The @code{ROLLBACK TO SAVEPOINT} statement rolls back a transaction to the
named savepoint.  Modifications that the current transaction made to rows
after the savepoint was set are undone in the rollback, but @code{InnoDB}
does @emph{not} release the row locks that were stored in memory after
the savepoint.  (Note that for a new inserted row, the lock information is
carried by the transaction ID stored in the row; the lock is not separately
stored in memory. In this case, the row lock is released in the undo.)
Savepoints that were set at a later time than the named savepoint are
deleted.

If the statement returns the following error, it means that
no savepoint with the specified name exists:

@example
ERROR 1181: Got error 153 during ROLLBACK
@end example

All savepoints of the current transaction are deleted if you execute a
@code{COMMIT}, or a @code{ROLLBACK} that does not name a savepoint.


@node LOCK TABLES, SET TRANSACTION, Savepoints, Transactional Commands
@subsection @code{LOCK TABLES} and @code{UNLOCK TABLES} Syntax

@findex LOCK TABLES
@findex UNLOCK TABLES

@c example_for_help_topic LOCK
@example
LOCK TABLES
    @var{tbl_name} [AS @var{alias}] @{READ [LOCAL] | [LOW_PRIORITY] WRITE@}
    [, @var{tbl_name} [AS @var{alias}] @{READ [LOCAL] | [LOW_PRIORITY] WRITE@}] ...
UNLOCK TABLES
@end example

@c description_for_help_topic LOCK  LOCK UNLOCK TABLES AS READ LOCAL LOW_PRIORITY WRITE
@code{LOCK TABLES} locks tables for the current thread.  @code{UNLOCK
TABLES} releases any locks held by the current thread.  All tables that
are locked by the current thread are implicitly unlocked when the
thread issues another @code{LOCK TABLES}, or when the connection to the
server is closed.
@c end_description_for_help_topic

@strong{Note 1}: @code{LOCK TABLES} is not transaction-safe and implicitly
commits any active transactions before attempting to lock the tables.
Also, beginning a transaction (for example, with @code{START TRANSACTION})
implicitly performs an @code{UNLOCK TABLES}.

@strong{Note 2}: The correct way to use @code{LOCK TABLES} with transactional
tables, like InnoDB, is to set @code{AUTOCOMMIT = 0} and not to call
@code{UNLOCK TABLES} until you commit the transaction explicitly.
When you call @code{LOCK TABLES}, InnoDB internally takes its own table
lock, and MySQL takes its own table lock. InnoDB releases its table lock at
the next commit, but for MySQL to release its table lock, you have to call
@code{UNLOCK TABLES}. You should not have @code{AUTOCOMMIT = 1}, because
then InnoDB releases its table lock immediately after the call of
@code{LOCK TABLES}, and deadlocks will very easily happen.

As of MySQL 4.0.2, to use @code{LOCK TABLES} you must have the
@code{LOCK TABLES} privilege and a @code{SELECT} privilege for the
involved tables. In MySQL 3.23, you must have @code{SELECT},
@code{INSERT}, @code{DELETE}, and @code{UPDATE} privileges for the
tables.

The main reasons to use @code{LOCK TABLES} are for emulating transactions
or to get more speed when updating tables.  This is explained in more
detail later.

If a thread obtains a @code{READ} lock on a table, that thread (and all other
threads) can only read from the table. If a thread obtains a @code{WRITE}
lock on a table, only the thread holding the lock can read from
or write to the table.  Other threads are blocked.

The difference between @code{READ LOCAL} and @code{READ} is that @code{READ
LOCAL} allows non-conflicting @code{INSERT} statements (concurrent inserts)
to execute while the lock is held.  However, this can't be used if you are
going to manipulate the database files outside MySQL while you hold the
lock.

When you use @code{LOCK TABLES}, you must lock all tables that you are going to
use in your queries.  While the locks obtained with a @code{LOCK TABLES}
statement are in effect, you cannot access any tables that were not locked by
the statement.  Also, you cannot use a locked table multiple times in one query
- use aliases for that.  Note that in that case you must get a lock for each
alias separately.

@example
mysql> LOCK TABLE t WRITE, t AS t1 WRITE;
mysql> INSERT INTO t SELECT * FROM t;
ERROR 1100: Table 't' was not locked with LOCK TABLES
mysql> INSERT INTO t SELECT * FROM t AS t1;
@end example

If your queries refer to a table using an alias, then you must lock the
table using that same alias.  It will not work to lock the table without
specifying the alias:

@example
mysql> LOCK TABLE t READ;
mysql> SELECT * FROM t AS myalias;
ERROR 1100: Table 'myalias' was not locked with LOCK TABLES
@end example

Conversely, if you lock a table using an alias, you must refer to it in
your queries using that alias:

@example
mysql> LOCK TABLE t AS myalias READ;
mysql> SELECT * FROM t;
ERROR 1100: Table 't' was not locked with LOCK TABLES
mysql> SELECT * FROM t AS myalias;
@end example

@code{WRITE} locks normally have higher priority than @code{READ} locks to
ensure that updates are processed as soon as possible. This means that if one
thread obtains a @code{READ} lock and then another thread requests a
@code{WRITE} lock, subsequent @code{READ} lock requests will wait until the
@code{WRITE} thread has gotten the lock and released it.  You can use
@code{LOW_PRIORITY WRITE} locks to allow other threads to obtain @code{READ}
locks while the thread is waiting for the @code{WRITE} lock. You should
use @code{LOW_PRIORITY WRITE} locks only if you are sure that there will
eventually be a time when no threads will have a @code{READ} lock.

@code{LOCK TABLES} works as follows:

@enumerate
@item
Sort all tables to be locked in an internally defined order. From the
user standpoint, this order is undefined.
@item
If a table is locked with a read and a write lock, put the write lock
before the read lock.
@item
Lock one table at a time until the thread gets all locks.
@end enumerate

This policy ensures that table locking is deadlock free. There are,
however, other things you need to be aware of about this policy:

If you are using a @code{LOW_PRIORITY WRITE} lock for a table, it
means only that MySQL will wait for this particular lock until
there are no threads that want a @code{READ} lock.  When the thread has
gotten the @code{WRITE} lock and is waiting to get the lock for the next
table in the lock table list, all other threads will wait for the
@code{WRITE} lock to be released.  If this becomes a serious problem
with your application, you should consider converting some of your
tables to transaction-safe tables.

You can safely use @code{KILL} to terminate a thread that is waiting for a
table lock.
@xref{KILL,  , @code{KILL}}.

Note that you should @emph{not} lock any tables that you are using with
@code{INSERT DELAYED} because in that case the @code{INSERT} is done by a
separate thread.

Normally, you don't have to lock tables, because all single @code{UPDATE} statements
are atomic; no other thread can interfere with any other currently executing
SQL statement. There are a few cases when you would like to lock tables
anyway:

@itemize @bullet
@item
If you are going to run many operations on a set of @code{MyISAM} tables,
it's much faster to lock the tables you are going to use.  Locking
@code{MyISAM} tables speeds up inserting, updating, or deleting on them.
The downside is that no thread can update a @code{READ}-locked table
(including the one holding the lock) and no thread can access a
@code{WRITE}-locked table other than the one holding the lock.

The reason some @code{MyISAM} operations are faster under @code{LOCK TABLES}
is that MySQL will not flush the key cache for the locked tables until
@code{UNLOCK TABLES} is called. Normally, the key cache is flushed after
each SQL statement.

@item
If you are using a storage engine in MySQL that doesn't support
transactions, you must use @code{LOCK TABLES} if you want to ensure that
no other thread comes between a @code{SELECT} and an @code{UPDATE}. The
example shown here requires @code{LOCK TABLES} to execute safely:

@example
mysql> LOCK TABLES trans READ, customer WRITE;
mysql> SELECT SUM(value) FROM trans WHERE customer_id=@var{some_id};
mysql> UPDATE customer
    ->     SET total_value=@var{sum_from_previous_statement}
    ->     WHERE customer_id=@var{some_id};
mysql> UNLOCK TABLES;
@end example

Without @code{LOCK TABLES}, it is possible that another thread might
insert a new row in the @code{trans} table between execution of the
@code{SELECT} and @code{UPDATE} statements.
@end itemize

You can avoid using @code{LOCK TABLES} in many cases
by using relative updates (@code{UPDATE customer SET
@var{value}=@var{value}+@var{new_value}}) or the @code{LAST_INSERT_ID()} function,
@xref{ANSI diff Transactions}.

You can also avoid locking tables in some cases by using the user-level
advisory lock functions @code{GET_LOCK()} and @code{RELEASE_LOCK()}.
These locks are saved in a hash table in the server and implemented with
@code{pthread_mutex_lock()} and @code{pthread_mutex_unlock()} for high speed.
@xref{Miscellaneous functions}.

See @ref{Internal locking}, for more information on locking policy.

You can lock all tables in all databases with read locks with the @code{FLUSH
TABLES WITH READ LOCK} statement. @xref{FLUSH,  , @code{FLUSH}}. This
is a very convenient way to get backups if you have a filesystem such as
Veritas that can take snapshots in time.

@strong{Note}: If you use @code{ALTER TABLE} on a locked table, it may become
unlocked. @xref{ALTER TABLE problems}.


@node SET TRANSACTION,  , LOCK TABLES, Transactional Commands
@subsection @code{SET TRANSACTION} Syntax

@findex SET TRANSACTION
@findex ISOLATION LEVEL

@c description_for_help_topic ISOLATION  TRANSACTION ISOLATION LEVEL GLOBAL SESSION READ COMMITTED UNCOMMITTED REPEATABLE SERIALIZABLE
@example
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
@{ READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE @}
@end example

This statement
sets the transaction isolation level for the next transaction, globally, or
for the current session.

The default behavior of @code{SET TRANSACTION} is to set the isolation level
for the next (not yet
started) transaction.  If you use the @code{GLOBAL} keyword, the statement
sets the default transaction level globally for all new connections
created from that point on. Existing connections are unaffected.
You need the @code{SUPER}
privilege to do this.  Using the @code{SESSION} keyword sets the
default transaction level for all future transactions performed on the
current connection.

For descriptions of each @code{InnoDB} transaction isolation level, see
@ref{InnoDB transaction isolation, @code{InnoDB} transaction isolation}.
@code{InnoDB} supports each of these levels
from MySQL 4.0.5 on. The default level is @code{REPEATABLE READ}.

You can set the initial default global isolation level for @command{mysqld} with
the @code{--transaction-isolation} option.
@xref{Server options}.


@c end_description_for_help_topic


@node Database Administration, Replication SQL, Transactional Commands, SQL Syntax
@section Database Administration Statements

@c TODO: This node should be renamed. There is a "MySQL Database
@c Administration" node already, which is too similar.


@menu
* Account management SQL::      Account Management Statements
* Table maintenance SQL::       Table Maintenance Statements
* SET OPTION::                  @code{SET} Syntax
* SHOW::                        @code{SHOW} Syntax
* Other administrative SQL::    Other Administrative Statements
@end menu

@c help_category Administration


@node Account management SQL, Table maintenance SQL, Database Administration, Database Administration
@subsection Account Management Statements

@menu
* DROP USER::                   @code{DROP USER} Syntax
* GRANT::                       @code{GRANT} and @code{REVOKE} Syntax
* SET PASSWORD::                @code{SET PASSWORD} Syntax
@end menu


@node DROP USER, GRANT, Account management SQL, Account management SQL
@subsubsection @code{DROP USER} Syntax

@findex DROP USER

@cindex privileges, deleting
@cindex privileges, dropping
@cindex dropping, user
@cindex user privileges, dropping
@cindex deleting, user
@cindex user privileges, deleting
@cindex deleting, users
@cindex users, deleting

@example
DROP USER user [, user] ...
@end example

The @code{DROP USER} statement deletes one or more MySQL accounts that
don't have any privileges.  It serves to remove each account record from
the @code{user} table. The account is named using the same format as for
@code{GRANT} or @code{REVOKE}; for example, @code{'jeffrey'@@'localhost'}.
The user and host parts of the account name correspond to the @code{User} and
@code{Host} column values of the @code{user} table record for the account.

To remove a MySQL user account, you should use the following procedure,
performing the steps in the order shown:

@enumerate
@item
Use @code{SHOW GRANTS} to determine what privileges the account has.
@xref{SHOW GRANTS,  , @code{SHOW GRANTS}}.
@item
Use @code{REVOKE} to revoke the privileges displayed by @code{SHOW GRANTS}.
This removes records for the account from all the grant tables except the
@code{user} table, and revokes any global privileges listed in the @code{user}
table.
@xref{GRANT,  , @code{GRANT}}.
@item
Delete the account by using @code{DROP USER} to remove the @code{user} table
record.
@end enumerate

The @code{DROP USER} statement was added in MySQL 4.1.1.  Before 4.1.1,
you should first revoke the account privileges as just described. Then
delete the @code{user} table record and flush the grant tables like this:

@example
mysql> DELETE FROM mysql.user
    -> WHERE User='@var{user_name}' and Host='@var{host_name}';
mysql> FLUSH PRIVILEGES;
@end example


@node GRANT, SET PASSWORD, DROP USER, Account management SQL
@subsubsection @code{GRANT} and @code{REVOKE} Syntax

@c TODO: This section has few useful examples

@findex GRANT
@findex REVOKE

@cindex privileges, granting
@cindex privileges, revoking
@cindex global privileges
@cindex revoking, privileges
@cindex granting, privileges

@c help_category Administration
@c example_for_help_topic GRANT
@example
GRANT @var{priv_type} [(@var{column_list})] [, @var{priv_type} [(@var{column_list})]] ...
    ON @{@var{tbl_name} | * | *.* | @var{db_name}.*@}
    TO @var{user} [IDENTIFIED BY [PASSWORD] '@var{password}']
        [, @var{user} [IDENTIFIED BY [PASSWORD] '@var{password}']] ...
    [REQUIRE
        NONE |
        [@{SSL| X509@}]
        [CIPHER '@var{cipher}' [AND]]
        [ISSUER '@var{issuer}' [AND]]
        [SUBJECT '@var{subject}']]
    [WITH [GRANT OPTION | MAX_QUERIES_PER_HOUR @var{count} |
                          MAX_UPDATES_PER_HOUR @var{count} |
                          MAX_CONNECTIONS_PER_HOUR @var{count}]]
@end example

@c example_for_help_topic REVOKE
@example
REVOKE @var{priv_type} [(@var{column_list})] [, @var{priv_type} [(@var{column_list})]] ...
    ON @{@var{tbl_name} | * | *.* | @var{db_name}.*@}
    FROM @var{user} [, @var{user}] ...

REVOKE ALL PRIVILEGES, GRANT OPTION FROM @var{user} [, @var{user}] ...
@end example

@c description_for_help_topic GRANT  ALL BY ALTER IDENTIFIED REQUIRE PASSWORD GRANT REVOKE ISSUER CIPHER WITH SUBJECT OPTION MAX_QUERIES_PER_HOUR MAX_UPDATES_PER_HOUR MAX_CONNECTIONS_PER_HOUR CLIENT EXECUTE FILE SSL X509 SECURITY USAGE SUPER NONE PROCESS PRIVILEGES REFERENCES RELOAD REPLICATION SHUTDOWN
The @code{GRANT} and @code{REVOKE} statements allow system administrators to
create MySQL user accounts and to grant rights to and revoke them from
accounts.  @code{GRANT} and @code{REVOKE} are implemented in MySQL 3.22.11
or later. For earlier MySQL versions, these statements do nothing.

MySQL account information is stored in the tables of the @code{mysql}
database. This database and the access control system are discussed
extensively in @ref{MySQL Database Administration}, which you should consult
for additional details.

Privileges can be granted at four levels:

@table @strong
@item Global level
Global privileges apply to all databases on a given server. These privileges
are stored in the @code{mysql.user} table.
@code{GRANT ALL ON *.*} and
@code{REVOKE ALL ON *.*} grant and revoke only global privileges.

@item Database level
Database privileges apply to all objects in a given database. These privileges
are stored in the @code{mysql.db} and @code{mysql.host} tables.
@code{GRANT ALL ON @var{db_name}.*} and
@code{REVOKE ALL ON @var{db_name}.*} grant and revoke only database privileges.

@item Table level
Table privileges apply to all columns in a given table. These privileges are
stored in the @code{mysql.tables_priv} table.
@code{GRANT ALL ON @var{db_name.tbl_name}} and
@code{REVOKE ALL ON @var{db_name.tbl_name}} grant and revoke only table privileges.

@item Column level
Column privileges apply to single columns in a given table. These privileges are
stored in the @code{mysql.columns_priv} table.
When using @code{REVOKE}, you must specify the same columns that were granted.
@end table
@c end_description_for_help_topic

To make it easy to revoke all privileges, MySQL 4.1.2 has added the
following syntax, which drops all global, database-, table-, and column-level
privileges for the named users:

@example
REVOKE ALL PRIVILEGES, GRANT OPTION FROM @var{user} [, @var{user}] ...
@end example

Before MySQL 4.1.2, all privileges cannot be dropped at once.
Two statements are necessary:

@example
REVOKE ALL PRIVILEGES ON *.* FROM @var{user} [, @var{user}] ...
REVOKE GRANT OPTION ON *.* FROM @var{user} [, @var{user}] ...
@end example


@c description_for_help_topic GRANT types
For the @code{GRANT} and @code{REVOKE} statements, @code{priv_type} can be
specified as any of the following:

@c FIX agl 2002-06-13 New table, need to measure colwidths!
@multitable @columnfractions .30 .70
@item @strong{Privilege} @tab @strong{Meaning}
@item @code{ALL [PRIVILEGES]} @tab Sets all simple privileges except @code{GRANT OPTION}
@item @code{ALTER}  @tab Allows use of @code{ALTER TABLE}
@item @code{CREATE} @tab Allows use of @code{CREATE TABLE}
@item @code{CREATE TEMPORARY TABLES} @tab Allows use of @code{CREATE TEMPORARY TABLE}
@item @code{CREATE VIEW} @tab Allows use of @code{CREATE VIEW}
@item @code{DELETE} @tab Allows use of @code{DELETE}
@item @code{DROP} @tab Allows use of @code{DROP TABLE}
@item @code{EXECUTE} @tab Allows the user to run stored procedures (MySQL 5.0)
@item @code{FILE} @tab Allows use of @code{SELECT ... INTO OUTFILE} and @code{LOAD DATA INFILE}
@item @code{INDEX} @tab Allows use of @code{CREATE INDEX} and @code{DROP INDEX}
@item @code{INSERT} @tab Allows use of @code{INSERT}
@item @code{LOCK TABLES} @tab Allows use of @code{LOCK TABLES} on tables for which you have the @code{SELECT} privilege
@item @code{PROCESS} @tab Allows use of @code{SHOW FULL PROCESSLIST}
@item @code{REFERENCES} @tab Not yet implemented
@item @code{RELOAD} @tab Allows use of @code{FLUSH}
@item @code{REPLICATION CLIENT} @tab Allows the user to ask where the slave or master servers are
@item @code{REPLICATION SLAVE} @tab Needed for replication slaves (to read binary log events from the master)
@item @code{SELECT} @tab Allows use of @code{SELECT}
@item @code{SHOW DATABASES} @tab @code{SHOW DATABASES} shows all databases
@item @code{SHOW VIEW} @tab Allows use of @code{SHOW CREATE VIEW}
@item @code{SHUTDOWN} @tab Allows use of @command{mysqladmin shutdown}
@item @code{SUPER} @tab Allows use of @code{CHANGE MASTER}, @code{KILL},
@code{PURGE MASTER LOGS}, and @code{SET GLOBAL} statements, the @command{mysqladmin debug} command; allows you to connect (once) even if @code{max_connections} is reached
@item @code{UPDATE} @tab Allows use of @code{UPDATE}
@item @code{USAGE} @tab Synonym for ``no privileges''
@item @code{GRANT OPTION} @tab Allows privileges to be granted
@end multitable
@c end_description_for_help_topic

@code{USAGE} can be used when you want to create a user that has no privileges.

Use @code{SHOW GRANTS} to determine what privileges the account has.
@xref{SHOW GRANTS,  , @code{SHOW GRANTS}}.

The @code{CREATE TEMPORARY TABLES}, @code{EXECUTE},
@code{LOCK TABLES}, @code{REPLICATION ...}, @code{SHOW DATABASES} and
@code{SUPER} privileges are new in MySQL 4.0.2.  To use them
after upgrading to 4.0.2 or later, you must upgrade your grant tables.
Similarly,
the @code{CREATE VIEW} and @code{SHOW VIEW}
privileges are new in MySQL 5.0.1.  To use them
after upgrading to 5.0.1 or later, you must upgrade your grant tables.
@xref{Upgrading-grant-tables}.

In older MySQL versions that do not have the @code{SUPER} privilege, the
@code{PROCESS} privilege can be used instead.

You can assign global privileges by using @code{ON *.*} syntax or
database privileges by using @code{ON @var{db_name}.*} syntax. If you specify
@code{ON *} and you have a current database, the privileges will be granted in
that database.  (@strong{Warning:} If you specify @code{ON *} and you
@emph{don't} have a current database, the privileges granted will be global!)

The @code{EXECUTION}, @code{FILE}, @code{PROCESS}, @code{RELOAD},
@code{REPLICATION CLIENT}, @code{REPLICATION SLAVE}, @code{SHOW DATABASES},
@code{SHUTDOWN}, and @code{SUPER} privileges are administrative privileges
that can only be granted globally (using @code{ON *.*} syntax).

Other privileges can be granted globally or at more specific levels.

The only @code{priv_type} values you can specify for a table are @code{SELECT},
@code{INSERT}, @code{UPDATE}, @code{DELETE}, @code{CREATE}, @code{DROP},
@code{GRANT OPTION}, @code{INDEX}, and @code{ALTER}.

The only @code{priv_type} values you can specify for a column (that is, when
you use a @code{column_list} clause) are @code{SELECT}, @code{INSERT}, and
@code{UPDATE}.

For the global, database, and table levels,
@code{GRANT ALL} assigns only the privileges that exist at the level you are
granting. For example, if you use @code{GRANT ALL ON @var{db_name}.*}, that is a
database-level statement, so none of the global-only privileges such as
@code{FILE} will be granted.

For column-level privileges (that is, when you specify @var{column_list}),
you must explicitly name the privileges to be granted. You cannot use
@code{ALL} as a privilege specifier.

MySQL allows you to create database-level privileges even if the database
doesn't exist, to make it easy to prepare for database use.  However, MySQL
currently does not allow you to create table-level or column-level
privileges if the table doesn't exist.

MySQL does not automatically revoke any privileges even if you drop a table
or drop a database.

@strong{Note}: the @samp{_} and @samp{%} wildcards are allowed when
specifying database names in @code{GRANT} statements that grant privileges at
the global or database levels. This means, for example, that if you
want to use a @samp{_} character as part of a database name,
you should specify it as @samp{\_} in the @code{GRANT} statement, to prevent
the user from being able to access additional databases matching the
wildcard pattern; for example, @code{GRANT ... ON `foo\_bar`.* TO ...}.

In order to accommodate granting rights to users from arbitrary hosts,
MySQL supports specifying the @var{user} value in the form
@code{@var{user_name}@@@var{host_name}}.  If you want to specify a @var{user_name} string
containing special characters (such as @samp{-}), or a @var{host_name} string
containing special characters or wildcard characters (such as @samp{%}), you
can quote the username or hostname (for example,
@code{'test-user'@@'test-hostname'}). Quote the username and hostname
separately.

You can specify wildcards in the hostname.  For example,
@code{@var{user_name}@@'%.loc.gov'} applies to @var{user_name} for any host in the
@code{loc.gov} domain, and @code{@var{user_name}@@'144.155.166.%'} applies to
@var{user_name} for any host in the @code{144.155.166} class C subnet.

The simple form @var{user_name} is a synonym for @code{@var{user_name}@@'%'}.

MySQL doesn't support wildcards in usernames.  Anonymous users are
defined by inserting entries with @code{User=''} into the
@code{mysql.user} table or creating a user with an empty name with the
@code{GRANT} statement:

@example
mysql> GRANT ALL ON test.* TO ''@@'localhost' ...
@end example

When specifying quoted values, quote database, table, or column names as
identifiers, using backticks (@samp{`}).
Quote hostnames, usernames, or passwords as strings, using apostrophes
(@samp{'}).

@strong{Warning:} If you allow anonymous users to connect to the MySQL
server, you should also grant privileges to all local users as
@code{@var{user_name}@@localhost}. Otherwise, the anonymous-user account for
the local host in the @code{mysql.user} table will be used when named users
try to log in to the MySQL server from the local machine!
(This anonymous-user account is created during MySQL installation.)

You can determine whether this applies to you by executing the following query:

@example
mysql> SELECT Host, User FROM mysql.user WHERE User='';
@end example

If you want to delete the local anonymous-user account to avoid the problem
just described, use these statements:

@example
mysql> DELETE FROM mysql.user WHERE Host='localhost' AND User='';
mysql> FLUSH PRIVILEGES;
@end example

@c TODO: actually, Db, tbl_name, Column_name now are 64 characters...

For the moment, @code{GRANT} only supports host, table, database, and
column names up to 60 characters long. A username can be up to 16
characters.

The privileges for a table or column are formed additively from the
logical OR of the privileges at each of the four privilege
levels.  For example, if the @code{mysql.user} table specifies that a
user has a global @code{SELECT} privilege, the privilege cannot be denied by an
entry at the database, table, or column level.

The privileges for a column can be calculated as follows:

@example
global privileges
OR (database privileges AND host privileges)
OR table privileges
OR column privileges
@end example

In most cases, you grant rights to a user at only one of the privilege
levels, so life isn't normally this complicated. The details of the
privilege-checking procedure are presented in
@ref{Privilege system}.

If you grant privileges for a username/hostname combination that does not exist
in the @code{mysql.user} table, an entry is added and remains there until
deleted with a @code{DELETE} statement.  In other words, @code{GRANT} may
create @code{user} table entries, but @code{REVOKE} will not remove them;
you must do that explicitly using @code{DROP USER} or @code{DELETE}.

@cindex passwords, setting
In MySQL 3.22.12 or later,
if a new user is created or if you have global grant privileges, the user's
password is set to the password specified by the @code{IDENTIFIED BY}
clause, if one is given.  If the user already had a password, it is replaced
by the new one.

@strong{Warning:} If you create a new user but do not specify an
@code{IDENTIFIED BY} clause, the user has no password.  This is insecure.
As of MySQL 5.0.2, you can enable the @code{NO_AUTO_CREATE_USER} SQL mode
to prevent @code{GRANT} from creating new users if it would otherwise do so,
unless @code{IDENTIFIED BY} is given to provide a password.

Passwords can also be set with the @code{SET PASSWORD} statement.
@xref{SET PASSWORD, , @code{SET PASSWORD}}.

In the @code{IDENTIFIED BY} clause, the password should be given as the
literal password value.  It is unnecessary to use the @code{PASSWORD()}
function as it is for the @code{SET PASSWORD} statement. For example:

@example
GRANT ... IDENTIFIED BY 'mypass';
@end example

If you don't want to send the password in clear text and you know the hashed
value that @code{PASSWORD()} would return for the password, you can specify
the hashed value preceded by the keyword @code{PASSWORD}:

@example
GRANT ... IDENTIFIED BY PASSWORD '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4';
@end example

In a C program, you can get the hashed value by using the
@code{make_scrambled_password()} C API function.

If you grant privileges for a database, an entry in the @code{mysql.db}
table is created if needed. If all privileges for the database are
removed with @code{REVOKE}, this entry is deleted.

If a user has no privileges for a table, the table name is not displayed
when the user requests a list of tables (for example, with a @code{SHOW TABLES}
statement). If a user has no privileges for a database, the database name
is not displayed by @code{SHOW DATABASES} unless the user has the @code{SHOW
DATABASES} privilege.

The @code{WITH GRANT OPTION} clause gives the user the ability to give
to other users any privileges the user has at the specified privilege level.
You should be careful to whom you give the @code{GRANT OPTION} privilege,
because two users with different privileges may be able to join privileges!

You cannot grant another user a privilege you don't have yourself; the
@code{GRANT OPTION} privilege allows you to give away only those privileges
you possess.

Be aware that when you grant a user the @code{GRANT OPTION} privilege at a
particular privilege level, any privileges the user already possesses (or
is given in the future!) at that level are also grantable by that user.
Suppose that you grant a user the @code{INSERT} privilege on a database.  If
you then grant the @code{SELECT} privilege on the database and specify
@code{WITH GRANT OPTION}, the user can give away not only the @code{SELECT}
privilege, but also @code{INSERT}.  If you then grant the @code{UPDATE}
privilege to the user on the database, the user can give away
@code{INSERT}, @code{SELECT}, and @code{UPDATE}.

You should not grant @code{ALTER} privileges to a normal user.  If you
do that, the user can try to subvert the privilege system by renaming
tables!

The @code{MAX_QUERIES_PER_HOUR count}, @code{MAX_UPDATES_PER_HOUR count},
and @code{MAX_CONNECTIONS_PER_HOUR count} options are new in MySQL 4.0.2.
They limit the number of queries, updates, and logins a user can perform
during one hour. If @code{count} is 0 (the default), this means there is no
limitation for that user. @xref{User resources}.  Note: To specify any of
these options for an existing user without affecting existing privileges,
use @code{GRANT USAGE ON *.* ... WITH MAX_...}.

@cindex SSL related options
@findex REQUIRE GRANT option

MySQL can check X509 certificate attributes in addition to the usual
authentication that is based on the username and password.  To specify
SSL-related options for a MySQL account, use the @code{REQUIRE} clause of
the @code{GRANT} statement.
(For background on the use of SSL with MySQL, see @ref{Secure connections}.)

There are different possibilities for limiting connection types for an account:

@itemize @bullet
@item
If an account has no SSL or X509 requirements, unencrypted connections are
allowed if the username and password are valid. However, encrypted
connections also can be used at the client's option, if the client has the
proper certificate and key files.

@item
The @code{REQUIRE SSL} option tells the server to allow only SSL-encrypted
connections for the account. Note that this option can be omitted
if there are any access-control records that allow non-SSL connections.

@example
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@@'localhost'
    -> IDENTIFIED BY 'goodsecret' REQUIRE SSL;
@end example

@item
@code{REQUIRE X509} means that the client must have a valid certificate
but that the exact certificate, issuer, and subject do not matter.
The only requirement is that it should be possible to verify its
signature with one of the CA certificates.

@example
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@@'localhost'
    -> IDENTIFIED BY 'goodsecret' REQUIRE X509;
@end example

@item
@code{REQUIRE ISSUER 'issuer'} places the restriction on connection attempts
that the client must present a valid X509 certificate issued by CA
@code{'issuer'}.  If the client presents a certificate that is valid but has
a different issuer, the server rejects the connection.  Use of X509
certificates always implies encryption, so the @code{SSL} option is
unneccessary.

@c TODO: isn't preceding sentence also true for X509, SUBJECT, and CIPHER?

@example
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@@'localhost'
    -> IDENTIFIED BY 'goodsecret'
    -> REQUIRE ISSUER '/C=FI/ST=Some-State/L=Helsinki/
       O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@@example.com';
@end example

Note that the @code{ISSUER} value should be entered as a single string.

@item
@code{REQUIRE SUBJECT 'subject'} places the restriction on connection
attempts that the client must present a valid X509 certificate with subject
@code{'subject'} in it.  If the client presents a certificate that is valid
but has a different subject, the server rejects the connection.

@example
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@@'localhost'
    -> IDENTIFIED BY 'goodsecret'
    -> REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/
       O=MySQL demo client certificate/
       CN=Tonu Samuel/Email=tonu@@example.com';
@end example

Note that the @code{SUBJECT} value should be entered as a single string.

@item
@code{REQUIRE CIPHER 'cipher'} is needed to ensure that strong enough ciphers
and key lengths will be used. SSL itself can be weak if old algorithms
with short encryption keys are used. Using this option, you can ask for
some exact cipher method to allow a connection.

@example
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@@'localhost'
    -> IDENTIFIED BY 'goodsecret'
    -> REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA';
@end example

@end itemize

The @code{SUBJECT}, @code{ISSUER}, and @code{CIPHER} options can be
combined in the @code{REQUIRE} clause like this:

@example
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@@'localhost'
    -> IDENTIFIED BY 'goodsecret'
    -> REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/
       O=MySQL demo client certificate/
       CN=Tonu Samuel/Email=tonu@@example.com'
    -> AND ISSUER '/C=FI/ST=Some-State/L=Helsinki/
       O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@@example.com'
    -> AND CIPHER 'EDH-RSA-DES-CBC3-SHA';
@end example

Note that the @code{SUBJECT} and @code{ISSUER} values each should be entered
as a single string.

Starting from MySQL 4.0.4, the @code{AND} keyword is optional between
@code{REQUIRE} options.

The order of the options does not matter, but no option can be specified
twice.

When @command{mysqld} starts, all privileges are read into memory.
Database, table, and column privileges take effect at once, and
user-level privileges take effect the next time the user connects.
Modifications to the grant tables that you perform using @code{GRANT} or
@code{REVOKE} are noticed by the server immediately.
If you modify the grant tables manually (using @code{INSERT}, @code{UPDATE},
and so on), you should execute a @code{FLUSH PRIVILEGES} statement or run
@command{mysqladmin flush-privileges} to tell the server to reload the grant
tables.
@xref{Privilege changes}.

Note that if you are using table or column privileges for even one user, the
server examines table and column privileges for all users and this slows
down MySQL a bit.  Similarly, if you limit the number of queries, updates,
or connections for any users, the server must monitor these values.

@cindex Standard SQL, differences from
The biggest differences between the standard SQL and MySQL versions of
@code{GRANT} are:

@itemize @bullet
@item
In MySQL, privileges are associated with a username/hostname combination
and not with only a username.

@item
Standard SQL doesn't have global or database-level privileges, nor does it 
support all the privilege types that MySQL supports.

@item
MySQL doesn't support the standard SQL @code{TRIGGER} or @code{UNDER}
privileges.

@item
Standard SQL privileges are structured in a hierarchical manner. If you remove
a user, all privileges the user has been granted are revoked. In
MySQL, the granted privileges are not automatically revoked;
you must revoke them yourself.

@item
With standard SQL, when you drop a table, all privileges for the table are
revoked.  With standard SQL, when you revoke a privilege, all privileges
that were granted based on the privilege are also revoked. In MySQL,
privileges can be dropped only with explicit @code{REVOKE} statements or
by manipulating the MySQL grant tables.

@item
In MySQL, if you have the @code{INSERT} privilege on only some of the
columns in a table, you can execute @code{INSERT} statements on the
table; the columns for which you don't have the @code{INSERT} privilege
will be set to their default values. Standard SQL requires you to have the
@code{INSERT} privilege on all columns.

@end itemize


@node SET PASSWORD,  , GRANT, Account management SQL
@subsubsection @code{SET PASSWORD} Syntax

@findex SET PASSWORD

@cindex passwords, setting
@cindex setting passwords

@c help_category Administration
@c example_for_help_topic SET PASSWORD
@example
SET PASSWORD = PASSWORD('@var{some password}')
SET PASSWORD FOR @var{user} = PASSWORD('@var{some password}')
@end example

The @code{SET PASSWORD} statement assigns a password to an existing
MySQL user account.

The first syntax sets the password for the current user. Any client that has
connected to the server using a non-anonymous account can change the password
for that account.

@c TODO: "with access to"? Which privilege, exactly? UPDATE?

The second syntax sets the password for a specific account on the current
server host. Only clients with access to the @code{mysql} database can do
this.  The @var{user} value should be given in @code{@var{user_name}@@@var{host_name}}
format, where @var{user_name} and @var{host_name} are exactly as they are
listed in the @code{User} and @code{Host} columns of the @code{mysql.user}
table entry.  For example, if you had an entry with @code{User} and
@code{Host} column values of @code{'bob'} and @code{'%.loc.gov'}, you would
write the statement like this:

Starting from MySQL 4.1 you can check your current authentication
@code{user@@host} entry by executing @code{SELECT current_user()}..

@example
mysql> SET PASSWORD FOR 'bob'@@'%.loc.gov' = PASSWORD('@var{newpass}');
@end example

That is equivalent to the following statements:

@example
mysql> UPDATE mysql.user SET Password=PASSWORD('@var{newpass}')
    -> WHERE User='bob' AND Host='%.loc.gov';
mysql> FLUSH PRIVILEGES;
@end example

@strong{Note}: If you are connecting to a MySQL 4.1 or later server
using a pre-4.1 client program, do not use the above @code{UPDATE}
statement without reading @ref{Password hashing} first. The password
format changed in MySQL 4.1, and under certain circumstances it is
possible that if you change your password, you might not be able to
connect to the server afterward.


@node Table maintenance SQL, SET OPTION, Account management SQL, Database Administration
@subsection Table Maintenance Statements

@menu
* ANALYZE TABLE::               @code{ANALYZE TABLE} Syntax
* BACKUP TABLE::                @code{BACKUP TABLE} Syntax
* CHECK TABLE::                 @code{CHECK TABLE} Syntax
* CHECKSUM TABLE::              @code{CHECKSUM TABLE} Syntax
* OPTIMIZE TABLE::              @code{OPTIMIZE TABLE} Syntax
* REPAIR TABLE::                @code{REPAIR TABLE} Syntax
* RESTORE TABLE::               @code{RESTORE TABLE} Syntax
@end menu


@node ANALYZE TABLE, BACKUP TABLE, Table maintenance SQL, Table maintenance SQL
@subsubsection @code{ANALYZE TABLE} Syntax

@findex ANALYZE TABLE

@c example_for_help_topic ANALYZE
@example
ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE @var{tbl_name} [, @var{tbl_name}] ...
@end example

@c description_for_help_topic ANALYZE  TABLE NO_WRITE_TO_BINLOG LOCAL
This statement analyzes and stores the key distribution for a table.
During the analysis, the table is locked with a read lock.  This works on
@code{MyISAM} and @code{BDB} tables and (as of MySQL 4.0.13) @code{InnoDB}
tables. For @code{MyISAM} tables, this
statement is equivalent to using @command{myisamchk -a}.

MySQL uses the stored key distribution to decide the order in which
tables should be joined when you perform a join on something other than a
constant.
@c end_description_for_help_topic

The statement returns a table with the following columns:

@multitable @columnfractions .15 .60
@item @strong{Column} @tab @strong{Value}
@item @code{Table} @tab The table name
@item @code{Op} @tab Always @code{analyze}
@item @code{Msg_type} @tab One of @code{status}, @code{error}, @code{info}, or @code{warning}
@item @code{Msg_text} @tab The message
@end multitable

You can check the stored key distribution with the @code{SHOW INDEX} statement.
@xref{SHOW INDEX,  , @code{SHOW INDEX}}.

If the table hasn't changed since the last @code{ANALYZE TABLE} statement,
the table will not be analyzed again.

Before MySQL 4.1.1, @code{ANALYZE TABLE} statements are not written
to the binary log. As of MySQL 4.1.1, they are written to the binary
log unless the optional @code{NO_WRITE_TO_BINLOG} keyword 
(or its alias @code{LOCAL}) is used.


@node BACKUP TABLE, CHECK TABLE, ANALYZE TABLE, Table maintenance SQL
@subsubsection @code{BACKUP TABLE} Syntax

@findex BACKUP TABLE

@cindex backups, database

@c example_for_help_topic BACKUP TABLE
@example
BACKUP TABLE @var{tbl_name} [, @var{tbl_name}] ... TO '@var{/path/to/backup/directory}'
@end example

@c description_for_help_topic BACKUP TABLE  BACKUP TABLE
@strong{Note}: This statement is deprecated. We are working on a better
replacement for it that will provide online backup capabilities.
In the meantime, the @command{mysqlhotcopy} script can be used instead.

@code{BACKUP TABLE} copies to the backup directory the minimum number of
table files needed to restore the table, after flushing any buffered changes
to disk. The statement works only for @code{MyISAM} tables.  It copies the
@file{.frm} definition  and @file{.MYD} data files. The @file{.MYI}
index file can be rebuilt from those two files.
The directory should be specified as a full pathname.
@c end_description_for_help_topic

Before using this statement, please see @ref{Backup}.

During the backup, a read lock is held for each table, one at time,
as they are being backed up. If you want to back up several tables as
a snapshot (preventing any of them from being changed during the backup
operation), you must first issue a @code{LOCK TABLES} statement to obtain a read
lock for every table in the group.

The statement returns a table with the following columns:

@multitable @columnfractions .15 .60
@item @strong{Column} @tab @strong{Value}
@item @code{Table} @tab The table name
@item @code{Op} @tab Always @code{backup}
@item @code{Msg_type} @tab One of @code{status}, @code{error}, @code{info}, or @code{warning}
@item @code{Msg_text} @tab The message
@end multitable

@code{BACKUP TABLE} is available in MySQL 3.23.25 and later.


@node CHECK TABLE, CHECKSUM TABLE, BACKUP TABLE, Table maintenance SQL
@subsubsection @code{CHECK TABLE} Syntax

@findex CHECK TABLE

@c example_for_help_topic CHECK
@example
CHECK TABLE @var{tbl_name} [, @var{tbl_name}] ... [@var{option}] ...

@var{option} = @{QUICK | FAST | MEDIUM | EXTENDED | CHANGED@}
@end example

@c description_for_help_topic CHECK  TABLE QUICK FAST MEDIUM EXTENDED CHANGED
@code{CHECK TABLE} works only on @code{MyISAM} and @code{InnoDB} tables. On
@code{MyISAM} tables, This is the same thing as running @command{myisamchk
--medium-check @var{tbl_name}} on the table.

If you don't specify any option, @code{MEDIUM} is used.
@c end_description_for_help_topic

Checks the table or tables for errors. For @code{MyISAM} tables, the key statistics
are updated. The statement returns a table with the following columns:

@multitable @columnfractions .15 .60
@item @strong{Column} @tab @strong{Value}
@item @code{Table}    @tab The table name
@item @code{Op}       @tab Always @code{check}
@item @code{Msg_type} @tab One of @code{status}, @code{error}, @code{info}, or @code{warning}
@item @code{Msg_text} @tab The message
@end multitable

Note that the statement might produce many rows of information for each
checked table.  The last row will have a @code{Msg_type} value of
@code{status} and the @code{Msg_text} normally should be @code{OK}.  If you
don't get @code{OK}, or @code{Table is already up to date} you should
normally run a repair of the table. @xref{Table maintenance}. @code{Table is
already up to date} means that the storage engine for the table indicated
that there was no need to check the table.

The different check options are as follows:

@multitable @columnfractions .15 .85
@item @strong{Type} @tab @strong{Meaning}
@item @code{QUICK} @tab Don't scan the rows to check for incorrect links.
@item @code{FAST}  @tab Only check tables that haven't been closed properly.
@item @code{CHANGED} @tab Only check tables that have been changed since the last check or haven't been closed properly.
@item @code{MEDIUM} @tab Scan rows to verify that deleted links are okay. This also calculates a key checksum for the rows and verifies this with a calculated checksum for the keys.
@item @code{EXTENDED} @tab Do a full key lookup for all keys for each row.  This ensures that the table is 100% consistent, but will take a long time!
@end multitable

These options apply only to checking @code{MyISAM} tables and are ignored for
@code{InnoDB} tables.

If none of the options @code{QUICK}, @code{MEDIUM}, or @code{EXTENDED}
are specified, the default check type for dynamic-format @code{MyISAM}
tables is @code{MEDIUM}.  The default check type also is @code{MEDIUM} for
static-format @code{MyISAM} tables, unless @code{CHANGED} or @code{FAST}
is specified.  In that case, the default is @code{QUICK}. The row scan
is skipped for @code{CHANGED} and @code{FAST} because the rows are very
seldom corrupted.

You can combine check options, as in the following example, which does
a quick check on the table to see whether it was
closed properly:

@example
CHECK TABLE test_table FAST QUICK;
@end example

@strong{Note}: In some cases, @code{CHECK TABLE} will change the
table!  This happens if the table is marked as ``corrupted'' or ``not
closed properly'' but @code{CHECK TABLE} doesn't find any problems in the
table.  In this case, @code{CHECK TABLE} marks the table as okay.

If a table is corrupted, it's most likely that the problem is in
the indexes and not in the data part.  All of the preceding check types
check the indexes thoroughly and should thus find most errors.

If you just want to check a table that you assume is okay, you should use
no check options or the @code{QUICK} option. The latter should be used
when you are in a hurry and can take the very small risk that
@code{QUICK} doesn't find an error in the data file. (In most cases,
MySQL should find, under normal usage, any error in the data file.
If this happens, the table is marked as ``corrupted'' and cannot
be used until it's repaired.)

@code{FAST} and @code{CHANGED} are mostly intended to be used from a
script (for example, to be executed from @command{cron}) if you want to check your
table from time to time. In most cases, @code{FAST} is to be preferred
over @code{CHANGED}.  (The only case when it isn't preferred is when you suspect
that you have found a bug in the @code{MyISAM} code.)

@code{EXTENDED} is to be used only after you have run a normal check but
still get strange errors from a table when MySQL tries to
update a row or find a row by key. (This is very unlikely if a
normal check has succeeded!)

Some problems reported by @code{CHECK TABLE} can't be corrected automatically:

@itemize @bullet
@item
@code{Found row where the auto_increment column has the value 0}.

This means that you have a row in the table where the
@code{AUTO_INCREMENT} index column contains the value 0.
(It's possible to create a row where the @code{AUTO_INCREMENT} column is 0 by
explicitly setting the column to 0 with an @code{UPDATE} statement.)

This isn't an error in itself, but could cause trouble if you decide to
dump the table and restore it or do an @code{ALTER TABLE} on the
table. In this case, the @code{AUTO_INCREMENT} column will change value
according to the rules of @code{AUTO_INCREMENT} columns, which could cause
problems such as a duplicate-key error.

To get rid of the warning, just execute an @code{UPDATE} statement
to set the column to some other value than 0.
@end itemize


@node CHECKSUM TABLE, OPTIMIZE TABLE, CHECK TABLE, Table maintenance SQL
@subsubsection @code{CHECKSUM TABLE} Syntax
@findex CHECKSUM TABLE

@c example_for_help_topic CHECKSUM
@example
CHECKSUM TABLE @var{tbl_name} [, @var{tbl_name}] ... [ QUICK | EXTENDED ]
@end example

@c description_for_help_topic CHECKSUM

Reports a table checksum.

If @code{QUICK} is specified, the live table checksum is reported if it is
available, or @code{NULL} otherwise.  This is very fast.  A live checksum
is enabled by specifying the @code{CHECKSUM=1} table option, currently
supported only for @code{MyISAM} tables.
@xref{CREATE TABLE,  , @code{CREATE TABLE}}.

In @code{EXTENDED} mode the whole table is read row by row and the checksum
is calculated. This can be very slow for large tables.

By default, if neither @code{QUICK} nor @code{EXTENDED} is specified, MySQL
returns a live checksum if the table storage engine supports it and scans
the table otherwise.

This statement is implemented in MySQL 4.1.1.


@node OPTIMIZE TABLE, REPAIR TABLE, CHECKSUM TABLE, Table maintenance SQL
@subsubsection @code{OPTIMIZE TABLE} Syntax

@c TODO: output from statement?

@findex OPTIMIZE TABLE

@cindex tables, defragmenting
@cindex tables, fragmentation

@c example_for_help_topic OPTIMIZE
@example
OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE @var{tbl_name} [, @var{tbl_name}] ...
@end example

@c description_for_help_topic OPTIMIZE  NO_WRITE_TO_BINLOG LOCAL TABLE
@code{OPTIMIZE TABLE} should be used if you have deleted a large part of a
table or if you have made many changes to a table with variable-length rows
(tables that have @code{VARCHAR}, @code{BLOB}, or @code{TEXT} columns).
Deleted records are maintained in a linked list and subsequent @code{INSERT}
operations reuse old record positions. You can use @code{OPTIMIZE TABLE} to
reclaim the unused space and to defragment the data file.
@c end_description_for_help_topic

In most setups, you need not run @code{OPTIMIZE TABLE} at all.  Even
if you do a lot of updates to variable-length rows, it's not likely that
you need to do this more than once a week or month and only on certain
tables.

For the moment, @code{OPTIMIZE TABLE} works only on @code{MyISAM},
@code{BDB} and @code{InnoDB} tables. For @code{BDB} tables, @code{OPTIMIZE
TABLE} is currently mapped to @code{ANALYZE TABLE}. It was also the case for
@code{InnoDB} tables before MySQL 4.1.3; starting from this version it is
mapped to @code{ALTER TABLE}.
@xref{ANALYZE TABLE, , @code{ANALYZE TABLE}}.

You can get @code{OPTIMIZE TABLE} to work on other table types by starting
@command{mysqld} with the @code{--skip-new} or @code{--safe-mode} option;
in this case, @code{OPTIMIZE TABLE} is just mapped to @code{ALTER TABLE}.

@code{OPTIMIZE TABLE} works as follows:
@enumerate
@item
If the table has deleted or split rows, repair the table.
@item
If the index pages are not sorted, sort them.
@item
If the statistics are not up to date (and the repair couldn't be done
by sorting the index), update them.
@end enumerate

Note that MySQL locks the table during the time @code{OPTIMIZE TABLE} is
running.

Before MySQL 4.1.1, @code{OPTIMIZE TABLE} statements are not written
to the binary log. As of MySQL 4.1.1, they are written to the binary
log unless the optional @code{NO_WRITE_TO_BINLOG} keyword 
(or its alias @code{LOCAL}) is used.


@node REPAIR TABLE, RESTORE TABLE, OPTIMIZE TABLE, Table maintenance SQL
@subsubsection @code{REPAIR TABLE} Syntax

@findex REPAIR TABLE

@c example_for_help_topic REPAIR
@example
REPAIR [LOCAL | NO_WRITE_TO_BINLOG] TABLE
    @var{tbl_name} [, @var{tbl_name}] ... [QUICK] [EXTENDED] [USE_FRM]
@end example

@c description_for_help_topic REPAIR  USE_FRM TABLE QUICK EXTENDED NO_WRITE_TO_BINLOG LOCAL
@code{REPAIR TABLE} repairs a possibly corrupted table.
By default,
it has the same effect as @command{myisamchk --recover @var{tbl_name}}.
@code{REPAIR TABLE} works only on @code{MyISAM} tables.
@c end_description_for_help_topic

Normally you should never have to run this statement. However, if disaster
strikes, @code{REPAIR TABLE} is very likely to get back all your data from
a @code{MyISAM} table.  If your tables become corrupted often, you should try
to find the reason for it, to eliminate the need to use @code{REPAIR TABLE}.
@xref{Crashing}.  @xref{MyISAM table problems,  , @code{MyISAM} table problems}.

The statement returns a table with the following columns:

@multitable @columnfractions .15 .60
@item @strong{Column} @tab @strong{Value}
@item @code{Table} @tab The table name
@item @code{Op} @tab Always @code{repair}
@item @code{Msg_type} @tab One of @code{status}, @code{error}, @code{info}, or @code{warning}
@item @code{Msg_text} @tab The message
@end multitable

The @code{REPAIR TABLE} statement might produce many rows of information
for each repaired table.  The last row will have a @code{Msg_type} value of
@code{status} and @code{Msg_test} normally should be @code{OK}.  If you
don't get @code{OK}, you should try repairing the table with @command{myisamchk
--safe-recover}, because @code{REPAIR TABLE} does not yet implement all the
options of @command{myisamchk}. We plan to make it more flexible in the future.

If @code{QUICK} is given, @code{REPAIR TABLE} tries to repair
only the index tree.  This type of repair is like that done by
@command{myisamchk --recover --quick}.

If you use @code{EXTENDED}, MySQL creates the index row by row instead of
creating one index at a time with sorting.  (Before MySQL 4.1, this might
be better than sorting on fixed-length keys if you have long @code{CHAR}
keys that compress very well.)  This type of repair is like that done by
@command{myisamchk --safe-recover}.

As of MySQL 4.0.2, there is a @code{USE_FRM} mode for @code{REPAIR TABLE}.
Use it if the @file{.MYI} index file is missing or if its header is
corrupted.  In this mode, MySQL will re-create the @file{.MYI} file using
information from the @file{.frm} file. This kind of repair cannot be done
with @command{myisamchk}. @strong{Note}: Use this mode @strong{only} if you cannot
use regular @code{REPAIR} modes. @file{.MYI} header contains important
table metadata (in particular, current @code{AUTO_INCREMENT} value
and @code{Delete link}) that will be lost in @code{REPAIR ... USE_FRM}.
Don't use @code{USE_FRM} if the table is compressed, as this information
is also stored in @file{.MYI} file.

Before MySQL 4.1.1, @code{REPAIR TABLE} statements are not written
to the binary log. As of MySQL 4.1.1, they are written to the binary
log unless the optional @code{NO_WRITE_TO_BINLOG} keyword 
(or its alias @code{LOCAL}) is used.

@strong{Warning:} If the server dies during a @code{REPAIR TABLE} operation,
it's essential after restarting it that you immediately execute another
@code{REPAIR TABLE} statement for the table before performing any other
operations on it. (It's always good to start by making a backup.)  In the
worst case, you might have a new clean index file without information about
the data file, and then the next operation you perform could overwrite the
data file.  This is an unlikely, but possible scenario.

@node RESTORE TABLE,  , REPAIR TABLE, Table maintenance SQL
@subsubsection @code{RESTORE TABLE} Syntax

@findex RESTORE TABLE

@c description_for_help_topic RESTORE  TABLE

@example
RESTORE TABLE @var{tbl_name} [, @var{tbl_name}] ... FROM '@var{/path/to/backup/directory}'
@end example

Restores the table or tables from a backup that was made with @code{BACKUP
TABLE}. Existing tables will not be overwritten; if you try to restore over
an existing table, you will get an error.  Just as @code{BACKUP TABLE},
@code{RESTORE TABLE} currently works only for @code{MyISAM} tables.
The directory should be specified as a full pathname.

The backup for each table consists of its @file{.frm} format file and
@file{.MYD} data file. The restore operation restores those files, then
uses them to rebuild the @file{.MYI} index file.  Restoring takes longer
than backing up due to the need to rebuild the indexes. The more indexes the
table has, the longer it will take.
@c end_description_for_help_topic

The statement returns a table with the following columns:

@multitable @columnfractions .15 .60
@item @strong{Column} @tab @strong{Value}
@item @code{Table} @tab The table name
@item @code{Op} @tab Always @code{restore}
@item @code{Msg_type} @tab One of @code{status}, @code{error}, @code{info}, or @code{warning}
@item @code{Msg_text} @tab The message
@end multitable


@node SET OPTION, SHOW, Table maintenance SQL, Database Administration
@subsection @code{SET} Syntax

@findex SET
@findex SET OPTION

@c help_category Data Manipulation

@c example_for_help_topic SET
@example
SET @var{variable_assignment} [, @var{variable_assignment}] ...

@var{variable_assignment}:
      @var{user_var_name} = @var{expr}
    | [GLOBAL | SESSION] @var{system_var_name} = @var{expr}
    | @@@@[global. | session.]@var{system_var_name} = @var{expr}
@end example

@c description_for_help_topic SET  GLOBAL SESSION VARIABLE
@code{SET} sets different types of variables that affect the operation of the
server or your client. It can be used to assign values to user variables or
system variables.
@c end_description_for_help_topic

The @code{SET PASSWORD} statement for assigning account passwords is
described in
@xref{SET PASSWORD,  , @code{SET PASSWORD}}.

In MySQL 4.0.3, we added the @code{GLOBAL} and @code{SESSION} options
and allowed most important system variables to be changed dynamically at
runtime.
The system variables that you can set at runtime are described in
@ref{Dynamic System Variables}.

In older versions of MySQL, @code{SET OPTION} is used instead of @code{SET},
but this is now deprecated; just leave out the word @code{OPTION}.

The following example show the different syntaxes you can use to set
variables.

A user variable is written as @code{@@@var{var_name}} and can be set as follows:

@example
SET @@@var{var_name} = @var{expr};
@end example

Further information about user variables is given in @ref{Variables}.

System variables can be referred to in @code{SET} statements as
@var{var_name}. The name optionally can be preceded by @code{GLOBAL} or
@code{@@@@global.} to indicate explicitly that the variable is a global
variable, or by @code{SESSION}, @code{@@@@session.}, or @code{@@@@} to
indicate that it is a session variable.  @code{LOCAL} and @code{@@@@local.}
are synonyms for @code{SESSION} and @code{@@@@session.}. If no modifier is
present, @code{SET} sets the session variable.

The @code{@@@@@var{var_name}} syntax for system variables is supported to make
MySQL syntax compatible with some other database systems.

If you set several system variables in the same statement, the last used
@code{GLOBAL} or @code{SESSION} option is used for variables that have no mode
specified.

@example
SET sort_buffer_size=10000;
SET @@@@local.sort_buffer_size=10000;
SET GLOBAL sort_buffer_size=1000000, SESSION sort_buffer_size=1000000;
SET @@@@sort_buffer_size=1000000;
SET @@@@global.sort_buffer_size=1000000, @@@@local.sort_buffer_size=1000000;
@end example

If you set a system variable using @code{SESSION} (the default), the value
remains in effect until the current session ends or until you set the
variable to a different value. If you set a system variable using
@code{GLOBAL}, which requires the @code{SUPER} privilege, the value is
remembered and used for new connections until the server restarts. If you
want to make a variable setting permanent, you should put it in an option
file.  @xref{Option files}.

To prevent incorrect usage, MySQL produces an error if you use @code{SET
GLOBAL} with a variable that can only be used with @code{SET SESSION} or if
you do not specify @code{GLOBAL} when setting a global variable.

If you want to set a @code{SESSION} variable to the @code{GLOBAL} value or a
@code{GLOBAL} value to the compiled-in MySQL default value, you can set it to
@code{DEFAULT}. For example, the following two statements are identical in
setting the session value of @code{max_join_size} to the global value:

@example
SET max_join_size=DEFAULT;
SET @@@@session.max_join_size=@@@@global.max_join_size;
@end example

You can get a list of most system variables with @code{SHOW VARIABLES}.
@xref{SHOW VARIABLES,  , @code{SHOW VARIABLES}}.
To get a specific variable name or list of names that match a pattern, use a
@code{LIKE} clause:

@example
SHOW VARIABLES LIKE 'max_join_size';
SHOW GLOBAL VARIABLES LIKE 'max_join_size';
@end example

You can also get the value for a specific value by using the
@code{@@@@[global.|local.]var_name} syntax with @code{SELECT}:

@example
SELECT @@@@max_join_size, @@@@global.max_join_size;
@end example

When you retrieve a variable with @code{SELECT @@@@var_name} (that is, you
do not specify @code{global.}, @code{session.}, or @code{local.}), MySQL returns
the @code{SESSION} value if it exists and the @code{GLOBAL} value otherwise.

The following list describes variables that have non-standard syntax or that are
not described in the list of system variables that is found in
@ref{Server system variables}.
Although these variables are not displayed by @code{SHOW VARIABLES}, you can
obtain their values with @code{SELECT} (with the exception of @code{CHARACTER
SET} and @code{SET NAMES}). For example:

@example
mysql> SELECT @@@@AUTOCOMMIT;
+--------------+
| @@@@autocommit |
+--------------+
|            1 |
+--------------+
@end example

@c TODO: Move this list to server config chapter?

@table @code

@item AUTOCOMMIT = @{0 | 1@}
Set the autocommit mode.
If set to @code{1}, all changes to a table take effect immediately.
If set to @code{0}, you have to use @code{COMMIT} to accept a transaction or
@code{ROLLBACK} to cancel it.  If you change @code{AUTOCOMMIT}
mode from @code{0} to @code{1}, MySQL performs an automatic @code{COMMIT}
of any open transaction.  Another way to begin a transaction is to use a
@code{START TRANSACTION} or @code{BEGIN} statement.
@xref{COMMIT,  , @code{COMMIT}}.

@item BIG_TABLES = @{0 | 1@}
@cindex table is full
If set to @code{1}, all temporary tables are stored on disk rather than in
memory.  This is a little slower, but the error @code{The table @var{tbl_name} is
full} will not occur for @code{SELECT} operations that require a large
temporary table.  The default value for a new connection is
@code{0} (use in-memory temporary tables).  As of MySQL 4.0, you
should normally never need to set this variable, because MySQL automatically
converts in-memory tables to disk-based tables as necessary.  This variable
previously was named @code{SQL_BIG_TABLES}.

@c TODO: discuss optional collation

@item CHARACTER SET @{@var{charset_name} | DEFAULT@}
This maps all strings from and to the client with the given mapping.
Before MySQL 4.1, the only allowable value for @var{charset_name}
is @code{cp1251_koi8}, but you can add new mappings by editing the
@file{sql/convert.cc} file in the MySQL source distribution.  As of MySQL
4.1.1, @code{SET CHARACTER SET} sets three session system variables:
@code{character_set_client} and @code{character_set_results} are set to
the given character set, and @code{character_set_connection} to the value
of @code{character_set_database}.

The default mapping can be restored by using a value of @code{DEFAULT}.

Note that the syntax for @code{SET CHARACTER SET} differs
from that for setting most other options.

@c THIS IS NOT IMPLEMENTED
@c @item DATE_FORMAT = @var{format_str}
@c Determines how the server converts @code{DATE} values to strings. This
@c variable is available as a global, local, or command-line
@c option. @var{format_str} can be specified conveniently using the
@c @code{GET_FORMAT()} function.
@c @xref{Date and time functions}.

@c THIS IS NOT IMPLEMENTED
@c @item DATETIME_FORMAT = @var{format_str}
@c Determines how the server converts @code{DATETIME} values to
@c strings. This variable is available as a global, local, or command-line
@c option. @var{format_str} can be specified conveniently using the
@c @code{GET_FORMAT()} function.
@c @xref{Date and time functions}.

@item FOREIGN_KEY_CHECKS = @{0 | 1@}
If set to @code{1} (the default), foreign key constraints for @code{InnoDB}
tables are checked.  If set to @code{0}, they are ignored.  Disabling foreign
key checking can be useful for reloading @code{InnoDB} tables in an order
different than that required by their parent/child relationships.
This variable was added in MySQL 3.23.52.
@xref{InnoDB foreign key constraints,  , @code{InnoDB} foreign key constraints}.

@item IDENTITY = @var{value}
The variable is a synonym for the @code{LAST_INSERT_ID} variable.
It exists for compatibility with other databases.
As of MySQL 3.23.25, you can read its value with @code{SELECT @@@@IDENTITY}.
As of MySQL 4.0.3, you can also set its value with @code{SET IDENTITY}.

@item INSERT_ID = @var{value}
Set the value to be used by the following @code{INSERT} or @code{ALTER TABLE}
statement when inserting an @code{AUTO_INCREMENT} value.  This is mainly used
with the binary log.

@item LAST_INSERT_ID = @var{value}
Set the value to be returned from @code{LAST_INSERT_ID()}. This is stored in
the binary log when you use @code{LAST_INSERT_ID()} in a statement that updates
a table. Setting this variable does not update theh value returned by the
@code{mysql_insert_id()} C API function.

@c TODO: discuss optional collation

@item NAMES @{'@var{charset_name}' | DEFAULT@}
@code{SET NAMES} sets the three session system variables
@code{character_set_client}, @code{character_set_connection}, and
@code{character_set_results} to the given character set.

The default mapping can be restored by using a value of @code{DEFAULT}.

Note that the syntax for @code{SET NAMES} differs
from that for setting most other options.
This statement is available as of MySQL 4.1.0.

@item SQL_AUTO_IS_NULL = @{0 | 1@}
If set to @code{1} (the default), you can find the last inserted row for a table
that contains an @code{AUTO_INCREMENT} column by using the following construct:

@example
WHERE @var{auto_increment_column} IS NULL
@end example

This behavior is used by some ODBC programs, such as Access.
@code{SQL_AUTO_IS_NULL} was added in MySQL 3.23.52.

@item SQL_BIG_SELECTS = @{0 | 1@}
If set to @code{0}, MySQL aborts @code{SELECT} statements
that probably will take a very long time (that is, statements for which
the optimizer estimates that the number of examined rows will
exceed the value of @code{max_join_size}).
This is useful when an inadvisable @code{WHERE} statement has been
issued.  The default value for a new connection is @code{1}, which allows
all @code{SELECT} statements.

If you set the @code{max_join_size} system variable to a value other than
@code{DEFAULT}, @code{SQL_BIG_SELECTS} will be set to @code{0}.

@item SQL_BUFFER_RESULT = @{0 | 1@}
@code{SQL_BUFFER_RESULT} forces results from @code{SELECT} statements
to be put into temporary tables. This helps MySQL free the
table locks early and can be beneficial in cases where it takes a long time to
send results to the client.
This variable was added in MySQL 3.23.13.

@item SQL_LOG_BIN = @{0 | 1@}
If set to @code{0}, no logging is done to the binary log for the client.
The client must have the @code{SUPER} privilege to set this option.
This variable was added in MySQL 3.23.16.

@item SQL_LOG_OFF = @{0 | 1@}
If set to @code{1}, no logging is done to the general query log for this
client.  The client must have the @code{SUPER} privilege to set this option.

@item SQL_LOG_UPDATE = @{0 | 1@}
If set to @code{0}, no logging is done to the update log for the client.
The client must have the @code{SUPER} privilege to set this option.
This variable was added in MySQL 3.22.5.
Starting from MySQL 5.0.0, it is deprecated and is mapped to
@code{SQL_LOG_BIN} (@pxref{News-5.0.0}).

@item SQL_QUOTE_SHOW_CREATE = @{0 | 1@}
If set to @code{1}, @code{SHOW CREATE TABLE} quotes table and column
names. If set to @code{0}, quoting is disabled.  This option is enabled
by default so that replication will work for tables with table and column
names that require quoting.
This variable was added in MySQL 3.23.26.
@ref{SHOW CREATE TABLE, , @code{SHOW CREATE TABLE}}.

@item SQL_SAFE_UPDATES = @{0 | 1@}
If set to @code{1}, MySQL aborts @code{UPDATE} or @code{DELETE} statements
that do not use a key in the @code{WHERE} clause or a @code{LIMIT} clause.
This makes it possible to catch @code{UPDATE} or @code{DELETE} statements
where keys are not used properly and that would probably change or delete a
large number of rows.
This variable was added in MySQL 3.22.32.

@item SQL_SELECT_LIMIT = @{@var{value} | DEFAULT@}
The maximum number of records to return from @code{SELECT} statements.  The
default value for a new connection is ``unlimited.'' If you have changed the
limit, the default value can be restored by using a @code{SQL_SELECT_LIMIT}
value of @code{DEFAULT}.

If a @code{SELECT} has a @code{LIMIT} clause, the @code{LIMIT} takes
precedence over the value of @code{SQL_SELECT_LIMIT}.

@item SQL_WARNINGS = @{0 | 1@}
This variable controls whether single-row @code{INSERT} statements produce
an information string if warnings occur.  The default is 0.  Set the value
to 1 to produce an information string.
This variable was added in MySQL 3.22.11.

@item TIMESTAMP = @{@var{timestamp_value} | DEFAULT@}
Set the time for this client.  This is used to get the original timestamp if
you use the binary log to restore rows.  @code{timestamp_value} should be a
Unix epoch timestamp, not a MySQL timestamp.

@c THIS IS NOT IMPLEMENTED
@c @item TIME_FORMAT = @var{format_str}
@c Determines how the server converts @code{TIME} values to strings. This
@c variable is available as a global, local, or command-line
@c option. @var{format_str} can be specified conveniently using the
@c @code{GET_FORMAT()} function.
@c @xref{Date and time functions}.

@item UNIQUE_CHECKS = @{0 | 1@}
If set to @code{1} (the default), uniqueness checks for secondary indexes in
@code{InnoDB} tables are performed. If set to @code{0}, uniqueness
checks are not done for index entries inserted into InnoDB's insert
buffer. If you know for certain that your data does not contain
uniqueness violations, you can set this to 0 to speed up large table
imports to InnoDB. This variable was added in MySQL 3.23.52.

@end table


@node SHOW, Other administrative SQL, SET OPTION, Database Administration
@subsection @code{SHOW} Syntax

@c FIX more index hits needed

@cindex displaying, information, @code{SHOW}
@findex Database information, obtaining
@findex SHOW COLUMNS
@findex SHOW CREATE DATABASE
@findex SHOW CREATE SCHEMA
@findex SHOW CREATE TABLE
@findex SHOW DATABASES
@findex SHOW SCHEMAS
@findex SHOW ENGINES
@findex SHOW ERRORS
@findex SHOW FIELDS
@findex SHOW GRANTS
@findex SHOW INDEX
@findex SHOW INNODB STATUS
@findex SHOW KEYS
@findex SHOW PRIVILEGES
@findex SHOW PROCESSLIST
@findex SHOW STATUS
@findex SHOW TABLES
@findex SHOW TABLE STATUS
@findex SHOW ENGINES
@findex SHOW TABLE TYPES
@findex SHOW VARIABLES
@findex SHOW WARNINGS

@c description_for_help_topic SHOW  COLUMNS LIKE TABLES OPEN FROM INDEX INDEXES STATUS VARIABLES DATABASE SCHEMA DATABASES SCHEMAS LOGS FULL PROCESSLIST FOR GRANTS TABLE CREATE WARNINGS ERRORS TYPES FIELDS HOSTS KEYS ENGINES INNODB

@code{SHOW} has many forms that provide information about databases,
tables, columns, or status information about the server.
This section describes those following:

@c example_for_help_topic SHOW
@example
SHOW [FULL] COLUMNS FROM @var{tbl_name} [FROM @var{db_name}] [LIKE '@var{pattern}']
SHOW CREATE DATABASE @var{db_name}
SHOW CREATE TABLE @var{tbl_name}
SHOW DATABASES [LIKE '@var{pattern}']
SHOW [STORAGE] ENGINES
SHOW ERRORS [LIMIT [@var{offset},] @var{row_count}]
SHOW GRANTS FOR @var{user}
SHOW INDEX FROM @var{tbl_name} [FROM @var{db_name}]
SHOW INNODB STATUS
SHOW [BDB] LOGS
SHOW PRIVILEGES
SHOW [FULL] PROCESSLIST
SHOW STATUS [LIKE '@var{pattern}']
SHOW TABLE STATUS [FROM @var{db_name}] [LIKE '@var{pattern}']
SHOW [OPEN] TABLES [FROM @var{db_name}] [LIKE '@var{pattern}']
SHOW [GLOBAL | SESSION] VARIABLES [LIKE '@var{pattern}']
SHOW WARNINGS [LIMIT [@var{offset},] @var{row_count}]
@end example

If the syntax for a given @code{SHOW} statement includes a @code{LIKE
'@var{pattern}'} part, @code{'@var{pattern}'} is a string that can contain the SQL @samp{%}
and @samp{_} wildcard characters.
The pattern is useful for restricting statement output to matching values.
@c end_description_for_help_topic

Note that there are other forms of these statements described elsewhere:

@itemize @bullet

@item
The @code{SHOW} statement has forms that provide information about
replication master and slave servers:

@findex SHOW BINLOG EVENTS
@findex SHOW MASTER LOGS
@findex SHOW MASTER STATUS
@findex SHOW SLAVE HOSTS
@findex SHOW SLAVE STATUS

@example
SHOW BINLOG EVENTS
SHOW MASTER LOGS
SHOW MASTER STATUS
SHOW SLAVE HOSTS
SHOW SLAVE STATUS
@end example

These forms of @code{SHOW} are described in @ref{Replication SQL}.

@end itemize

@menu
* SHOW CHARACTER SET::          @code{SHOW CHARACTER SET} Syntax
* SHOW COLLATION::              @code{SHOW COLLATION} Syntax
* SHOW COLUMNS::                @code{SHOW COLUMNS} Syntax
* SHOW CREATE DATABASE::        @code{SHOW CREATE DATABASE} Syntax
* SHOW CREATE TABLE::           @code{SHOW CREATE TABLE} Syntax
* SHOW CREATE VIEW::            @code{SHOW CREATE VIEW} Syntax
* SHOW DATABASES::              @code{SHOW DATABASES} Syntax
* SHOW ENGINES::                @code{SHOW ENGINES} Syntax
* SHOW ERRORS::                 @code{SHOW ERRORS} Syntax
* SHOW GRANTS::                 @code{SHOW GRANTS} Syntax
* SHOW INDEX::                  @code{SHOW INDEX} Syntax
* SHOW INNODB STATUS::          @code{SHOW INNODB STATUS} Syntax
* SHOW LOGS::                   @code{SHOW LOGS} Syntax
* SHOW PRIVILEGES::             @code{SHOW PRIVILEGES} Syntax
* SHOW PROCESSLIST::            @code{SHOW PROCESSLIST} Syntax
* SHOW STATUS::                 @code{SHOW STATUS} Syntax
* SHOW TABLE STATUS::           @code{SHOW TABLE STATUS} Syntax
* SHOW TABLES::                 @code{SHOW TABLES} Syntax
* SHOW VARIABLES::              @code{SHOW VARIABLES} Syntax
* SHOW WARNINGS::               @code{SHOW WARNINGS} Syntax
@end menu

@node SHOW CHARACTER SET, SHOW COLLATION, SHOW, SHOW
@subsubsection @code{SHOW CHARACTER SET} Syntax

@findex SHOW CHARACTER SET

@example
SHOW CHARACTER SET [LIKE '@var{pattern}']
@end example

The @code{SHOW CHARACTER SET} statement shows all available character sets.
It takes an optional @code{LIKE} clause that indicates which character set
names to match. For example:

@example
mysql> SHOW CHARACTER SET LIKE 'latin%';
+---------+-----------------------------+-------------------+--------+
| Charset | Description                 | Default collation | Maxlen |
+---------+-----------------------------+-------------------+--------+
| latin1  | ISO 8859-1 West European    | latin1_swedish_ci |      1 |
| latin2  | ISO 8859-2 Central European | latin2_general_ci |      1 |
| latin5  | ISO 8859-9 Turkish          | latin5_turkish_ci |      1 |
| latin7  | ISO 8859-13 Baltic          | latin7_general_ci |      1 |
+---------+-----------------------------+-------------------+--------+
@end example

The @code{Maxlen} column shows the maximum number of bytes used to
store one character.

@code{SHOW CHARACTER SET} is available as of MySQL 4.1.0.


@node SHOW COLLATION, SHOW COLUMNS, SHOW CHARACTER SET, SHOW
@subsubsection @code{SHOW COLLATION} Syntax

@findex SHOW COLLATION

@example
SHOW COLLATION [LIKE '@var{pattern}']
@end example

The output from @code{SHOW COLLATION} includes all available character
sets.
It takes an optional @code{LIKE} clause that indicates which collation
names to match. For example:

@example
mysql> SHOW COLLATION LIKE 'latin1%';
+-------------------+---------+----+---------+----------+---------+
| Collation         | Charset | Id | Default | Compiled | Sortlen |
+-------------------+---------+----+---------+----------+---------+
| latin1_german1_ci | latin1  |  5 |         |          |       0 |
| latin1_swedish_ci | latin1  |  8 | Yes     | Yes      |       0 |
| latin1_danish_ci  | latin1  | 15 |         |          |       0 |
| latin1_german2_ci | latin1  | 31 |         | Yes      |       2 |
| latin1_bin        | latin1  | 47 |         | Yes      |       0 |
| latin1_general_ci | latin1  | 48 |         |          |       0 |
| latin1_general_cs | latin1  | 49 |         |          |       0 |
| latin1_spanish_ci | latin1  | 94 |         |          |       0 |
+-------------------+---------+----+---------+----------+---------+
@end example

The @code{Default} column indicates whether a collation is the
default for its character set.
@code{Compiled} indicates whether the character set is
compiled into the server.
@code{Sortlen} is related to the amount of memory required to sort strings
expressed in the character set.

@code{SHOW COLLATION} is available as of MySQL 4.1.0.


@node SHOW COLUMNS, SHOW CREATE DATABASE, SHOW COLLATION, SHOW
@subsubsection @code{SHOW COLUMNS} Syntax

@c TODO: need description of SHOW COLUMNS output columns

@cindex displaying, information, @code{SHOW}
@findex SHOW COLUMNS

@example
SHOW [FULL] COLUMNS FROM @var{tbl_name} [FROM @var{db_name}] [LIKE '@var{pattern}']
@end example

@code{SHOW COLUMNS} lists the columns in a given table.  If the column types
differ from what you expect them to be based on your @code{CREATE TABLE}
statement, note that MySQL sometimes changes column types when you create or
alter a table.  The conditions for which this occurs are described in
@ref{Silent column changes}.

The @code{FULL} keyword can be used from MySQL 3.23.32 on. It causes the
output to include the privileges you have for each column.  As of MySQL 4.1,
@code{FULL} also causes any per-column comments to be displayed.

You can use @var{db_name.tbl_name} as an alternative to the @code{@var{tbl_name}
FROM @var{db_name}} syntax.  These two statements are equivalent:

@example
mysql> SHOW COLUMNS FROM mytable FROM mydb;
mysql> SHOW COLUMNS FROM mydb.mytable;
@end example

@code{SHOW FIELDS} is a synonym for @code{SHOW COLUMNS}.  You can also
list a table's columns with the @command{mysqlshow @var{db_name} @var{tbl_name}} command.

The @code{DESCRIBE} statement provides information similar to
@code{SHOW COLUMNS}.
@xref{DESCRIBE, , @code{DESCRIBE}}.


@node SHOW CREATE DATABASE, SHOW CREATE TABLE, SHOW COLUMNS, SHOW
@subsubsection @code{SHOW CREATE DATABASE} Syntax

@findex SHOW CREATE DATABASE
@findex SHOW CREATE SCHEMA

@example
SHOW CREATE @{DATABASE | SCHEMA@} @var{db_name}
@end example

Shows a @code{CREATE DATABASE} statement that will create the given
database.  It was added in MySQL 4.1.  @code{SHOW CREATE SCHEMA} can be used
as of MySQL 5.0.2.

@example
mysql> SHOW CREATE DATABASE test\G
*************************** 1. row ***************************
       Database: test
Create Database: CREATE DATABASE `test`
                 /*!40100 DEFAULT CHARACTER SET latin1 */
@end example


@node SHOW CREATE TABLE, SHOW CREATE VIEW, SHOW CREATE DATABASE, SHOW
@subsubsection @code{SHOW CREATE TABLE} Syntax

@findex SHOW CREATE TABLE

@example
SHOW CREATE TABLE @var{tbl_name}
@end example

Shows a @code{CREATE TABLE} statement that will create the given table.
It was added in MySQL 3.23.20.

@example
mysql> SHOW CREATE TABLE t\G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE t (
  id INT(11) default NULL auto_increment,
  s char(60) default NULL,
  PRIMARY KEY (id)
) TYPE=MyISAM

@end example

@code{SHOW CREATE TABLE} quotes table and column names according to
the value of the @code{SQL_QUOTE_SHOW_CREATE} option.
@ref{SET OPTION, , @code{SET SQL_QUOTE_SHOW_CREATE}}.


@node SHOW CREATE VIEW, SHOW DATABASES, SHOW CREATE TABLE, SHOW
@subsubsection @code{SHOW CREATE VIEW} Syntax

@findex SHOW CREATE VIEW

@c example_for_help_topic SHOW CREATE VIEW
@example
SHOW CREATE VIEW @var{view_name}
@end example

@c description_for_help_topic SHOW CREATE VIEW
This statement shows a @code{CREATE VIEW} statement that will create
the given view.
@c end_description_for_help_topic

@example
mysql> SHOW CREATE VIEW v;
+-------+----------------------------------------------------+
| Table | Create Table                                       |
+-------+----------------------------------------------------+
| v     | CREATE VIEW `test`.`v` AS select 1 AS `a`,2 AS `b` |
+-------+----------------------------------------------------+
@end example

This statement was added in MySQL 5.0.1.


@node SHOW DATABASES, SHOW ENGINES, SHOW CREATE VIEW, SHOW
@subsubsection @code{SHOW DATABASES} Syntax

@findex SHOW DATABASES
@findex SHOW SCHEMAS

@example
SHOW @{DATABASES | SCHEMAS@} [LIKE '@var{pattern}']
@end example

@code{SHOW DATABASES} lists the databases on the MySQL server host.
You can also get this list using the @command{mysqlshow} command.
As of MySQL 4.0.2, you will see only those databases for which you have some
kind of privilege, if you don't have the global @code{SHOW DATABASES}
privilege.

If the server was started with the @code{--skip-show-database} option, you
cannot use this statement at all unless you have the @code{SHOW DATABASES}
privilege.

@code{SHOW SCHEMAS} can be used as of MySQL 5.0.2


@node SHOW ENGINES, SHOW ERRORS, SHOW DATABASES, SHOW
@subsubsection @code{SHOW ENGINES} Syntax

@findex SHOW ENGINES
@findex SHOW STORAGE ENGINES
@findex SHOW TABLE TYPES

@example
SHOW [STORAGE] ENGINES
@end example

@code{SHOW ENGINES} shows you status information about the storage engines.
This is particularly useful for checking whether a storage engine is
supported, or to see what the default engine is.
This statement is implemented in MySQL 4.1.2.
@code{SHOW TABLE TYPES} is a deprecated synonym.

@example
mysql> SHOW ENGINES\G
*************************** 1. row ***************************
 Engine: MyISAM
Support: DEFAULT
Comment: Default engine as of MySQL 3.23 with great performance
*************************** 2. row ***************************
 Engine: HEAP
Support: YES
Comment: Alias for MEMORY
*************************** 3. row ***************************
 Engine: MEMORY
Support: YES
Comment: Hash based, stored in memory, useful for temporary tables
*************************** 4. row ***************************
 Engine: MERGE
Support: YES
Comment: Collection of identical MyISAM tables
*************************** 5. row ***************************
 Engine: MRG_MYISAM
Support: YES
Comment: Alias for MERGE
*************************** 6. row ***************************
 Engine: ISAM
Support: NO
Comment: Obsolete storage engine, now replaced by MyISAM
*************************** 7. row ***************************
 Engine: MRG_ISAM
Support: NO
Comment: Obsolete storage engine, now replaced by MERGE
*************************** 8. row ***************************
 Engine: InnoDB
Support: YES
Comment: Supports transactions, row-level locking, and foreign keys
*************************** 9. row ***************************
 Engine: INNOBASE
Support: YES
Comment: Alias for INNODB
*************************** 10. row ***************************
 Engine: BDB
Support: YES
Comment: Supports transactions and page-level locking
*************************** 11. row ***************************
 Engine: BERKELEYDB
Support: YES
Comment: Alias for BDB
*************************** 12. row ***************************
 Engine: NDBCLUSTER
Support: YES
Comment: Clustered, fault-tolerant, memory-based tables
*************************** 13. row ***************************
 Engine: NDB
Support: YES
Comment: Alias for NDBCLUSTER
*************************** 14. row ***************************
 Engine: EXAMPLE
Support: YES
Comment: Example storage engine
*************************** 15. row ***************************
 Engine: ARCHIVE
Support: YES
Comment: Archive storage engine
@end example

A @code{Support} value indicates whether the particular storage engine is
supported, and which is the default engine. For example, if the server
is started with the @code{--default-table-type=InnoDB} option, then
the @code{Support} value for the @code{InnoDB} row will have the value
@code{DEFAULT}.


@node SHOW ERRORS, SHOW GRANTS, SHOW ENGINES, SHOW
@subsubsection @code{SHOW ERRORS} Syntax

@findex SHOW ERRORS

@example
SHOW ERRORS [LIMIT [@var{offset},] @var{row_count}]
SHOW COUNT(*) ERRORS
@end example

This statement is similar to @code{SHOW WARNINGS}, except that instead
of displaying errors, warnings, and notes, it displays only errors.
@code{SHOW ERRORS} is available as of MySQL 4.1.0.

The @code{LIMIT} clause has the same syntax as for the @code{SELECT}
statement.
@xref{SELECT,  , @code{SELECT}}.

The @code{SHOW COUNT(*) ERRORS} statement displays the number of errors.
You can also retrieve this number from the @code{error_count} variable:

@example
SHOW COUNT(*) ERRORS;
SELECT @@@@error_count;
@end example

For more information, see @ref{SHOW WARNINGS,  , @code{SHOW WARNINGS}}.


@node SHOW GRANTS, SHOW INDEX, SHOW ERRORS, SHOW
@subsubsection @code{SHOW GRANTS} Syntax

@cindex privileges, display
@findex GRANTS
@findex SHOW GRANTS

@example
SHOW GRANTS FOR @var{user}
@end example

This statement lists the @code{GRANT} statements that must be issued to
duplicate the privileges for a MySQL user account.

@example
mysql> SHOW GRANTS FOR 'root'@@'localhost';
+---------------------------------------------------------------------+
| Grants for root@@localhost                                           |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@@'localhost' WITH GRANT OPTION |
+---------------------------------------------------------------------+
@end example

As of MySQL 4.1.2, to list privileges for the current session, you can use
any of the following statements:

@example
SHOW GRANTS;
SHOW GRANTS FOR CURRENT_USER;
SHOW GRANTS FOR CURRENT_USER();
@end example

Before MySQL 4.1.2,  you can find out what user the
session was authenticated as by selecting the value
of the @code{CURRENT_USER()} function (new in MySQL 4.0.6).
Then use that value in the @code{SHOW GRANTS} statement.
@xref{Information functions, ,@code{CURRENT_USER()}}.

@code{SHOW GRANTS} is available as of MySQL 3.23.4.


@node SHOW INDEX, SHOW INNODB STATUS, SHOW GRANTS, SHOW
@subsubsection @code{SHOW INDEX} Syntax

@cindex displaying, information, @code{SHOW}
@findex SHOW INDEX
@findex SHOW KEYS

@example
SHOW INDEX FROM @var{tbl_name} [FROM @var{db_name}]
@end example

@code{SHOW INDEX} returns table index information in a format that
resembles the @code{SQLStatistics} call in ODBC.

@code{SHOW INDEX} returns the following fields:

@table @code

@item Table
The name of the table.

@item Non_unique
0 if the index can't contain duplicates, 1 if it can.

@item Key_name
The name of the index.

@item Seq_in_index
The column sequence number in the index, starting with 1.

@item Column_name
The column name.

@cindex displaying, information, Collation

@item Collation
How the column is sorted in the index. In MySQL, this can have values
@samp{A} (Ascending) or @code{NULL} (Not sorted).

@cindex displaying, information, Cardinality

@item Cardinality
The number of unique values in the index.  This is updated by running
@code{ANALYZE TABLE} or @command{myisamchk -a}.  @code{Cardinality} is counted
based on statistics stored as integers, so it's not necessarily accurate for
small tables. The higher the cardinality, the greater the chance that MySQL
will use the index when doing joins.

@item Sub_part
The number of indexed characters if the column is only partly indexed.
@code{NULL} if the entire column is indexed.

@item Packed
Indicates how the key is packed.  @code{NULL} if it is not.

@item Null
Contains @code{YES} if the column may contain @code{NULL}, @code{''}
if not.

@item Index_type
The index method used (@code{BTREE}, @code{FULLTEXT}, @code{HASH},
@code{RTREE}).

@item Comment
Various remarks.  Before MySQL 4.0.2 when the @code{Index_type} column was
added, @code{Comment} indicates whether an index is @code{FULLTEXT}.

@end table

The @code{Packed} and @code{Comment} columns were added in MySQL 3.23.0.
The @code{Null} and @code{Index_type} columns were added in MySQL 4.0.2.

You can use @var{db_name.tbl_name} as an alternative to the @code{@var{tbl_name}
FROM @var{db_name}} syntax.  These two statements are equivalent:

@example
mysql> SHOW INDEX FROM mytable FROM mydb;
mysql> SHOW INDEX FROM mydb.mytable;
@end example

@code{SHOW KEYS} is a synonym for @code{SHOW INDEX}.  You can also list
a table's indexes with the @command{mysqlshow -k @var{db_name} @var{tbl_name}} command.


@node SHOW INNODB STATUS, SHOW LOGS, SHOW INDEX, SHOW
@subsubsection @code{SHOW INNODB STATUS} Syntax

@example
SHOW INNODB STATUS
@end example

This statement shows extensive information about the state of the
@code{InnoDB} storage engine.


@node SHOW LOGS, SHOW PRIVILEGES, SHOW INNODB STATUS, SHOW
@subsubsection @code{SHOW LOGS} Syntax

@example
SHOW [BDB] LOGS
@end example

@code{SHOW LOGS} displays status information about existing log files.
It was implemented in MySQL 3.23.29. Currently, it displays only information
about Berkeley DB log files, so an alias for it (available as of MySQL
4.1.1) is @code{SHOW BDB LOGS}.

@code{SHOW LOGS} returns the following fields:

@table @code

@item File
The full path to the log file.

@item Type
The log file type (@code{BDB} for Berkeley DB log files).

@item Status
The status of the log file (@code{FREE} if the file can be removed, or
@code{IN USE} if the file is needed by the transaction subsystem)

@end table


@node SHOW PRIVILEGES, SHOW PROCESSLIST, SHOW LOGS, SHOW
@subsubsection @code{SHOW PRIVILEGES} Syntax

@findex SHOW PRIVILEGES

@example
SHOW PRIVILEGES
@end example


@code{SHOW PRIVILEGES} shows the list of system privileges that the underlying 
MySQL server supports.
This statement is implemented as of MySQL 4.1.0.

@example
mysql> SHOW PRIVILEGES\G
*************************** 1. row ***************************
Privilege: Select
  Context: Tables
  Comment: To retrieve rows from table
*************************** 2. row ***************************
Privilege: Insert
  Context: Tables
  Comment: To insert data into tables
*************************** 3. row ***************************
Privilege: Update
  Context: Tables
  Comment: To update existing rows 
*************************** 4. row ***************************
Privilege: Delete
  Context: Tables
  Comment: To delete existing rows
*************************** 5. row ***************************
Privilege: Index
  Context: Tables
  Comment: To create or drop indexes
*************************** 6. row ***************************
Privilege: Alter
  Context: Tables
  Comment: To alter the table
*************************** 7. row ***************************
Privilege: Create
  Context: Databases,Tables,Indexes
  Comment: To create new databases and tables
*************************** 8. row ***************************
Privilege: Drop
  Context: Databases,Tables
  Comment: To drop databases and tables
*************************** 9. row ***************************
Privilege: Grant
  Context: Databases,Tables
  Comment: To give to other users those privileges you possess
*************************** 10. row ***************************
Privilege: References
  Context: Databases,Tables
  Comment: To have references on tables
*************************** 11. row ***************************
Privilege: Reload
  Context: Server Admin
  Comment: To reload or refresh tables, logs and privileges
*************************** 12. row ***************************
Privilege: Shutdown
  Context: Server Admin
  Comment: To shutdown the server
*************************** 13. row ***************************
Privilege: Process
  Context: Server Admin
  Comment: To view the plain text of currently executing queries
*************************** 14. row ***************************
Privilege: File
  Context: File access on server
  Comment: To read and write files on the server
@end example


@node SHOW PROCESSLIST, SHOW STATUS, SHOW PRIVILEGES, SHOW
@subsubsection @code{SHOW PROCESSLIST} Syntax

@c TODO: list the output fields and explain them

@findex threads
@findex PROCESSLIST
@findex SHOW PROCESSLIST

@cindex threads, display
@cindex processes, display

@example
SHOW [FULL] PROCESSLIST
@end example

@code{SHOW PROCESSLIST} shows you which threads are running.
You can also get this information using the @command{mysqladmin processlist}
statement.  If you have the @code{SUPER} privilege, you can see all
threads.  Otherwise, you can see only your own threads (that is, threads
associated with the MySQL account that you are using).
@xref{KILL, ,@code{KILL}}.
If you don't use the @code{FULL} keyword, only the first 100
characters of each query are shown.

Starting from MySQL 4.0.12, the statement reports the hostname for TCP/IP
connections in @code{@var{host_name}:@var{client_port}} format to make it easier to
determine which client is doing what.

This statement is very useful if you get the "too many connections" error
message and want to find out what is going on. MySQL reserves one extra
connection to be used by accounts that have the @code{SUPER} privilege, to
ensure that administrators should always be able to connect and check the
system (assuming that you are not giving this privilege to all your users).

Some states commonly seen in the output from @code{SHOW PROCESSLIST}:

@table @code

@item Checking table
The thread is performing (automatic) checking of the table.

@item Closing tables
Means that the thread is flushing the changed table data to disk and
closing the used tables. This should be a fast operation.  If not, then
you should verify that you don't have a full disk and that the disk is not
in very heavy use.

@item Connect Out
Slave connecting to master.

@item Copying to tmp table on disk
The temporary result set was larger than @code{tmp_table_size} and the
thread is now changing the temporary table from in-memory to disk-based
format to save memory.

@item Creating tmp table
The thread is creating a temporary table to hold a part of the result for
the query.

@item deleting from main table
The server is executing the first part of a multiple-table delete and
deleting only from the first table.

@item deleting from reference tables
The server is executing the second part of a multiple-table delete and deleting
the matched rows from the other tables.

@item Flushing tables
The thread is executing @code{FLUSH TABLES} and is waiting for all
threads to close their tables.

@item Killed
Someone has sent a kill to the thread and it should abort next time it
checks the kill flag.  The flag is checked in each major loop in MySQL,
but in some cases it might still take a short time for the thread to die.
If the thread is locked by some other thread, the kill takes effect
as soon as the other thread releases its lock.

@item Locked
The query is locked by another query.

@item Sending data
The thread is processing rows for a @code{SELECT} statement and
also is sending data to the client.

@item Sorting for group
The thread is doing a sort to satisfy a @code{GROUP BY}.

@item Sorting for order
The thread is doing a sort to satisfy a @code{ORDER BY}.

@item Opening tables
The thread is trying to open a table. This is should be very fast procedure,
unless something prevents opening. For example, an @code{ALTER TABLE} or a
@code{LOCK TABLE} statement can prevent opening a table until the statement
is finished.

@item Removing duplicates
The query was using @code{SELECT DISTINCT} in such a way that MySQL
couldn't optimize away the distinct operation at an early stage. Because of
this, MySQL requires an extra stage to remove all duplicated rows before
sending the result to the client.

@item Reopen table
The thread got a lock for the table, but noticed after getting the lock
that the underlying table structure changed. It has freed the lock,
closed the table, and is now trying to reopen it.

@item Repair by sorting
The repair code is using sorting to create indexes.

@item Repair with keycache
The repair code is using creating keys one by one through the key cache.
This is much slower than @code{Repair by sorting}.

@item Searching rows for update
The thread is doing a first phase to find all matching rows before
updating them.  This has to be done if the @code{UPDATE} is changing
the index that is used to find the involved rows.

@item Sleeping
The thread is waiting for the client to send a new statement to it.

@item System lock
The thread is waiting to get an external system lock for the
table. If you are not using multiple @command{mysqld} servers that are accessing
the same tables, you can disable system locks with the
@code{--skip-external-locking} option.

@item Upgrading lock
The @code{INSERT DELAYED} handler is trying to get a lock for the table
to insert rows.

@item Updating
The thread is searching for rows to update and updating them.

@item User Lock
The thread is waiting on a @code{GET_LOCK()}.

@item Waiting for tables
The thread got a notification that the underlying structure for a table
has changed and it needs to reopen the table to get the new structure.
However, to be able to reopen the table, it must wait until all other
threads have closed the table in question.

This notification happens if another thread has used @code{FLUSH TABLES}
or one of the following statements on the table in question: @code{FLUSH
TABLES @var{tbl_name}}, @code{ALTER TABLE}, @code{RENAME TABLE},
@code{REPAIR TABLE}, @code{ANALYZE TABLE}, or @code{OPTIMIZE TABLE}.

@item waiting for handler insert
The @code{INSERT DELAYED} handler has processed all pending inserts and is
waiting for new ones.

@end table

Most states correspond to very quick operations. If a thread stays in any
of these states for many seconds, there might be a problem that
needs to be investigated.

There are some other states that are not mentioned in the preceding list,
but many of them are useful only for finding bugs in the server.


@node SHOW STATUS, SHOW TABLE STATUS, SHOW PROCESSLIST, SHOW
@subsubsection @code{SHOW STATUS} Syntax

@cindex status variables
@cindex variables, status

@example
SHOW STATUS [LIKE '@var{pattern}']
@end example

@cindex @command{mysqladmin}
@code{SHOW STATUS} provides server status information.  This information
also can be obtained using the @command{mysqladmin extended-status} command.

Partial output is shown here. The list of variables and their values may be
different for your server. The meaning of each variable is given in
@xref{Server status variables}.

@example
mysql> SHOW STATUS;
+--------------------------+------------+
| Variable_name            | Value      |
+--------------------------+------------+
| Aborted_clients          | 0          |
| Aborted_connects         | 0          |
| Bytes_received           | 155372598  |
| Bytes_sent               | 1176560426 |
| Connections              | 30023      |
| Created_tmp_disk_tables  | 0          |
| Created_tmp_tables       | 8340       |
| Created_tmp_files        | 60         |
...
| Open_tables              | 1          |
| Open_files               | 2          |
| Open_streams             | 0          |
| Opened_tables            | 44600      |
| Questions                | 2026873    |
...
| Table_locks_immediate    | 1920382    |
| Table_locks_waited       | 0          |
| Threads_cached           | 0          |
| Threads_created          | 30022      |
| Threads_connected        | 1          |
| Threads_running          | 1          |
| Uptime                   | 80380      |
+--------------------------+------------+
@end example

With a @code{LIKE} clause, the statement displays only those variables that
match the pattern:

@example
mysql> SHOW STATUS LIKE 'Key%';
+--------------------+----------+
| Variable_name      | Value    |
+--------------------+----------+
| Key_blocks_used    | 14955    |
| Key_read_requests  | 96854827 |
| Key_reads          | 162040   |
| Key_write_requests | 7589728  |
| Key_writes         | 3813196  |
+--------------------+----------+
@end example


@node SHOW TABLE STATUS, SHOW TABLES, SHOW STATUS, SHOW
@subsubsection @code{SHOW TABLE STATUS} Syntax

@cindex displaying, table status
@cindex tables, displaying status
@cindex status, tables

@example
SHOW TABLE STATUS [FROM @var{db_name}] [LIKE '@var{pattern}']
@end example

@code{SHOW TABLE STATUS} (new in MySQL 3.23) works likes @code{SHOW
TABLE}, but provides a lot of information about each table. You can
also get this list using the @command{mysqlshow --status @var{db_name}} command.

@code{SHOW TABLE STATUS} returns the following fields:

@table @code

@item Name
The name of the table.

@item Engine
The storage engine for the table.
Before MySQL 4.1.2, this value is labeled as @code{Type}.
@xref{Storage engines}.

@item Version
The version number of the table's
@file{.frm} file.

@item Row_format
The row storage format (@code{Fixed}, @code{Dynamic}, or @code{Compressed}).

@item Rows
The number of rows.
Some storage engines, such as @code{MyISAM} and @code{ISAM}, store the 
exact count.

For other storage engines, such as @code{InnoDB}, this value is an 
approximation, and may vary from the actual value by as much as 
40 to 50%. In such cases, use @code{SELECT COUNT(*)} to obtain an 
accurate count.

@item Avg_row_length
The average row length.

@c TODO: Next few item descriptions are MyISAM-specific; generalize.

@item Data_length
The length of the data file.

@item Max_data_length
The maximum length of the data file.
For fixed-row formats, this is the maximum number of rows in the table.
For dynamic-row formats, this is the total number of data bytes that
can be stored in the table, given the data pointer size used.

@item Index_length
The length of the index file.

@item Data_free
The number of allocated but unused bytes.

@item Auto_increment
The next @code{AUTO_INCREMENT} value.

@item Create_time
When the table was created.

@item Update_time
When the data file was last updated.

@item Check_time
When the table was last checked.

@item Collation
The table's character set and collation. (New in 4.1.1)

@item Checksum
The live checksum value (if any). (New in 4.1.1)

@item Create_options
Extra options used with @code{CREATE TABLE}.

@item Comment
The comment used when creating the table (or some information why MySQL
couldn't access the table information).

@end table

In the table comment, @code{InnoDB} tables will report the free space of
the tablespace to which the table belongs.  For a table located in the
shared tablespace, this is the free space of the shared tablespace. If
you are using multiple tablespaces and the table has its own tablespace,
the freespace is for just that table.

For @code{MEMORY} (@code{HEAP}) tables, the @code{Data_length},
@code{Max_data_length}, and @code{Index_length} values approximate the
actual amount of allocated memory. The allocation algorithm reserves memory
in large amounts to reduce the number of allocation operations.


@node SHOW TABLES, SHOW VARIABLES, SHOW TABLE STATUS, SHOW
@subsubsection @code{SHOW TABLES} Syntax

@c TODO: need description of SHOW OPEN TABLES output columns, particularly
@c as the output no longer seems to *have* a Comment field

@cindex displaying, information, @code{SHOW}
@findex SHOW TABLES

@example
SHOW [FULL|OPEN] TABLES [FROM @var{db_name}] [LIKE '@var{pattern}']
@end example

@code{SHOW TABLES} lists the non-@code{TEMPORARY} tables in a given
database.  You can also get this list using the @command{mysqlshow @var{db_name}}
command.

Before MySQL 5.0.1, the output from @code{SHOW TABLES} contains a single
column of table names.  Beginning with MySQL 5.0.1, also lists the views in
the database. As of MySQL 5.0.2, the @code{FULL} modifier is supported such
that @code{SHOW FULL TABLES} displays a second output column.  Values in the
second column are @code{BASE TABLE} for a table and @code{VIEW} for a view.

@strong{Note}: If you have no privileges for a table, the table
will not show up in the output from @code{SHOW TABLES} or @command{mysqlshow
db_name}.

@c TODO: non-TEMPORARY tables only?

@code{SHOW OPEN TABLES} lists the tables that are currently open in
the table cache. @xref{Table cache}.  The @code{Comment} field in the output
tells how many times the table is @code{cached} and @code{in_use}.
@code{OPEN} can be used from MySQL 3.23.33 on.


@node SHOW VARIABLES, SHOW WARNINGS, SHOW TABLES, SHOW
@subsubsection @code{SHOW VARIABLES} Syntax

@cindex system variables
@cindex server variables
@cindex variables, server
@cindex variables, system

@example
SHOW [GLOBAL | SESSION] VARIABLES [LIKE '@var{pattern}']
@end example

@cindex @command{mysqladmin}
@code{SHOW VARIABLES} shows the values of some MySQL system variables.  This
information also can be obtained using the @command{mysqladmin variables}
command.

The @code{GLOBAL} and @code{SESSION} options are new in MySQL 4.0.3.
With @code{GLOBAL}, you will get the values that will be used for new
connections to MySQL. With @code{SESSION}, you will get the values that
are in effect for the current connection. If you use neither option, the
default @code{SESSION}. @code{LOCAL} is a synonym for @code{SESSION}.

If the default values are unsuitable, you can set most of these variables
using command-line options when @command{mysqld} starts or at runtime with
the @code{SET} statement.
See @ref{Server options} and @ref{SET OPTION, , @code{SET}}.

Partial output is shown here. The list of variables and their values may be
different for your server. The meaning of each variable is given in
@xref{Server system variables}.
Information about tuning them is provided in @ref{Server parameters}.

@example
mysql> SHOW VARIABLES;
+---------------------------------+------------------------------+
| Variable_name                   | Value                        |
+---------------------------------+------------------------------|
| back_log                        | 50                           |
| basedir                         | /usr/local/mysql             |
| bdb_cache_size                  | 8388572                      |
| bdb_log_buffer_size             | 32768                        |
| bdb_home                        | /usr/local/mysql             |
...
| max_connections                 | 100                          |
| max_connect_errors              | 10                           |
| max_delayed_threads             | 20                           |
| max_error_count                 | 64                           |
| max_heap_table_size             | 16777216                     |
| max_join_size                   | 4294967295                   |
| max_relay_log_size              | 0                            |
| max_sort_length                 | 1024                         |
...
| timezone                        | EEST                         |
| tmp_table_size                  | 33554432                     |
| tmpdir                          | /tmp/:/mnt/hd2/tmp/          |
| version                         | 4.0.4-beta                   |
| wait_timeout                    | 28800                        |
+---------------------------------+------------------------------+
@end example

With a @code{LIKE} clause, the statement displays only those variables that
match the pattern:

@example
mysql> SHOW VARIABLES LIKE 'have%';
+--------------------+----------+
| Variable_name      | Value    |
+--------------------+----------+
| have_bdb           | YES      |
| have_innodb        | YES      |
| have_isam          | YES      |
| have_raid          | NO       |
| have_symlink       | DISABLED |
| have_openssl       | YES      |
| have_query_cache   | YES      |
+--------------------+----------+
@end example


@node SHOW WARNINGS,  , SHOW VARIABLES, SHOW
@subsubsection @code{SHOW WARNINGS} Syntax

@findex SHOW WARNINGS

@example
SHOW WARNINGS [LIMIT [@var{offset},] @var{row_count}]
SHOW COUNT(*) WARNINGS
@end example


@code{SHOW WARNINGS} shows the error, warning, and note messages that
resulted from the last statement that generated messages, or nothing if the
last statement that used a table generated no messages.
This statement is implemented as of MySQL 4.1.0.
A related statement, @code{SHOW ERRORS}, shows only the errors.
@xref{SHOW ERRORS,  , @code{SHOW ERRORS}}.

The list of messages is reset for each new statement that uses a table.

The @code{SHOW COUNT(*) WARNINGS} statement displays the total number of
errors, warnings, and notes. You can also retrieve this number from the
@code{warning_count} variable:

@example
SHOW COUNT(*) WARNINGS;
SELECT @@@@warning_count;
@end example

The value of @code{warning_count} might be greater than the number of
messages displayed by @code{SHOW WARNINGS} if the @code{max_error_count}
system variable is set low enough that not all messages are stored. An
example shown later in this section demonstrates how this can happen.

The @code{LIMIT} clause has the same syntax as for the @code{SELECT}
statement.
@xref{SELECT,  , @code{SELECT}}.

The MySQL server sends back the total number of errors, warnings, and
notes resulting from the last statement.
If you are using the C API, this value can be obtained by calling
@code{mysql_warning_count()}.
@xref{mysql_warning_count,  , @code{mysql_warning_count()}}.

Note that the framework for warnings was added in MySQL 4.1.0, at which
point many statements did not generate warnings.  In 4.1.1, the situation is
much improved, with warnings generated for statements such as @code{LOAD
DATA INFILE} and DML statements such as @code{INSERT}, @code{UPDATE},
@code{CREATE TABLE}, and @code{ALTER TABLE}.

The following @code{DROP TABLE} statement results in a note:

@example
mysql> DROP TABLE IF EXISTS no_such_table;
mysql> SHOW WARNINGS;
+-------+------+-------------------------------+
| Level | Code | Message                       |
+-------+------+-------------------------------+
| Note  | 1051 | Unknown table 'no_such_table' |
+-------+------+-------------------------------+
@end example

Here is a simple example that shows a syntax warning for @code{CREATE TABLE}
and conversion warnings for @code{INSERT}:

@example
mysql> CREATE TABLE t1 (a TINYINT NOT NULL, b CHAR(4)) TYPE=MyISAM;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
  Level: Warning
   Code: 1287
Message: 'TYPE=storage_engine' is deprecated, use
         'ENGINE=storage_engine' instead
1 row in set (0.00 sec)

mysql> INSERT INTO t1 VALUES(10,'mysql'),(NULL,'test'),
    -> (300,'Open Source');
Query OK, 3 rows affected, 4 warnings (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 4

mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
  Level: Warning
   Code: 1265
Message: Data truncated for column 'b' at row 1
*************************** 2. row ***************************
  Level: Warning
   Code: 1263
Message: Data truncated, NULL supplied to NOT NULL column 'a' at row 2
*************************** 3. row ***************************
  Level: Warning
   Code: 1264
Message: Data truncated, out of range for column 'a' at row 3
*************************** 4. row ***************************
  Level: Warning
   Code: 1265
Message: Data truncated for column 'b' at row 3
4 rows in set (0.00 sec)
@end example

The maximum number of error, warning, and note messages to store is controlled
by the @code{max_error_count} system variable.  By default, its value is 64.
To change the number of messages you want stored, change the value of
@code{max_error_count}.
In the following example, the @code{ALTER TABLE} statement produces three
warning messages, but only one is stored because @code{max_error_count}
has been set to @code{1}:

@example
mysql> SHOW VARIABLES LIKE 'max_error_count';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_error_count | 64    |
+-----------------+-------+
1 row in set (0.00 sec)

mysql> SET max_error_count=1;
Query OK, 0 rows affected (0.00 sec)

mysql> ALTER TABLE t1 MODIFY b CHAR;
Query OK, 3 rows affected, 3 warnings (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 3

mysql> SELECT @@@@warning_count;
+-----------------+
| @@@@warning_count |
+-----------------+
|               3 |
+-----------------+
1 row in set (0.01 sec)

mysql> SHOW WARNINGS;
+---------+------+----------------------------------------+
| Level   | Code | Message                                |
+---------+------+----------------------------------------+
| Warning | 1263 | Data truncated for column 'b' at row 1 |
+---------+------+----------------------------------------+
1 row in set (0.00 sec)
@end example

To disable warnings, set @code{max_error_count} to @code{0}. In this case,
@code{warning_count} still indicates how many warnings have occurred, but
none of the messages are stored.


@node Other administrative SQL,  , SHOW, Database Administration
@subsection Other Administrative Statements

@menu
* CACHE INDEX::                 @code{CACHE INDEX} Syntax
* FLUSH::                       @code{FLUSH} Syntax
* KILL::                        @code{KILL} Syntax
* LOAD INDEX::                  @code{LOAD INDEX INTO CACHE} Syntax
* RESET::                       @code{RESET} Syntax
@end menu


@node CACHE INDEX, FLUSH, Other administrative SQL, Other administrative SQL
@subsubsection @code{CACHE INDEX} Syntax

@findex CACHE INDEX

@cindex key cache, assigning indexes to
@cindex indexes, assigning to key cache

@c example_for_help_topic CACHE INDEX
@example
CACHE INDEX
  @var{tbl_index_list} [, @var{tbl_index_list}] ...
  IN @var{key_cache_name}

@var{tbl_index_list}:
  @var{tbl_name} [[INDEX|KEY] (@var{index_name}[, @var{index_name}] ...)]
@end example

@c description_for_help_topic CACHE INDEX
The @code{CACHE INDEX} statement assigns table indexes to a specific key
cache. It is used only for @code{MyISAM} tables.

The following statement assigns indexes from the tables @code{t1},
@code{t2}, and @code{t3} to the key cache named @code{hot_cache}:

@example
mysql> CACHE INDEX t1, t2, t3 IN hot_cache;
+---------+--------------------+----------+----------+
| Table   | Op                 | Msg_type | Msg_text |
+---------+--------------------+----------+----------+
| test.t1 | assign_to_keycache | status   | OK       |
| test.t2 | assign_to_keycache | status   | OK       |
| test.t3 | assign_to_keycache | status   | OK       |
+---------+--------------------+----------+----------+
@end example
@c end_description_for_help_topic

The syntax of @code{CACHE INDEX} allows you to specify that only particular
indexes from a table should be assigned to the cache.  However, the current
implementation assigns all the table's indexes to the cache, so there is no
reason to specify anything other than the table name.

The key cache referred to in a @code{CACHE INDEX} statement can be created
by setting its size with a parameter setting statement or in the server
parameter settings. For example:

@example
mysql> SET GLOBAL keycache1.key_buffer_size=128*1024;
@end example

Key cache parameters can be accessed as members of a structured system
variable.
@xref{Structured System Variables}.

A key cache must exist before you can assign indexes to it:

@example
mysql> CACHE INDEX t1 IN non_existent_cache;
ERROR 1283 (HY000): Unknown key cache 'non_existent_cache'
@end example

By default, table indexes are assigned to the main (default) key cache
created at the server startup. When a key cache is destroyed, all
indexes assigned to it become assigned to the default key cache again.

Index assignment affects the server globally: If one client
assigns an index to a given cache, this cache is used for all queries
involving the index, no matter what client issues the queries.

@code{CACHE INDEX} was added in MySQL 4.1.1.


@node FLUSH, KILL, CACHE INDEX, Other administrative SQL
@subsubsection @code{FLUSH} Syntax

@findex FLUSH

@cindex @command{mysqladmin}
@cindex clearing, caches
@cindex caches, clearing

@c example_for_help_topic FLUSH
@example
FLUSH [LOCAL | NO_WRITE_TO_BINLOG] @var{flush_option} [, @var{flush_option}] ...
@end example

@c description_for_help_topic FLUSH  LOCAL NO_WRITE_TO_BINLOG DES_KEY_FILE USER_RESOURCES
You should use the @code{FLUSH} statement if you want to clear some of the
internal caches MySQL uses.  To execute @code{FLUSH}, you must have
the @code{RELOAD} privilege.
@c end_description_for_help_topic

@var{flush_option} can be any of the following:

@table @code

@item HOSTS
Empties the host cache tables.  You should flush the
host tables if some of your hosts change IP number or if you get the
error message @code{Host ... is blocked}.  When more than
@code{max_connect_errors} errors occur successively for a given host while
connecting to the MySQL server, MySQL assumes that
something is wrong and blocks the host from further connection requests.
Flushing the host tables allows the host to attempt to connect
again. @xref{Blocked host}. You can start @command{mysqld} with
@code{--max_connect_errors=999999999} to avoid this error message.

@item DES_KEY_FILE
Reloads the DES keys from the file that was
specified with the @code{--des-key-file} option at server startup time.

@item LOGS
Closes and reopens all log files.
If you have specified an update log file or a binary log file without
an extension, the extension number of the log file will be incremented
by one relative to the previous file. If you have used an extension in
the file name, MySQL will close and reopen the update log or binary log file.
@xref{Update log}. On Unix, this is the same thing as sending a @code{SIGHUP}
signal to the @command{mysqld} server (except on some Mac OS X 10.3 versions
where @code{mysqld} will ignore @code{SIGHUP} and @code{SIGQUIT}).

@item PRIVILEGES
Reloads the privileges from the grant tables in
the @code{mysql} database.

@item QUERY CACHE
Defragment the query cache to better utilize its
memory.  This statement does not remove any queries from the cache, unlike
@code{RESET QUERY CACHE}.

@item STATUS
Resets most status variables to zero. This is something you should use only when debugging a query. @xref{Bug reports}.

@c TODO: non-TEMPORARY tables only?

@item @{TABLE | TABLES@} [@var{tbl_name} [, @var{tbl_name}] ...]
When no tables are named, closes all open tables and forces all tables in use to be closed. This also flushes the query cache.  With one or more table names, flushes only the given tables.
@code{FLUSH TABLES} also removes all query results from the query cache, like
the @code{RESET QUERY CACHE} statement.

@item TABLES WITH READ LOCK
Closes all open tables and locks all
tables for all databases with a read lock until you execute @code{UNLOCK
TABLES}. This is very convenient way to get backups if you have a filesystem
such as Veritas that can take snapshots in time.

@item USER_RESOURCES
Resets all user resources to zero. This
enables clients that have reached their hourly connection, query, or update
limits to resume activity.
@xref{GRANT,  , @code{GRANT}}.

@end table

Before MySQL 4.1.1, @code{FLUSH} statements are not written to the binary
log. As of MySQL 4.1.1, they are written to the binary log unless the
optional @code{NO_WRITE_TO_BINLOG} keyword (or its alias @code{LOCAL}) is
used.  Exceptions are that @code{FLUSH LOGS}, @code{FLUSH MASTER},
@code{FLUSH SLAVE}, and @code{FLUSH TABLES WITH READ LOCK} are not logged in
any case because they would cause problems if replicated to a slave.

You can also access some of these statements with the @command{mysqladmin}
utility, using the @code{flush-hosts}, @code{flush-logs}, @code{flush-privileges},
@code{flush-status}, or @code{flush-tables} commands.

Take also a look at the @code{RESET} statement used with replication.
@xref{RESET, , @code{RESET}}.


@node KILL, LOAD INDEX, FLUSH, Other administrative SQL
@subsubsection @code{KILL} Syntax

@findex KILL

@cindex @command{mysqladmin}

@c example_for_help_topic KILL
@example
KILL [CONNECTION | QUERY] @var{thread_id}
@end example

@c description_for_help_topic KILL
Each connection to @command{mysqld} runs in a separate thread.  You can see
which threads are running with the @code{SHOW PROCESSLIST} statement and kill
a thread with the @code{KILL thread_id} statement.

As of MySQL 5.0.0, @code{KILL} allows the optional @code{CONNECTION} or
@code{QUERY} modifiers:

@itemize @bullet

@item
@code{KILL CONNECTION} is the same as @code{KILL} with no modifier:
It terminates the connection associated with the given @var{thread_id}.

@item
@code{KILL QUERY} terminates the statement that the connection currently
is executing, but leaves the connection intact.

@end itemize

If you have the @code{PROCESS} privilege, you can see all threads.
If you have the @code{SUPER} privilege, you can kill all threads and
statements.  Otherwise, you can see and kill only your own threads and
statements.

You can also use the @command{mysqladmin processlist} and @command{mysqladmin kill}
commands to examine and kill threads.

@strong{Note}: You currently cannot use @code{KILL} with the Embedded MySQL
Server library, because the embedded server merely runs inside the threads
of the host application, it does not create connection threads of its own.
@c end_description_for_help_topic

When you do a @code{KILL}, a thread-specific kill flag is set for
the thread.
In most cases, it might take some time for the thread to die, because the kill
flag is checked only at specific intervals:

@itemize @bullet
@item
In @code{SELECT}, @code{ORDER BY} and @code{GROUP BY} loops, the flag is
checked after reading a block of rows. If the kill flag is set, the
statement is aborted.
@item
During @code{ALTER TABLE}, the kill flag is checked before each block of
rows are read from the original table. If the kill flag was set, the statement
is aborted and the temporary table is deleted.
@item
During @code{UPDATE} or @code{DELETE}, the kill flag
is checked after each block read and after each updated or deleted
row. If the kill flag is set, the statement is aborted.  Note that if you
are not using transactions, the changes will not be rolled back!
@item
@code{GET_LOCK()} will abort and return @code{NULL}.
@item
An @code{INSERT DELAYED} thread will quickly flush (insert) all rows it has in
memory and terminate.
@item
If the thread is in the table lock handler (state: @code{Locked}),
the table lock will be quickly aborted.
@item
If the thread is waiting for free disk space in a write call, the
write is aborted with a "disk full" error message.
@item
Some threads might refuse to be killed.  For example, @code{REPAIR TABLE},
@code{CHECK TABLE}, and @code{OPTIMIZE TABLE} cannot be killed before
MySQL 4.1 and run to completion.  This now is changed: @code{REPAIR TABLE}
and @code{OPTIMIZE TABLE}
can be killed as of MySQL 4.1.0, as can @code{CHECK TABLE} as of MySQL 4.1.3.
However, killing a @code{REPAIR TABLE} or @code{OPTIMIZE TABLE} operation
on a @code{MyISAM} table results in a table that IS corrupted and will be
unusable (reads and writes to it will fail) until you optimize or repair it
again.
@end itemize


@node LOAD INDEX, RESET, KILL, Other administrative SQL
@subsubsection @code{LOAD INDEX INTO CACHE} Syntax

@c example_for_help_topic LOAD INDEX
@example
LOAD INDEX INTO CACHE
  @var{tbl_index_list} [, @var{tbl_index_list}] ...

@var{tbl_index_list}:
  @var{tbl_name}
    [[INDEX|KEY] (@var{index_name}[, @var{index_name}] ...)]
    [IGNORE LEAVES]
@end example

@c description_for_help_topic LOAD INDEX
The @code{LOAD INDEX INTO CACHE} statement preloads a table index into the
key cache to which it has been assigned by an explicit @code{CACHE INDEX}
statement, or into the default key cache otherwise.  @code{LOAD INDEX INTO
CACHE} is used only for @code{MyISAM} tables.

The @code{IGNORE LEAVES} modifier causes only blocks for the non-leaf
nodes of the index to be preloaded.
@c end_description_for_help_topic

The following statement preloads nodes (index blocks) of indexes of the
tables @code{t1} and @code{t2}:

@example
mysql> LOAD INDEX INTO CACHE t1, t2 IGNORE LEAVES;
+---------+--------------+----------+----------+
| Table   | Op           | Msg_type | Msg_text |
+---------+--------------+----------+----------+
| test.t1 | preload_keys | status   | OK       |
| test.t2 | preload_keys | status   | OK       |
+---------+--------------+----------+----------+
@end example

This statement preloads all index blocks from @code{t1}. It preloads only
blocks for the non-leaf nodes from @code{t2}.

The syntax of @code{LOAD INDEX INTO CACHE} allows you to specify that only
particular indexes from a table should be preloaded.  However, the current
implementation preloads all the table's indexes into the cache, so there is
no reason to specify anything other than the table name.

@code{LOAD INDEX INTO CACHE} was added in MySQL 4.1.1.


@node RESET,  , LOAD INDEX, Other administrative SQL
@subsubsection @code{RESET} Syntax

@c example_for_help_topic RESET
@example
RESET @var{reset_option} [, @var{reset_option}] ...
@end example

@c description_for_help_topic RESET
The @code{RESET} statement is used to clear the state of various server
operations. It also acts as a stronger
version of the @code{FLUSH} statement.  @xref{FLUSH, , @code{FLUSH}}.
@c end_description_for_help_topic

To execute @code{RESET}, you must have the @code{RELOAD} privilege.

@var{reset_option} can be any of the following:

@table @code

@item MASTER
Deletes all binary logs listed in the index file, resets the binary log
index file to be empty, and creates a new binary log file. Previously named
@code{FLUSH MASTER}.
@xref{Replication Master SQL}.

@item QUERY CACHE
Removes all query results from the query cache.

@item SLAVE
Makes the slave forget its replication position in the master
binary logs.  Previously named @code{FLUSH SLAVE}.
@xref{Replication Slave SQL}.

@end table


@node Replication SQL, SQLPS, Database Administration, SQL Syntax
@section Replication Statements

This section describes replication-related SQL statements.
One group of statements is used for controlling master servers.
The other is used for controlling slave servers.

@menu
* Replication Master SQL::      SQL Statements for Controlling Master Servers
* Replication Slave SQL::       SQL Statements for Controlling Slave Servers
@end menu

@node Replication Master SQL, Replication Slave SQL, Replication SQL, Replication SQL
@subsection SQL Statements for Controlling Master Servers

@cindex SQL commands, replication masters
@cindex commands, replication masters
@cindex replication masters, commands

Replication can be controlled through the SQL interface. This section
discusses statements for managing master replication servers.
@ref{Replication Slave SQL} discusses statements for managing slave servers.

@menu
* PURGE MASTER LOGS::           @code{PURGE MASTER LOGS} Syntax
* RESET MASTER::                @code{RESET MASTER} Syntax
* SET SQL_LOG_BIN::             @code{SET SQL_LOG_BIN} Syntax
* SHOW BINLOG EVENTS::          @code{SHOW BINLOG EVENTS} Syntax
* SHOW MASTER LOGS::            @code{SHOW MASTER LOGS} Syntax
* SHOW MASTER STATUS::          @code{SHOW MASTER STATUS} Syntax
* SHOW SLAVE HOSTS::            @code{SHOW SLAVE HOSTS} Syntax
@end menu


@node PURGE MASTER LOGS, RESET MASTER, Replication Master SQL, Replication Master SQL
@subsubsection @code{PURGE MASTER LOGS} Syntax

@findex PURGE MASTER LOGS

@c description_for_help_topic PURGE MASTER LOGS BEFORE TO
@example
PURGE @{MASTER | BINARY@} LOGS TO '@var{log_name}'
PURGE @{MASTER | BINARY@} LOGS BEFORE '@var{date}'
@end example

Deletes all the binary logs listed in the log
index that are strictly prior to the specified log or date.
The logs also are removed from the list recorded in the log index file,
so that the given log becomes the first. 
@c end_description_for_help_topic

Example:

@c example_for_help_topic PURGE
@example
PURGE MASTER LOGS TO 'mysql-bin.010';
PURGE MASTER LOGS BEFORE '2003-04-02 22:46:26';
@end example

The @code{BEFORE} variant is available as of MySQL 4.1. Its date argument
can be in @code{'YYYY-MM-DD hh:mm:ss'} format.
@code{MASTER} and @code{BINARY} are synonyms, but @code{BINARY} can be used
only as of MySQL 4.1.1.

If you have an active slave that currently is reading one of the logs you
are trying to delete, this statement does nothing and fails with an error.
However, if a slave is dormant and you happen to purge one of
the logs it wants to read, the slave will be unable to replicate once it
comes up.  The statement is safe to run while slaves are replicating. You
do not need to stop them.

To purge logs, follow this procedure:

@enumerate
@item
On each slave server, use @code{SHOW SLAVE STATUS} to check which log it is
reading.
@item
Obtain a listing of the logs on the master server with @code{SHOW MASTER LOGS}.
@item
Determine the earliest log among all the slaves. This is the target log.
If all the slaves are up to date, this will be the last log on the list.
@item
Make a backup of all the logs you are about to delete.  (The step is optional,
but a good idea.)
@item
Purge all logs up to but not including the target log.
@end enumerate


@node RESET MASTER, SET SQL_LOG_BIN, PURGE MASTER LOGS, Replication Master SQL
@subsubsection @code{RESET MASTER} Syntax

@findex RESET MASTER

@c description_for_help_topic RESET MASTER  RESET MASTER
@example
RESET MASTER
@end example

Deletes all binary logs listed in the index file,
resets the binary log index file to be empty, and creates a new binary log
file.

This statement was named @code{FLUSH MASTER} before MySQL 3.23.26.
@c end_description_for_help_topic


@node SET SQL_LOG_BIN, SHOW BINLOG EVENTS, RESET MASTER, Replication Master SQL
@subsubsection @code{SET SQL_LOG_BIN} Syntax

@findex SET SQL_LOG_BIN

@c description_for_help_topic SET SQL_LOG_BIN  SET SQL_LOG_BIN
@example
SET SQL_LOG_BIN = @{0|1@}
@end example

Disables or enables binary logging for the current connection 
(@code{SQL_LOG_BIN} is a session variable)
if the client connects using an account that has the @code{SUPER} privilege.
The statement is refused with an error if the client does not have that
privilege. (Before MySQL 4.1.2, the statement was simply ignored in that case.)
@c end_description_for_help_topic


@node SHOW BINLOG EVENTS, SHOW MASTER LOGS, SET SQL_LOG_BIN, Replication Master SQL
@subsubsection @code{SHOW BINLOG EVENTS} Syntax

@findex SHOW BINLOG EVENTS

@c description_for_help_topic SHOW BINLOG  SHOW BINLOG EVENTS LIMIT FROM IN
@example
SHOW BINLOG EVENTS
   [IN '@var{log_name}'] [FROM @var{pos}] [LIMIT [@var{offset},] @var{row_count}]
@end example

Shows the events in the binary log. 
If you do not specify @code{'log_name'}, the first binary log will be displayed.
@c end_description_for_help_topic

The @code{LIMIT} clause has the same syntax as for the @code{SELECT}
statement.
@xref{SELECT,  , @code{SELECT}}.

This statement is available as of MySQL 4.0.


@node SHOW MASTER LOGS, SHOW MASTER STATUS, SHOW BINLOG EVENTS, Replication Master SQL
@subsubsection @code{SHOW MASTER LOGS} Syntax

@c TODO: describe output

@findex SHOW MASTER LOGS
@findex SHOW BINARY LOGS

@c description_for_help_topic SHOW MASTER LOGS  SHOW MASTER BINARY LOGS
@example
SHOW MASTER LOGS
SHOW BINARY LOGS
@end example

Lists the binary log files on the server. This statement is used as part of
the procedure described in @ref{PURGE MASTER LOGS,  , @code{PURGE MASTER LOGS}}
for determining which logs can be purged.
@c end_description_for_help_topic

@code{SHOW MASTER LOGS} was added in MySQL 3.23.38.  As of MySQL 4.1.1,
you can also use @code{SHOW BINARY LOGS}, which is equivalent.


@node SHOW MASTER STATUS, SHOW SLAVE HOSTS, SHOW MASTER LOGS, Replication Master SQL
@subsubsection @code{SHOW MASTER STATUS} Syntax

@c TODO: describe output

@findex SHOW MASTER STATUS

@c description_for_help_topic SHOW MASTER STATUS  SHOW MASTER STATUS
@example
SHOW MASTER STATUS
@end example

Provides status information on the binary log files of the master.
@c end_description_for_help_topic


@node SHOW SLAVE HOSTS,  , SHOW MASTER STATUS, Replication Master SQL
@subsubsection @code{SHOW SLAVE HOSTS} Syntax

@c TODO: describe output

@findex SHOW SLAVE HOSTS

@c description_for_help_topic SHOW SLAVE HOSTS  SHOW SLAVE HOSTS
@example
SHOW SLAVE HOSTS
@end example

Displays a list of slaves currently registered with the master. 
Any slave not started with the @code{--report-host=slave_name} 
option will not be visible in that list.
@c end_description_for_help_topic


@node Replication Slave SQL,  , Replication Master SQL, Replication SQL
@subsection SQL Statements for Controlling Slave Servers

@cindex SQL commands, replication slaves
@cindex commands, replication slaves
@cindex replication slaves, commands

Replication can be controlled through the SQL interface. This section
discusses statements for managing slave replication servers.
@ref{Replication Master SQL} discusses statements for managing master servers.

@menu
* CHANGE MASTER TO::            @code{CHANGE MASTER TO} Syntax
* LOAD DATA FROM MASTER::       @code{LOAD DATA FROM MASTER} Syntax
* LOAD TABLE FROM MASTER::      @code{LOAD TABLE @var{tbl_name} FROM MASTER} Syntax
* MASTER_POS_WAIT::             @code{MASTER_POS_WAIT()} Syntax
* RESET SLAVE::                 @code{RESET SLAVE} Syntax
* SET GLOBAL SQL_SLAVE_SKIP_COUNTER::  @code{SET GLOBAL SQL_SLAVE_SKIP_COUNTER} Syntax
* SHOW SLAVE STATUS::           @code{SHOW SLAVE STATUS} Syntax
* START SLAVE::                 @code{START SLAVE} Syntax
* STOP SLAVE::                  @code{STOP SLAVE} Syntax
@end menu


@node CHANGE MASTER TO, LOAD DATA FROM MASTER, Replication Slave SQL, Replication Slave SQL
@subsubsection @code{CHANGE MASTER TO} Syntax

@findex CHANGE MASTER TO

@c description_for_help_topic CHANGE MASTER TO  CHANGE MASTER TO MASTER_HOST MASTER_USER MASTER_PASSWORD MASTER_PORT MASTER_LOG_FILE MASTER_LOG_POS MASTER_CONNECT_RETRY RELAY_LOG_POS RELAY_LOG_FILE MASTER_SSL MASTER_SSL_CA MASTER_SSL_CERT MASTER_SSL_KEY MASTER_SSL_CIPHER

@example
CHANGE MASTER TO master_def [, master_def] ...

master_def:
      MASTER_HOST = '@var{host_name}'
    | MASTER_USER = '@var{user_name}'
    | MASTER_PASSWORD = '@var{password}'
    | MASTER_PORT = @var{port_num}
    | MASTER_CONNECT_RETRY = @var{count}
    | MASTER_LOG_FILE = '@var{master_log_name}'
    | MASTER_LOG_POS = @var{master_log_pos}
    | RELAY_LOG_FILE = '@var{relay_log_name}'
    | RELAY_LOG_POS = @var{relay_log_pos}
    | MASTER_SSL = @{0|1@}
    | MASTER_SSL_CA = '@var{ca_file_name}'
    | MASTER_SSL_CAPATH = '@var{ca_directory_name}'
    | MASTER_SSL_CERT = '@var{cert_file_name}'
    | MASTER_SSL_KEY = '@var{key_file_name}'
    | MASTER_SSL_CIPHER = '@var{cipher_list}'
@end example

Changes the parameters that the slave server uses for connecting to and
communicating with the master server.

@code{MASTER_USER}, @code{MASTER_PASSWORD}, @code{MASTER_SSL},
@code{MASTER_SSL_CA}, @code{MASTER_SSL_CAPATH}, @code{MASTER_SSL_CERT},
@code{MASTER_SSL_KEY}, and @code{MASTER_SSL_CIPHER} provide information for
the slave about how to connect to its master.

The relay log options (@code{RELAY_LOG_FILE} and @code{RELAY_LOG_POS}) are
available beginning with MySQL 4.0.

The SSL options
(@code{MASTER_SSL},
@code{MASTER_SSL_CA},
@code{MASTER_SSL_CAPATH},
@code{MASTER_SSL_CERT},
@code{MASTER_SSL_KEY},
and
@code{MASTER_SSL_CIPHER})
are available beginning with MySQL 4.1.1.
You can change these options even on slaves that are compiled without SSL
support. They are saved to the @file{master.info} file, but are ignored
until you use a server that has SSL support enabled.

If you don't specify a given parameter, it keeps its old
value, except as indicated in the following discussion. For example, if the password to connect to your MySQL master has
changed, you just need to issue these statements
to tell the slave about the new password:

@example
mysql> STOP SLAVE; -- if replication was running
mysql> CHANGE MASTER TO MASTER_PASSWORD='new3cret';
mysql> START SLAVE; -- if you want to restart replication
@end example

There is no need to specify the parameters that do
not change (host, port, user, and so forth).

@code{MASTER_HOST} and @code{MASTER_PORT} are the hostname (or IP address) of
the master host and its TCP/IP port. Note that if @code{MASTER_HOST} is
equal to @code{localhost}, then, like in other parts of MySQL, the port
may be ignored (if Unix socket files can be used, for example).

If you specify @code{MASTER_HOST} or @code{MASTER_PORT},
the slave assumes that the master server is different than
before (even if you specify a host or port value that is
the same as the current value.) In this case, the old values for the master
binary log name and position are considered no longer applicable, so if you
do not specify @code{MASTER_LOG_FILE} and @code{MASTER_LOG_POS} in the
statement, @code{MASTER_LOG_FILE=''} and @code{MASTER_LOG_POS=4} are
silently appended to it. 

@code{MASTER_LOG_FILE} and @code{MASTER_LOG_POS} are the coordinates
at which the slave I/O thread should begin reading from the master the
next time the thread starts.
If you specify either of them, you can't specify @code{RELAY_LOG_FILE} or
@code{RELAY_LOG_POS}.
If neither of @code{MASTER_LOG_FILE} or @code{MASTER_LOG_POS} are
specified, the slave uses the last coordinates of the @emph{slave SQL thread}
before @code{CHANGE MASTER} was issued. This ensures that
replication has no discontinuity, even if the slave SQL thread was late
compared to the slave I/O thread, when you just want to change, say, the
password to use. This safe behavior was introduced starting from MySQL
4.0.17 and 4.1.1. (Before these versions, the coordinates used were 
the last coordinates of the slave I/O thread before @code{CHANGE MASTER}
was issued. This caused the SQL thread to possibly lose some events
from the master, thus breaking replication.)

@code{CHANGE MASTER} @emph{deletes all relay log files} and starts
a new one, unless you specify @code{RELAY_LOG_FILE} or
@code{RELAY_LOG_POS}. In that case, relay logs are kept;
as of MySQL 4.1.1 the @code{relay_log_purge} global variable
is set silently to 0.

@code{CHANGE MASTER TO} updates the contents of the @file{master.info} and
@file{relay-log.info} files.

@code{CHANGE MASTER} is useful for setting up a slave when you have
the snapshot of the master and have recorded the log and the offset
corresponding to it.  After loading the snapshot into the slave, you
can run @code{CHANGE MASTER TO MASTER_LOG_FILE='@var{log_name_on_master}',
MASTER_LOG_POS=@var{log_offset_on_master}} on the slave.

Examples:

@example
mysql> CHANGE MASTER TO
    ->     MASTER_HOST='master2.mycompany.com',
    ->     MASTER_USER='replication',
    ->     MASTER_PASSWORD='bigs3cret',
    ->     MASTER_PORT=3306,
    ->     MASTER_LOG_FILE='master2-bin.001',
    ->     MASTER_LOG_POS=4,
    ->     MASTER_CONNECT_RETRY=10;

mysql> CHANGE MASTER TO
    ->     RELAY_LOG_FILE='slave-relay-bin.006',
    ->     RELAY_LOG_POS=4025;
@end example
@c end_description_for_help_topic

The first example changes the master and master's binary log
coordinates. This is used when you want to set up the slave to replicate
the master.

The second example shows an operation that is less frequently used. It
is done when the slave has relay logs that you want it to execute again
for some reason.  To do this, the master need not be reachable. You just
have to use @code{CHANGE MASTER TO} and start the SQL thread (@code{START
SLAVE SQL_THREAD}).

You can even use the second operation in a non-replication setup with a
standalone, non-slave server, to recover after a crash.  Suppose that your
server has crashed and you have restored a backup.  You want to replay
the server's own binary logs (not relay logs, but regular binary logs),
supposedly named @file{myhost-bin.*}. First, make a backup copy of these
binary logs in some safe place, in case you don't exactly follow the
procedure below and accidentally have the server purge the binary logs.
If using MySQL 4.1.1 or newer, use @code{SET GLOBAL relay_log_purge=0} for
additional safety.  Then start the server without the @code{--log-bin}
option. Before MySQL 4.0.19, start it with a new (different from before) server
id; in newer versions there is no need, just use the
@code{--replicate-same-server-id} option. Start it with
@code{--relay-log=myhost-bin} (to make the server believe that these
regular binary logs are relay logs) and with @code{--skip-slave-start}. After
the server starts, issue these statements:

@example
mysql> CHANGE MASTER TO
    ->     RELAY_LOG_FILE='myhost-bin.153',
    ->     RELAY_LOG_POS=410,
    ->     MASTER_HOST='some_dummy_string';
mysql> START SLAVE SQL_THREAD;
@end example

The server will read and execute its own binary logs, thus achieving
crash recovery.  Once the recovery is finished, run @code{STOP SLAVE},
shut down the server, delete @file{master.info} and @file{relay-log.info},
and restart the server with its original options.

For the moment, specifying @code{MASTER_HOST} (even with a dummy value) is
required to make the server think it is a slave. In the future, we plan to add
options to get rid of these small constraints.


@node LOAD DATA FROM MASTER, LOAD TABLE FROM MASTER, CHANGE MASTER TO, Replication Slave SQL
@subsubsection @code{LOAD DATA FROM MASTER} Syntax

@findex LOAD DATA FROM MASTER

@c description_for_help_topic LOAD DATA FROM MASTER  LOAD DATA FROM MASTER
@example
LOAD DATA FROM MASTER
@end example

Takes a snapshot of the master and copies it to the slave.  It updates the
values of @code{MASTER_LOG_FILE} and @code{MASTER_LOG_POS} so that the slave
will start replicating from the correct position. Any table and database
exclusion rules specified with the @code{--replicate-*-do-*} and
@code{--replicate-*-ignore-*} options are honored.
@code{--replicate-rewrite-db} is @emph{not} taken into account (because one user
could, with this option, set up a non-unique mapping such as
@code{--replicate-rewrite-db=db1->db3} and
@code{--replicate-rewrite-db=db2->db3}, which would confuse the slave when
it loads the master's tables).

Use of this statement is subject to the following conditions:

@itemize @bullet

@item
It works only with @code{MyISAM} tables.

@item
It acquires a global read lock on the master while taking the snapshot,
which prevents updates on the master during the load operation.

@end itemize

In the future, it is planned to make this statement work with
@code{InnoDB} tables and to remove the need for a global read lock by using
non-blocking online backup.

If you are loading big tables, you might have to increase the values
of @code{net_read_timeout} and @code{net_write_timeout}
on both your master and slave servers.
@xref{Server system variables}.

Note that @code{LOAD DATA FROM MASTER} does @emph{not} copy any
tables from the @code{mysql} database.  This makes it easy to have
different users and privileges on the master and the slave.

The @code{LOAD DATA FROM MASTER} statement
requires the replication account that is used to connect to the master
to have the @code{RELOAD} and @code{SUPER} privileges on the master and the
@code{SELECT} privilege for all master tables you want to load. All
master tables for which the user does not have the @code{SELECT} privilege are
ignored by @code{LOAD DATA FROM MASTER}. This is because the
master will hide them from the user: @code{LOAD DATA FROM MASTER} calls
@code{SHOW DATABASES} to know the master databases to load, but
@code{SHOW DATABASES} returns only databases for which the user has
some privilege.
See @ref{SHOW DATABASES,  , @code{SHOW DATABASES}}.
On the slave's side, the user that issues @code{LOAD DATA FROM MASTER} should
have grants to drop and create the databases and tables that are copied.
@c end_description_for_help_topic


@node LOAD TABLE FROM MASTER, MASTER_POS_WAIT, LOAD DATA FROM MASTER, Replication Slave SQL
@subsubsection @code{LOAD TABLE @var{tbl_name} FROM MASTER} Syntax

@findex LOAD TABLE FROM MASTER

@c description_for_help_topic LOAD TABLE FROM MASTER  LOAD TABLE FROM MASTER
@example
LOAD TABLE @var{tbl_name} FROM MASTER
@end example

Transfers a copy of the table from master to the slave. This statement is
implemented mainly for debugging of @code{LOAD DATA FROM MASTER}.
It requires that the account used for connecting to the master server has the
@code{RELOAD} and @code{SUPER} privileges on the master and the
@code{SELECT} privilege on the master table to load.
On the slave side, the user that issues @code{LOAD TABLE FROM MASTER} should
have privileges to drop and create the table.

The conditions for @code{LOAD DATA FROM MASTER} apply here, too. For
example, @code{LOAD TABLE FROM MASTER} works only for @code{MyISAM} tables.
The timeout notes for @code{LOAD DATA FROM MASTER} apply as well.
@c end_description_for_help_topic


@node MASTER_POS_WAIT, RESET SLAVE, LOAD TABLE FROM MASTER, Replication Slave SQL
@subsubsection @code{MASTER_POS_WAIT()} Syntax

@findex MASTER_POS_WAIT()

@c help_category Miscellaneous Functions@Functions
@c example_for_help_topic MASTER_POS_WAIT
@example
SELECT MASTER_POS_WAIT('@var{master_log_file}', @var{master_log_pos})
@end example
@c help_category Administration

This is a function, not a statement. It is used to ensure that the slave
has read and executed events up to a given position in the master's binary log.
See @ref{Miscellaneous functions} for a full description.
@c end_description_for_help_topic


@node RESET SLAVE, SET GLOBAL SQL_SLAVE_SKIP_COUNTER, MASTER_POS_WAIT, Replication Slave SQL
@subsubsection @code{RESET SLAVE} Syntax

@findex RESET SLAVE

@c description_for_help_topic RESET SLAVE  RESET SLAVE
@example
RESET SLAVE
@end example

Makes the slave forget its replication position in the master's binary logs.
This statement is meant to be used for a clean start: It deletes the
@file{master.info} and @file{relay-log.info} files, all the relay logs,
and starts a new relay log.

@strong{Note}: All relay logs are deleted, even if they have not been
totally executed by the slave SQL thread.  (This is a condition likely to
exist on a replication slave if you have issued a @code{STOP SLAVE}
statement or if the slave is highly loaded.)

Connection information stored in the @file{master.info} file is immediately
reset using any values specified in the corresponding startup options.
This information includes values such as master host, master port, master
user, and master password.  If the slave SQL thread was in the middle of
replicating temporary tables when it was stopped, and @code{RESET SLAVE}
is issued, these replicated temporary tables are deleted on the slave.

This statement was named @code{FLUSH SLAVE} before MySQL 3.23.26.
@c end_description_for_help_topic


@node SET GLOBAL SQL_SLAVE_SKIP_COUNTER, SHOW SLAVE STATUS, RESET SLAVE, Replication Slave SQL
@subsubsection @code{SET GLOBAL SQL_SLAVE_SKIP_COUNTER} Syntax

@findex SET GLOBAL SQL_SLAVE_SKIP_COUNTER

@c description_for_help_topic SET GLOBAL SQL_SLAVE_SKIP_COUNTER  SET GLOBAL SQL_SLAVE_SKIP_COUNTER  
@example
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = @var{n}
@end example

Skip the next @var{n} events from the master. This is
useful for recovering from replication stops caused by a statement.

This statement is valid only when the slave thread is not running.
Otherwise, it produces an error.

Before MySQL 4.0, omit the @code{GLOBAL} keyword from the statement.
@c end_description_for_help_topic


@node SHOW SLAVE STATUS, START SLAVE, SET GLOBAL SQL_SLAVE_SKIP_COUNTER, Replication Slave SQL
@subsubsection @code{SHOW SLAVE STATUS} Syntax

@findex SHOW SLAVE STATUS

@c description_for_help_topic SHOW SLAVE STATUS  SHOW SLAVE STATUS
@example
SHOW SLAVE STATUS
@end example

Provides status information on
essential parameters of the slave threads. If you issue this statement using
the
@command{mysql} client, you can use a @code{\G} statement terminator rather than
semicolon to get a more readable vertical layout:

@example
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
       Slave_IO_State: Waiting for master to send event
          Master_Host: localhost
          Master_User: root
          Master_Port: 3306
        Connect_Retry: 3
      Master_Log_File: gbichot-bin.005
  Read_Master_Log_Pos: 79
       Relay_Log_File: gbichot-relay-bin.005
        Relay_Log_Pos: 548
Relay_Master_Log_File: gbichot-bin.005
     Slave_IO_Running: Yes
    Slave_SQL_Running: Yes
      Replicate_Do_DB:
  Replicate_Ignore_DB:
           Last_Errno: 0
           Last_Error:
         Skip_Counter: 0
  Exec_Master_Log_Pos: 79
      Relay_Log_Space: 552
      Until_Condition: None
       Until_Log_File:
        Until_Log_Pos: 0
   Master_SSL_Allowed: No
   Master_SSL_CA_File:
   Master_SSL_CA_Path:
      Master_SSL_Cert:
    Master_SSL_Cipher:
       Master_SSL_Key:
Seconds_Behind_Master: 8
@end example
@c end_description_for_help_topic

Depending on your version of MySQL, you may not see all the fields just
shown. In particular, several fields are present only as of MySQL 4.1.1.

@code{SHOW SLAVE STATUS} returns the following fields:

@table @code

@item Slave_IO_State
A copy of the @code{State} field of
the output of @code{SHOW PROCESSLIST} for the slave I/O thread. This
tells you if the thread is trying to connect to the master, waiting
for events from the master, reconnecting to the master, and so on. Possible
states are listed in @ref{Replication Implementation Details}. Looking at
this field is necessary because, for example, the thread can be running
but unsuccessfully trying to connect to the master; only this field
will make you aware of the connection problem.
The state of the SQL thread is not copied because it is simpler.
If it is running, there is no
problem; if it is not, you will find the error in the
@code{Last_Error} field (described below). 

This field is present beginning with MySQL 4.1.1.

@item Master_Host
The current master host.

@item Master_User
The current user used to connect to the master.

@item Master_Port
The current master port.

@item Connect_Retry
The current value of the @code{--master-connect-retry} option.

@item Master_Log_File
The name of the master binary log file from which the I/O thread is
currently reading.

@item Read_Master_Log_Pos
The position up to which the I/O thread has read in the current master binary log.

@item Relay_Log_File
The name of the relay log file from which the SQL thread is currently
reading and executing.

@item Relay_Log_Pos
The position up to which the SQL thread has read and executed in the current relay log.

@item Relay_Master_Log_File
The name of the master binary log file that contains the
last event executed by the SQL thread.

@item Slave_IO_Running
Whether or not the I/O thread is started.

@item Slave_SQL_Running
Whether or not the SQL thread is started.

@item Replicate_Do_DB, Replicate_Ignore_DB
The lists of databases that were specified with the
@code{--replicate-do-db} and @code{--replicate-ignore-db} options, if any.

These fields are present beginning with MySQL 4.1.1.

@item Replicate_Do_Table, Replicate_Ignore_Table, Replicate_Wild_Do_Table, Replicate_Wild_Ignore_Table

The lists of tables that were specified with the
@code{--replicate-do-table},
@code{--replicate-ignore-table},
@code{--replicate-wild-do-table},
and
@code{--replicate-wild-ignore_table}
options, if any.

These fields are present beginning with MySQL 4.1.1.

@item Last_Errno, Last_Error
The error number and error message returned by the most recently executed query.
An error number of 0 and message of the empty string mean ``no error.''
If the @code{Last_Error} value is not empty, it will also appear as a
message in the slave's error log.

For example:

@example
Last_Errno: 1051
Last_Error: error 'Unknown table 'z'' on query 'drop table z'
@end example

The message indicates that
the table @code{z} existed on the master and was dropped there, but it
did not exist on the slave, so @code{DROP TABLE} failed on the slave.
(This might occur, for example, if you forget to copy the table to the
slave when setting up replication.)

@item Skip_Counter
The last used value for @code{SQL_SLAVE_SKIP_COUNTER}.

@item Exec_Master_Log_Pos
The position of the last event executed by the SQL thread
from the master's binary log (@code{Relay_Master_Log_File}).
(@code{Relay_Master_Log_File}, @code{Exec_Master_Log_Pos}) in the
master's binary log corresponds to
(@code{Relay_Log_File}, @code{Relay_Log_Pos})
in the relay log.

@item Relay_Log_Space
The total combined size of all existing relay logs.

@item Until_Condition, Until_Log_File, Until_Log_Pos

The values specified in the @code{UNTIL} clause of the @code{START SLAVE}
statement.

@code{Until_Condition} has these values:

@itemize @bullet
@item
@code{None} if no @code{UNTIL} clause was specified
@item
@code{Master} if the slave is reading until a given position in the master's
binary logs
@item
@code{Relay} if the slave is reading until a given position in its relay logs
@end itemize

@code{Until_Log_File} and @code{Until_Log_Pos} indicate the log filename and
position values that define the point at which the SQL thread will stop
executing.

These fields are present beginning with MySQL 4.1.1.

@item Master_SSL_Allowed, Master_SSL_CA_File, Master_SSL_CA_Path, Master_SSL_Cert, Master_SSL_Cipher, Master_SSL_Key

These fields show the
the SSL parameters used by the slave to connect to the master, if any.

@code{Master_SSL_Allowed} has these values:

@itemize @bullet
@item
@code{Yes} if an SSL connection to the master is allowed
@item
@code{No} if an SSL connection to the master is not allowed
@item
@code{Ignored} if an SSL connection is allowed but the slave server does not
have SSL support enabled
@end itemize

The values of the other SSL-related fields correspond to the values of the
@code{--master-ca},
@code{--master-capath},
@code{--master-cert},
@code{--master-cipher},
and
@code{--master-key}
options.

These fields are present beginning with MySQL 4.1.1.

@item Seconds_Behind_Master
The number of seconds that have elapsed since the timestamp of the last
master's event executed by the slave SQL thread. This will be @code{NULL}
when no event has been executed yet, or after @code{CHANGE MASTER} and
@code{RESET SLAVE}. This field can be used to know how ``late'' your slave
is. It will work even though your master and slave don't have identical
clocks. But it has one limitation. Indeed the timestamp is preserved through
replication, which means that if your master M1 is itself a slave of M0, any
event from M1's binlog which has its origin in replication of an event of M0's
binlog, has the timestamp of that last event. This enables MySQL to replicate
@code{TIMESTAMP} successfully. But the drawback for
@code{Seconds_Behind_Master} is that if M1 also receives direct updates from
clients, then the value will randomly go up and down, because sometimes the
last M1's event will be from M0 and sometimes it will be from a direct update.

This field is present beginning with MySQL 4.1.1.

@end table


@node START SLAVE, STOP SLAVE, SHOW SLAVE STATUS, Replication Slave SQL
@subsubsection @code{START SLAVE} Syntax

@findex START SLAVE

@c description_for_help_topic START SLAVE  START SLAVE IO_THREAD SQL_THREAD
@example
START SLAVE [@var{thread_type} [, @var{thread_type}] ... ]
START SLAVE [SQL_THREAD] UNTIL
    MASTER_LOG_FILE = '@var{log_name}', MASTER_LOG_POS = @var{log_pos}
START SLAVE [SQL_THREAD] UNTIL
    RELAY_LOG_FILE = '@var{log_name}', RELAY_LOG_POS = @var{log_pos}

thread_type: IO_THREAD | SQL_THREAD
@end example

@code{START SLAVE} with no options starts both of the slave threads.
The I/O thread reads queries from the master server and stores them in the
relay log.  The SQL thread reads the relay log and executes the
queries.
@code{START SLAVE} requires the @code{SUPER} privilege.

If @code{START SLAVE} succeeds in starting the slave threads, it
returns without any error. However, even in that case, it might be that the slave
threads start and then later stop (for example, because they don't manage to
connect to the master or read its binary logs, or some other
problem). @code{START SLAVE} will not warn you about this. You must
check your slave's error log for error messages generated by
the slave threads, or check that they are running fine with @code{SHOW
SLAVE STATUS}.

@c end_description_for_help_topic

As of MySQL 4.0.2, you can add @code{IO_THREAD} and @code{SQL_THREAD}
options to the statement to name which of the threads to start.

As of MySQL 4.1.1, an @code{UNTIL} clause may be added to specify that
the slave should start and run until the SQL thread reaches a given point in
the master binary logs or in the slave relay logs. When the SQL thread reaches
that point, it stops.  If the @code{SQL_THREAD} option is specified in the
statement, it starts only the SQL thread.  Otherwise, it starts both slave
threads.  If the SQL thread is already running, the @code{UNTIL} clause is
ignored and a warning is issued.

With an @code{UNTIL} clause, you must specify both a log filename and
position. Do not mix master and relay log options.

Any @code{UNTIL} condition is reset by a subsequent @code{STOP SLAVE}
statement, a @code{START SLAVE} statement that includes no @code{UNTIL}
clause, or a server restart.

The @code{UNTIL} clause can be useful for debugging replication, or to
cause replication to proceed until just before the point where you want
to avoid having the slave replicate a statement. For example, if an unwise
@code{DROP TABLE} statement was executed on the master, you can use
@code{UNTIL} to tell the slave to execute up to that point but no farther.
To find what the event is, use @command{mysqlbinlog} with the master logs or
slave relay logs, or by using a @code{SHOW BINLOG EVENTS} statement.

If you are using @code{UNTIL} to have the slave process replicated queries in
sections, it is recommended that you start the slave with the
@code{--skip-slave-start} option to prevent the SQL thread from running
when the slave server starts.  It is probably best to use this option in an
option file rather than on the command line, so that an unexpected server
restart does not cause it to be forgotten.

The @code{SHOW SLAVE STATUS} statement includes output fields that display
the current values of the @code{UNTIL} condition.

This statement is called @code{SLAVE START} before MySQL 4.0.5.
For the moment, @code{SLAVE START} is still accepted for backward
compatibility, but is deprecated.


@node STOP SLAVE,  , START SLAVE, Replication Slave SQL
@subsubsection @code{STOP SLAVE} Syntax

@findex STOP SLAVE

@c description_for_help_topic STOP SLAVE  STOP SLAVE IO_THREAD SQL_THREAD
@example
STOP SLAVE [@var{thread_type} [, @var{thread_type}] ... ]

thread_type: IO_THREAD | SQL_THREAD
@end example

Stops the slave threads.
@code{STOP SLAVE} requires the @code{SUPER} privilege.

Like @code{START SLAVE}, as of MySQL 4.0.2, this statement
may be used with the @code{IO_THREAD} and @code{SQL_THREAD} options to name
the thread or threads to stop.

@c end_description_for_help_topic

This statement is called @code{SLAVE STOP} before MySQL 4.0.5.
For the moment, @code{SLAVE STOP} is still accepted for backward
compatibility, but is deprecated.

@c DISABLED UNTIL IT WORKS (OR UNTIL WE GIVE THIS STRATEGY UP?)
@c @node SHOW NEW MASTER, PURGE MASTER LOGS, SHOW BINLOG EVENTS, Replication SQL
@c @subsubsection @code{SHOW NEW MASTER FOR SLAVE}

@c @code{SHOW NEW MASTER FOR SLAVE
@c WITH MASTER_LOG_FILE='@var{logfile}' AND MASTER_LOG_POS=@var{pos} AND
@c MASTER_LOG_SEQ=@var{log_seq} AND MASTER_SERVER_ID=@var{server_id}}
@c
@c This statement is used when a slave of a possibly dead/unavailable master
@c needs to be switched to replicate off another slave that has been
@c replicating the same master. The statement will return recalculated
@c replication coordinates (the slave's current binary log file
@c name and position within that file). The output can be used in a subsequent
@c @code{CHANGE MASTER TO} statement. Normal users should never need to run
@c this statement. It is primarily reserved for internal use by the fail-safe
@c replication code. We may later change the syntax if we find a more
@c intuitive way to describe this operation.


@node SQLPS,  , Replication SQL, SQL Syntax
@section SQL Syntax for Prepared Statements
@findex PREPARE
@findex EXECUTE
@findex DEALLOCATE PREPARE

Support for server-side prepared statements was added in MySQL 4.1.
This support takes advantage of the efficient client/server binary protocol,
provided that you use an appropriate client programming interface. Candidate
interfaces include the MySQL C API client library (for C programs) or
MySQL Connector/J (for Java programs).  For example, the C API provides
a set of function calls that make up its prepared statement API.
@xref{C API Prepared statements}.
Other language interfaces can provide support for prepared statements that
use the binary protocol by linking in the C client library.  (The mysqli
extension in PHP 5.0 does this, for example.)

@c TODO: have something (a table?) that summarizes versions when various
@c APIs support the binary protocol. Might be better in API chapter, though.
@c C: 4.1.0
@c C/J: 3.1.0
@c ODBC: ?
@c PHP: mysqli in PHP 5.0.0
@c DBD::mysql: ?

Beginning with MySQL 4.1.3, an alternative interface to prepared statements
is available:  SQL syntax for prepared statements.  This interface is not as
efficient as using the binary protocol through a prepared statement API, but
requires no programming because it is available directly at the SQL level:

@itemize @bullet

@item
You can use it when no programming interface is available to you.

@item
You can use it from any program that allows you to send SQL statements to the
server to be executed, such as the @command{mysql} client program.

@item
You can use it even if the client is using an old version of the client
library. The only requirement is that you be able to connect to a server that
is recent enough to support SQL syntax for prepared statements.

@end itemize

SQL syntax for prepared statements is intended to be used for situations
such as these:

@itemize @bullet
@item
You want to test how prepared statements will work in your application
before doing the application coding.
Or perhaps an application has a problem executing prepared statements and you
want to determine what the problem is interactively.

@item
You want to create a test case that describes a problem you are having with
prepared statements, so that you can file a bug report.

@item
You need to use prepared statements but do not have access to a programming
API that supports them.

@end itemize

SQL syntax for prepared statements is based on three SQL statements:

@example
PREPARE @var{stmt_name} FROM @var{preparable_stmt};

EXECUTE @var{stmt_name} [USING @@@var{var_name} [, @@@var{var_name}] ...];

@{DEALLOCATE | DROP@} PREPARE @var{stmt_name};
@end example

The @code{PREPARE} statement prepares a statement and assigns it
a name, @var{stmt_name}, by which to refer to the statement later.
Statement names are not case sensitive.
@var{preparable_stmt} is either a string literal or a user variable that
contains the text of the statement.  The text must represent a single SQL
statement, not multiple statements.  Within the statement, @samp{?}
characters can be used as parameter markers to indicate where data values
are to be bound to the query later when you execute it. The @samp{?}
characters should not be enclosed within quotes, even if you intend to bind
them to string values.

If a prepared statement already exists with the same name, it is deallocated
implicitly before the new statement is prepared. This means that if the new
statement contains an error and cannot be prepared, an error is returned
and no statement with the given name will exist.

The scope of a prepared statement is the client session within which it is
created. Other clients cannot see it.

After preparing a statement, you execute it with an @code{EXECUTE}
statement that refers to the prepared statement name. If the prepared
statement contains any parameter markers, you must supply a @code{USING}
clause that lists user variables containing the values to be bound to
the parameters.
Parameter values can be supplied only by user variables, and the @code{USING}
clause must name exactly as many variables as the number of parameter markers
in the statement.

You can execute a given prepared statement multiple times, passing it
different variables or setting the variables to different values before
each execution.

To deallocate a prepared statement, use the @code{DEALLOCATE PREPARE}
statement.  Attempting to execute a prepared statement after deallocating
it results in an error.

If you terminate a client session without deallocating a previously prepared
statement, the server deallocates it automatically.

The following statements can be used as prepared statements:
@code{CREATE TABLE},
@code{DELETE},
@code{DO},
@code{INSERT},
@code{REPLACE},
@code{SELECT},
@code{SET},
@code{UPDATE},
and most
@code{SHOW},
statements.
Other statements are not yet supported.

The following examples show two equivalent ways of preparing a statement that
computes the hypotenuse of a triangle given the lengths of the two sides.

The first example shows how to create a prepared statment by using a string
literal to supply the text of the statement:

@example
mysql> PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql> SET @@a = 3;
mysql> SET @@b = 4;
mysql> EXECUTE stmt1 USING @@a, @@b;
+------------+
| hypotenuse |
+------------+
|          5 |
+------------+
mysql> DEALLOCATE PREPARE stmt1;
@end example

The second example is similar, but supplies the text of the statement
with a user variable:

@example
mysql> SET @@s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql> PREPARE stmt2 FROM @@s;
mysql> SET @@a = 6;
mysql> SET @@b = 8;
mysql> EXECUTE stmt2 USING @@a, @@b;
+------------+
| hypotenuse |
+------------+
|         10 |
+------------+
mysql> DEALLOCATE PREPARE stmt2;
@end example

SQL syntax for prepared statements cannot be used in nested fashion.
That is, a statement passed to @code{PREPARE} cannot itself be a
@code{PREPARE}, @code{EXECUTE}, or @code{DEALLOCATE PREPARE} statement.

Also, SQL syntax for prepared statements is distinct from using
prepared statement API calls.  For example, you cannot use the
@code{mysql_stmt_prepare()} C API function to prepare a @code{PREPARE},
@code{EXECUTE}, or @code{DEALLOCATE PREPARE} statement.



@node Storage engines, InnoDB, SQL Syntax, Top
@chapter MySQL Storage Engines and Table Types

@cindex types, of tables
@cindex storage engines, choosing
@cindex table types, choosing
@cindex MySQL storage engines
@cindex MySQL table types
@cindex @code{BDB} storage engine
@cindex @code{BDB} table type
@cindex @code{BerkeleyDB} storage engine
@cindex @code{BerkeleyDB} table type
@cindex @code{HEAP} storage engine
@cindex @code{HEAP} table type
@cindex @code{ISAM} storage engine
@cindex @code{ISAM} table type
@cindex @code{InnoDB} storage engine
@cindex @code{InnoDB} table type
@cindex @code{MEMORY} storage engine
@cindex @code{MEMORY} table type
@cindex @code{MERGE} storage engine
@cindex @code{MERGE} table type
@cindex @code{MyISAM} storage engine
@cindex @code{MyISAM} table type
@cindex @code{EXAMPLE} storage engine
@cindex @code{EXAMPLE} table type
@cindex @code{CSV} storage engine
@cindex @code{CSV} table type
@cindex @code{ARCHIVE} storage engine
@cindex @code{ARCHIVE} table type

MySQL supports several storage engines that act as handlers for different
table types. MySQL storage engines include both those that handle
transaction-safe tables and those that handle non-transaction-safe tables:

@itemize @bullet
@item
The original storage engine was @code{ISAM}, which managed non-transactional
tables. This engine has been replaced by @code{MyISAM} and should no longer
be used. It is deprecated in MySQL 4.1, and will be removed in MySQL 5.0.

@item
In MySQL 3.23.0, the @code{MyISAM} and @code{HEAP} storage engines were
introduced.  @code{MyISAM} is an improved replacement for @code{ISAM}.
The @code{HEAP} storage engine provides in-memory tables.
The @code{MERGE} storage engine was
added in MySQL 3.23.25.  It allows a collection of identical @code{MyISAM}
tables to be handled as a single table.  All three of these storage engines
handle non-transactional tables, and all are included in MySQL by default.
Note that the
@code{HEAP} storage engine now
is known as the @code{MEMORY} engine.

@item
The @code{InnoDB} and @code{BDB}
storage engines that handle transaction-safe tables were introduced in later
versions of MySQL 3.23.
Both are available in source distributions as of MySQL 3.23.34a.
@code{BDB} is included in MySQL-Max binary distributions on those operating
systems that support it.  @code{InnoDB} also is included in MySQL-Max binary
distributions for MySQL 3.23.  Beginning with MySQL 4.0, @code{InnoDB}
is included by default in all MySQL binary distributions.  In source
distributions, you can enable or disable either engine by configuring MySQL
as you like.

@item
The @code{EXAMPLE} storage engine was added in MySQL 4.1.3.  It is a
``stub'' engine that does nothing.  You can create tables with this engine,
but no data can be stored into them or retrieved from them. The purpose of
this engine is to serve as an example in the MySQL source code that
illustrates how to begin writing new storage engines. As such, it is
primarily of interest to developers.

@item
@code{NDB Cluster} is the storage engine used by MySQL Cluster to implement
tables that are partitioned over many computers. It is available in source
code distributions as of MySQL 4.1.2 and binary distributions as of
MySQL-Max 4.1.3.

@item
The @code{ARCHIVE} storage engine was added in MySQL 4.1.3.  It is used
for storing large amounts of data without indexes in a very small footprint.

@item
The @code{CSV} storage engine was added in MySQL 4.1.4. This engine stores
data in text files using comma-separated-values format.

@end itemize

This chapter describes each of the MySQL storage engines except for
@code{InnoDB} and @code{NDB Cluster}, which are covered in @ref{InnoDB}
and @ref{NDBCluster}.

When you create a new table, you can tell MySQL what type of table to create
by adding an @code{ENGINE} or @code{TYPE} table option to the @code{CREATE
TABLE} statement:

@example
CREATE TABLE t (i INT) ENGINE = INNODB;
CREATE TABLE t (i INT) TYPE = MEMORY;
@end example

@code{ENGINE} is the preferred term, but cannot be used before MySQL 4.0.18.
@code{TYPE} is available beginning with MySQL 3.23.0, the first
version of MySQL for which multiple storage engines were available.

If you omit the @code{ENGINE} or @code{TYPE} option, the default storage
engine is used.  By default this is @code{MyISAM}.  You can change it by
using the @code{--default-storage-engine} or @code{--default-table-type}
server startup option, or by setting the @code{storage_engine} or
@code{table_type} system variable.

When MySQL is installed on Windows using the MySQL Configuration Wizard,
the @code{InnoDB} storage engine will be the default instead of @code{MyISAM}.
@xref{mysql-config-wizard-introduction}.

To convert a table from one type to another, use an @code{ALTER TABLE}
statement that indicates the new type:

@example
ALTER TABLE t ENGINE = MYISAM;
ALTER TABLE t TYPE = BDB;
@end example

See @ref{CREATE TABLE, , @code{CREATE TABLE}} and
@ref{ALTER TABLE, , @code{ALTER TABLE}}.

@c We should consider removing this or making a new section 'What happens when a
@c table is created'. Currently it seems a bit out of place and not that
@c helpful.

@c TODO: this behavior now may be "using the default storage engine"
@c rather than "using MyISAM", but when did that change?

If you try to use a storage engine that is not compiled in or that is
compiled in but deactivated, MySQL instead creates a table of type
@code{MyISAM}.  This behavior is convenient when you want to copy tables
between MySQL servers that support different storage engines. (For example, in
a replication setup, perhaps your
master server supports transactional storage engines for increased safety,
but the slave servers use only non-transactional storage engines for greater
speed.)

This automatic automatic substitution of the @code{MyISAM} table type when an
unavailable type is specified can be confusing for new MySQL
users.  In MySQL 4.1 and up, a warning is generated when a table type is
automatically changed.

MySQL always creates an @file{.frm} file to hold the table and column
definitions. The table's index and data may be stored in one or more other
files, depending on the table type.
The server creates the @file{.frm} file above the storage engine level.
Individual storage engines create any additional files required for the tables
that they manage.

A database may contain tables of different types.

Transaction-safe tables (TSTs) have several advantages over
non-transaction-safe tables (NTSTs):

@itemize @bullet
@item
Safer. Even if MySQL crashes or you get hardware problems, you
can get your data back, either by automatic recovery or from a backup
plus the transaction log.
@item
You can combine many statements and accept them all at the same time with
the @code{COMMIT} statement (if autocommit is disabled).
@item
You can execute @code{ROLLBACK} to ignore your changes (if
autocommit is disabled).
@item
If an update fails, all your changes will be restored. (With
non-transaction-safe tables, all
changes that have taken place are permanent.)
@item
Transaction-safe storage engines
can provide better concurrency for tables that get many updates concurrently
with reads.
@end itemize

Note that to use the @code{InnoDB} storage engine in MySQL 3.23, you
must configure at least the @code{innodb_data_file_path} startup option.
In 4.0 and up, @code{InnoDB} uses default configuration values if you specify
none.
@xref{InnoDB configuration,  , @code{InnoDB} configuration}.

Non-transaction-safe tables have several advantages of their own, all
of which occur because there is no transaction overhead:

@itemize @bullet
@item
Much faster
@item
Lower disk space requirements
@item
Less memory required to perform updates
@end itemize

You can combine transaction-safe and non-transaction-safe tables in the same statements to get the best
of both worlds. However, within a transaction with autocommit disabled,
changes to non-transaction-safe tables still are committed immediately and
cannot be rolled back.

@menu
* MyISAM storage engine::       The @code{MyISAM} Storage Engine
* MERGE storage engine::        The @code{MERGE} Storage Engine
* MEMORY storage engine::       The @code{MEMORY} (@code{HEAP}) Storage Engine
* BDB storage engine::          The @code{BDB} (@code{BerkeleyDB}) Storage Engine
* EXAMPLE storage engine::      The @code{EXAMPLE} Storage Engine
* ARCHIVE storage engine::      The @code{ARCHIVE} Storage Engine
* CSV storage engine::          The @code{CSV} Storage Engine
* ISAM storage engine::         The @code{ISAM} Storage Engine
@end menu


@node MyISAM storage engine, MERGE storage engine, Storage engines, Storage engines
@section The @code{MyISAM} Storage Engine

@cindex @code{MyISAM} storage engine
@cindex @code{MyISAM} table type
@cindex tables, @code{MyISAM}

@code{MyISAM} is the default storage engine as of MySQL 3.23. It is
based on the @code{ISAM} code but has many useful extensions.

Each @code{MyISAM} table is stored on disk in three files.  The files have
names that begin with the table name and have an extension to indicate the
file type.  An @file{.frm} file stores the table definition.  The data file
has an @file{.MYD} (MYData) extension.  The index file has an @file{.MYI}
(MYIndex) extension,

To specify explicitly that you want a @code{MyISAM} table, indicate that with
an @code{ENGINE} or @code{TYPE} table option:

@example
CREATE TABLE t (i INT) ENGINE = MYISAM;
CREATE TABLE t (i INT) TYPE = MYISAM;
@end example

Normally, the @code{ENGINE} or @code{TYPE} option is unnecessary;
@code{MyISAM} is the default storage engine unless the default has been
changed.

You can check or repair @code{MyISAM} tables with the @command{myisamchk}
utility. @xref{Crash recovery}. You can compress @code{MyISAM} tables with
@command{myisampack} to take up much less space.
@xref{myisampack, , @command{myisampack}}.

The following characteristics of the @code{MyISAM} storage engine are
improvements over the older @code{ISAM} engine:

@itemize @bullet

@item
All data values are stored with the low byte first. This makes the data
machine and operating system independent. The only requirement for binary
portability is that the machine uses two's-complement signed integers
(as every machine for the last 20 years has) and IEEE floating-point
format (also totally dominant among mainstream machines). The only area of
machines that may not support binary compatibility are embedded systems,
which sometimes have peculiar processors.

There is no big speed penalty for storing data low byte first; the bytes
in a table row normally are unaligned and it doesn't take that much more
power to read an unaligned byte in order than in reverse order.  Also, the
code in the server that fetches column values is not time critical compared
to other code.

@item
Large files (up to 63-bit file length) are supported on
filesystems and operating systems that support large files.

@item
Dynamic-sized rows are much less fragmented when mixing deletes
with updates and inserts.  This is done by automatically combining adjacent
deleted blocks and by extending blocks if the next block is deleted.

@item
The maximum number of indexes per table is 64 (32 before MySQL 4.1.2).  This
can be changed by recompiling.  The maximum number of columns per index is 16.

@item
The maximum key length is 1000 bytes (500 before MySQL 4.1.2).
This can be changed by recompiling.  For the case of a key longer than
250 bytes, a larger key block size than the default of 1024 bytes is used.

@item
@code{BLOB} and @code{TEXT} columns can be indexed.

@item
@code{NULL} values are allowed in indexed columns.  This takes 0-1
bytes per key.

@item
All numeric key values are stored with the high byte first to allow better index
compression.

@item
Index files are usually much smaller with @code{MyISAM} than with
@code{ISAM}. This means that @code{MyISAM} normally will use less
system resources than @code{ISAM}, but will need more CPU time when inserting
data into a compressed index.

@item
When records are inserted in sorted order (as when you are using an
@code{AUTO_INCREMENT} column), the index tree is split so that the high
node only contains one key. This improves space utilization in the index
tree.

@item
Internal handling of one @code{AUTO_INCREMENT} column per table.
@code{MyISAM} automatically updates this column for @code{INSERT/UPDATE}.  This
makes @code{AUTO_INCREMENT} columns faster (at least 10%).
Values at the top of the sequence are not reused after being deleted as they
are with @code{ISAM}.  (When an @code{AUTO_INCREMENT} column is
defined as the last column of a multiple-column index, reuse of deleted
values does occur.)  The @code{AUTO_INCREMENT} value can be reset with
@code{ALTER TABLE} or @command{myisamchk}.

@item
If a table doesn't have free blocks in the middle of the data file, you can
@code{INSERT} new rows into it at the same time that other threads are
reading from the table. (These are known as concurrent inserts.) A free block can
occur as a result of deleting rows or an update of a dynamic length row with
more data than its current contents.  When all free blocks are used up
(filled in), future inserts become concurrent again.

@item
You can put the data file and index file on different directories
to get more speed with the @code{DATA DIRECTORY} and @code{INDEX DIRECTORY}
table options to
@code{CREATE TABLE}. @xref{CREATE TABLE,  , @code{CREATE TABLE}}.

@item
As of MySQL 4.1, each character column can have a different character set.

@item
There is a flag in the @code{MyISAM} index file that indicates whether the
table was closed correctly.  If @command{mysqld} is started with the
@code{--myisam-recover} option, @code{MyISAM} tables are automatically
checked when opened and repaired if the table wasn't closed
properly.

@item
@command{myisamchk} marks tables as checked if you run it with the
@code{--update-state} option. @command{myisamchk --fast} checks only those
tables that don't have this mark.

@item
@command{myisamchk --analyze} stores statistics for key parts, not only for
whole keys as in @code{ISAM}.

@item
@command{myisampack} can pack @code{BLOB} and @code{VARCHAR} columns;
@command{pack_isam} cannot.

@end itemize

@code{MyISAM} also supports the following features, which MySQL
will be able to use in the near future:

@itemize @bullet

@item
Support for a true @code{VARCHAR} type; a @code{VARCHAR} column starts
with a length stored in two bytes.

@item
Tables with @code{VARCHAR} may have fixed or dynamic record length.

@item
@code{VARCHAR} and @code{CHAR} columns may be up to 64KB.

@item
A hashed computed index can be used for @code{UNIQUE}. This will allow
you to have @code{UNIQUE} on any combination of columns in a table. (You
can't search on a @code{UNIQUE} computed index, however.)

@end itemize

@menu
* MyISAM start::                @code{MyISAM} Startup Options
* Key space::                   Space Needed for Keys
* MyISAM table formats::        @code{MyISAM} Table Storage Formats
* MyISAM table problems::       @code{MyISAM} Table Problems
@end menu


@node MyISAM start, Key space, MyISAM storage engine, MyISAM storage engine
@subsection @code{MyISAM} Startup Options

The following options to @command{mysqld} can be used to change the behavior of
@code{MyISAM} tables:

@table @code

@item --myisam-recover=@var{mode}

Set the mode for automatic recovery of crashed @code{MyISAM} tables.

@item --delay-key-write=ALL

Don't flush key buffers between writes for any @code{MyISAM} table.

@strong{Note}: If you do this, you should not use @code{MyISAM} tables from
another program (such as from another MySQL server or with @command{myisamchk}) when
the table is in use. Doing so will lead to index corruption.

Using @code{--external-locking} will not help for tables that use
@code{--delay-key-write}.

@end table

@xref{Server options}.

The following system variables affect the behavior of
@code{MyISAM} tables:

@table @code

@item bulk_insert_buffer_size

The size of the tree cache used in bulk insert
optimization. @strong{Note}: This is a limit @emph{per thread}!

@item myisam_max_extra_sort_file_size

Used to help MySQL to decide when to use the slow but safe key cache index
creation method. @strong{Note}: This parameter is given in megabytes
before MySQL 4.0.3, and in bytes as of 4.0.3.

@item myisam_max_sort_file_size

Don't use the fast sort index method to create an index if the temporary
file would become larger than this.  @strong{Note}: This parameter is
given in megabytes before MySQL 4.0.3, and in bytes as of 4.0.3.

@item myisam_sort_buffer_size

Set the size of the buffer used when recovering tables.

@end table

@xref{Server system variables}.

Automatic recovery is activated if you start @command{mysqld} with the
@code{--myisam-recover} option. In this case, when the server opens a
@code{MyISAM} table, it checks whether the table
is marked as crashed or whether the open count variable for the
table is not 0 and you are running the server with
@code{--skip-external-locking}.  If either of these conditions is true, the
following happens:

@itemize @bullet

@item
The table is checked for errors.

@item
If the server finds an error, it tries to do a fast table repair (with
sorting and without re-creating the data file).

@item
If the repair fails because of an error in the data file (for example, a
duplicate-key error), the server tries again, this time re-creating the
data file.

@item
If the repair still fails, the server tries once more with the old repair option
method (write row by row without sorting). This method should be able to repair
any type of error and has low disk space requirements.

@end itemize

If the recovery wouldn't be able to recover all rows from a previous
completed statement and you didn't specify @code{FORCE} in the value of the
@code{--myisam-recover} option, automatic repair aborts with an error
message in the error log:

@example
Error: Couldn't repair table: test.g00pages
@end example

If you specify @code{FORCE}, a warning like this is written instead:

@example
Warning: Found 344 of 354 rows when repairing ./test/g00pages
@end example

Note that if the automatic recovery value includes @code{BACKUP}, the
recovery process creates files with names of the form
@file{@var{tbl_name-datetime}.BAK}.  You should have a @command{cron} script that
automatically moves these files from the database directories to backup
media.


@node Key space, MyISAM table formats, MyISAM start, MyISAM storage engine
@subsection Space Needed for Keys

@cindex key space, MyISAM

@code{MyISAM} tables use B-tree indexes. You can roughly calculate
the size for the index file as @code{(key_length+4)/0.67}, summed over
all keys.  This is for the worst case when all keys are inserted in
sorted order and the table doesn't have any compressed keys.

String indexes are space compressed. If the first index part is a
string, it will also be prefix compressed.  Space compression makes the
index file smaller than the worst-case figure if the string column has a lot
of trailing space or is a @code{VARCHAR} column that is not always used
to the full length. Prefix compression is used on keys that start
with a string.  Prefix compression helps if there are many strings
with an identical prefix.

In @code{MyISAM} tables, you can also prefix compress numbers by specifying
@code{PACK_KEYS=1} when you create the table.  This helps when you have
many integer keys that have an identical prefix when the numbers are stored
high-byte first.


@node MyISAM table formats, MyISAM table problems, Key space, MyISAM storage engine
@subsection @code{MyISAM} Table Storage Formats

@code{MyISAM} supports three different storage formats. Two of them (fixed
and dynamic format) are chosen automatically depending on the type of
columns you are using. The third, compressed format, can be created only
with the @command{myisampack} utility.

When you @code{CREATE} or @code{ALTER} a table that has no @code{BLOB}
or @code{TEXT} columns, you can force the table format to @code{FIXED} or
@code{DYNAMIC} with the @code{ROW_FORMAT} table option. This causes
@code{CHAR} and @code{VARCHAR} columns to become @code{CHAR} for
@code{FIXED} format or @code{VARCHAR} for @code{DYNAMIC} format.

In the future, you will be able to compress or decompress tables by specifying
@code{ROW_FORMAT=@{COMPRESSED | DEFAULT@}} to @code{ALTER TABLE}.
@xref{CREATE TABLE,  , @code{CREATE TABLE}}.

@menu
* Static format::               Static (Fixed-Length) Table Characteristics
* Dynamic format::              Dynamic Table Characteristics
* Compressed format::           Compressed Table Characteristics
@end menu


@node Static format, Dynamic format, MyISAM table formats, MyISAM table formats
@subsubsection Static (Fixed-Length) Table Characteristics

Static format is the default for @code{MyISAM} tables.  It is used when the
table contains no variable-length columns (@code{VARCHAR}, @code{BLOB}, or
@code{TEXT}). Each row is stored using a fixed number of bytes.

Of the three @code{MyISAM} storage formats, static format is the simplest
and most secure (least subject to corruption). It is also the fastest of the
on-disk formats. The speed comes from the easy way that rows in the data file
can be found on disk: When looking up a row based on a row number in the
index, multiply the row number by the row length.  Also, when scanning a
table, it is very easy to read a constant number of records with each disk
read operation.

The security is evidenced if your computer crashes while the MySQL server is
writing to a fixed-format @code{MyISAM} file. In this case, @command{myisamchk}
can easily determine where each row starts and ends, so it can usually
reclaim all records except the partially written one. Note that @code{MyISAM}
table
indexes can always be reconstructed based on the data rows.

General characteristics of static format tables:

@itemize @bullet

@item
All @code{CHAR}, @code{NUMERIC}, and @code{DECIMAL} columns are space-padded
to the column width.

@item
Very quick.

@item
Easy to cache.

@item
Easy to reconstruct after a crash, because records are located in fixed
positions.

@item
Reorganization is unnecessary unless you delete a huge number of records
and want to return free disk space to the operating system. To do this,
use @code{OPTIMIZE TABLE} or @command{myisamchk -r}.

@item
Usually require more disk space than for dynamic-format tables.

@end itemize


@node Dynamic format, Compressed format, Static format, MyISAM table formats
@subsubsection Dynamic Table Characteristics

@cindex dynamic table characteristics
@cindex tables, dynamic

Dynamic storage format is used if a @code{MyISAM} table contains any
variable-length columns (@code{VARCHAR}, @code{BLOB}, or @code{TEXT}), or if
the table was created with the @code{ROW_FORMAT=DYNAMIC} option.

This format is a little more complex because each row has a header that
indicates
how long it is. One record can also end up at more than one location when it
is made longer as a result of an update.

@cindex tables, defragment
You can use @code{OPTIMIZE TABLE} or @command{myisamchk} to defragment a
table. If you have fixed-length columns that you access or change frequently
in a table that also contains some variable-length columns, it might be
a good idea to move the variable-length columns to other tables just to
avoid fragmentation.

General characteristics of dynamic-format tables:

@itemize @bullet

@item
All string columns are dynamic except those with a length less than four.

@item
Each record is preceded by a bitmap that indicates which columns contain the
empty string (for string columns) or zero (for numeric columns). Note that
this does not include columns that contain @code{NULL} values. If a string
column has a length of zero after trailing space removal, or a numeric
column has a value of zero, it is marked in the bitmap and not saved to
disk.  Non-empty strings are saved as a length byte plus the string
contents.

@item
Much less disk space usually is required than for fixed-length tables.

@item
Each record uses only as much space as is required. However, if a record
becomes larger, it is split into as many pieces as are required, resulting
in record fragmentation.  For example, if you update a row with information
that extends the row length, the row will be fragmented.  In this case,
you may have to run @code{OPTIMIZE TABLE} or @command{myisamchk -r} from time to time to get better
performance.  Use @command{myisamchk -ei} to obtain table statistics.

@item
More difficult than static-format tables to reconstruct after a crash,
because a record may be fragmented into many pieces and a link (fragment)
may be missing.

@item
The expected row length for dynamic-sized records is calculated using the
following expression:

@example
3
+ (@var{number of columns} + 7) / 8
+ (@var{number of char columns})
+ (@var{packed size of numeric columns})
+ (@var{length of strings})
+ (@var{number of NULL columns} + 7) / 8
@end example

There is a penalty of 6 bytes for each link. A dynamic record is linked
whenever an update causes an enlargement of the record. Each new link will be
at least 20 bytes, so the next enlargement will probably go in the same link.
If not, there will be another link. You may check how many links there are
with @command{myisamchk -ed}. All links may be removed with @command{myisamchk -r}.

@end itemize


@node Compressed format,  , Dynamic format, MyISAM table formats
@subsubsection Compressed Table Characteristics

@cindex tables, compressed format
@cindex compressed tables
@cindex MyISAM, compressed tables
@cindex @command{myisampack}

Compressed storage format is a read-only format that is generated with the
@command{myisampack} tool.

All MySQL distributions as of version 3.23.19 include @command{myisampack} by
default. (This version is when MySQL was placed under the GPL.) For earlier
versions, @command{myisampack} was included only with licenses or support
agreements, but the server still can read tables that were compressed
with @command{myisampack}.  Compressed tables can be uncompressed with
@command{myisamchk}.  (For the @code{ISAM} storage engine, compressed tables
can be created with @command{pack_isam} and uncompressed with @command{isamchk}.)

Compressed tables have the following characteristics:

@itemize @bullet

@item
Compressed tables take very little disk space. This minimizes disk usage, which
is very nice when using slow disks (such as CD-ROMs).

@item
Each record is compressed separately, so there is very little access overhead.  The
header for a record is fixed (1-3 bytes) depending on the biggest record in the
table.  Each column is compressed differently.  There is usually a different
Huffman tree for each column.  Some of the compression types are:

@itemize @minus

@item
Suffix space compression.

@item
Prefix space compression.

@item
Numbers with a value of zero are stored using one bit.

@item
If values in an integer column have a small range, the column is stored
using the smallest possible type. For example, a @code{BIGINT} column
(eight bytes) can be stored as a @code{TINYINT} column (one byte) if all
its values are in the range from @code{-128} to @code{127}.

@item
If a column has only a small set of possible values, the column type is
converted to @code{ENUM}.

@item
A column may use a combination of the preceding compressions.

@end itemize

@item
Can handle fixed-length or dynamic-length records.

@end itemize


@node MyISAM table problems,  , MyISAM table formats, MyISAM storage engine
@subsection @code{MyISAM} Table Problems

The file format that MySQL uses to store data has been extensively
tested, but there are always circumstances that may cause database tables
to become corrupted.

@menu
* Corrupted MyISAM tables::     Corrupted @code{MyISAM} Tables
* MyISAM table close::          Problems from Tables Not Being Closed Properly
@end menu


@node Corrupted MyISAM tables, MyISAM table close, MyISAM table problems, MyISAM table problems
@subsubsection Corrupted @code{MyISAM} Tables

Even though the @code{MyISAM} table format is very reliable (all changes to
a table made by an SQL statement are written before the statement returns),
you can still get corrupted tables if some of the following things happen:

@itemize @bullet

@item
The @command{mysqld} process is killed in the middle of a write.

@item
Unexpected computer shutdown occurs (for example, the computer is turned off).

@item
Hardware errors.

@item
You are using an external program (such as @command{myisamchk}) on a table that
is being modified by the server at the same time.

@item
A software bug in the MySQL or @code{MyISAM} code.

@end itemize

Typical symptoms for a corrupt table are:

@itemize @bullet

@item
You get the following error while selecting data from the table:

@example
Incorrect key file for table: '...'. Try to repair it
@end example

@item
Queries don't find rows in the table or return incomplete data.

@end itemize

You can check whether a @code{MyISAM} table is okay with the @code{CHECK
TABLE} statement.  You can repair a corrupted @code{MyISAM} table with
@code{REPAIR TABLE}.  When @command{mysqld} is not running, you can also
check or repair a table with the @command{myisamchk} command.
See @ref{CHECK TABLE,  , @code{CHECK TABLE}},
@ref{REPAIR TABLE,  , @code{REPAIR TABLE}}, and @ref{myisamchk syntax}.

If your tables become corrupted frequently, you should try to determine why
this is happening.  The most important thing to know is whether the table
became corrupted as a result of a server crash. You can verify this easily
by looking for a recent @code{restarted mysqld} message in the error log.
If there is such a message, it is likely that that table corruption is a
result of the server dying.  Otherwise, corruption may have occurred during
normal operation, which is a bug. You should try to create a reproducible
test case that demonstrates the problem.
See @ref{Crashing} and @ref{Reproduceable test case}.


@node MyISAM table close,  , Corrupted MyISAM tables, MyISAM table problems
@subsubsection Problems from Tables Not Being Closed Properly

Each @code{MyISAM} index (@file{.MYI}) file has a counter in the header
that can be used to check whether a table has been closed properly.
If you get the following warning from @code{CHECK TABLE} or @command{myisamchk},
it means that this counter has gone out of sync:

@example
clients are using or haven't closed the table properly
@end example

This warning doesn't necessarily mean that the table is corrupted, but
you should at least check the table to verify that it's okay.

The counter works as follows:

@itemize @bullet

@item
The first time a table is updated in MySQL, a counter in the
header of the index files is incremented.

@item
The counter is not changed during further updates.

@item
When the last instance of a table is closed (because of a @code{FLUSH
TABLES} operation or because there isn't room in the table cache), the
counter is decremented if the table has been updated at any point.

@item
When you repair the table or check the table and it is found to be okay,
the counter is reset to zero.

@item
To avoid problems with interaction with other processes that might
check the table, the counter is not decremented on close if it was zero.

@end itemize

In other words, the counter can go out of sync only under these conditions:

@itemize @bullet

@item
The @code{MyISAM} tables are copied without a preceding @code{LOCK TABLES} and
@code{FLUSH TABLES}.

@item
MySQL has crashed between an update and the final close.
(Note that the table may still be okay, because MySQL always issues writes
for everything between each statement.)

@item
A table was modified by @command{myisamchk --recover} or @command{myisamchk
--update-state} at the same time that it was in use by @command{mysqld}.

@item
Many @command{mysqld} servers are using the table and one server performed a
@code{REPAIR TABLE} or @code{CHECK TABLE} on the table while it was in use by
another server.  In this setup, it is safe to use @code{CHECK TABLE},
although you might get the warning from other servers. However, @code{REPAIR
TABLE} should be avoided because when one server replaces the data file
with a new one, this is not signaled to the other servers.

In general, it is a bad idea to share a data directory among multiple servers.
See @ref{Multiple servers} for additional discussion.

@end itemize


@node MERGE storage engine, MEMORY storage engine, MyISAM storage engine, Storage engines
@section The @code{MERGE} Storage Engine

@cindex @code{MERGE} storage engine
@cindex @code{MERGE} table type
@cindex tables, @code{MERGE}

@cindex tables, merging
@cindex MERGE tables, defined
@cindex tables, partitioning
@c description_for_help_topic MERGE

@menu
* MERGE table problems::        @code{MERGE} Table Problems
@end menu

The @code{MERGE} storage engine was introduced in MySQL 3.23.25. It
is also known as the @code{MRG_MyISAM} engine. The code is now reasonably
stable.

A @code{MERGE} table is a collection of identical @code{MyISAM} tables that
can be used as one.  ``Identical'' means that all tables have
identical column and index information.  You can't merge tables in which the
columns are listed in a different order, don't have exactly the same columns, or
have the indexes in different order.  However, any or all of the tables can be
compressed with @command{myisampack}.
@xref{myisampack, , @command{myisampack}}.
Differences in table options such as @code{AVG_ROW_LENGTH}, @code{MAX_ROWS},
or @code{PACK_KEYS} do not matter.
@c end_description_for_help_topic


When you create a @code{MERGE} table, MySQL creates two files on disk.
The files have names that begin with the table name and have an extension
to indicate the file type.  An @file{.frm} file stores the table definition,
and an @file{.MRG} file contains the names of the tables that should be
used as one.  (Originally, all used tables had to be in the same database
as the @code{MERGE} table itself. This restriction has been lifted as of
MySQL 4.1.1.)

You can use @code{SELECT}, @code{DELETE}, @code{UPDATE}, and (as of MySQL
4.0) @code{INSERT} on the collection of tables.  For the moment, you must
have @code{SELECT}, @code{UPDATE}, and @code{DELETE} privileges on the
tables that you map to a @code{MERGE} table.

If you @code{DROP} the @code{MERGE} table, you are dropping only the
@code{MERGE} specification. The underlying tables are not affected.

When you create a @code{MERGE} table, you must specify a
@code{UNION=(list-of-tables)} clause that indicates which tables you want to
use as one. You can optionally specify an @code{INSERT_METHOD} option if you
want inserts for the @code{MERGE} table to happen in the first or last table
of the @code{UNION} list. If you don't specify any @code{INSERT_METHOD}
option or specify it with a value of @code{NO}, attempts to insert records
into the @code{MERGE} table result in an error.

The following example shows how to create a @code{MERGE} table:

@c example_for_help_topic MERGE
@example
mysql> CREATE TABLE t1 (
    ->    a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->    message CHAR(20));
mysql> CREATE TABLE t2 (
    ->    a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->    message CHAR(20));
mysql> INSERT INTO t1 (message) VALUES ('Testing'),('table'),('t1');
mysql> INSERT INTO t2 (message) VALUES ('Testing'),('table'),('t2');
mysql> CREATE TABLE total (
    ->    a INT NOT NULL AUTO_INCREMENT,
    ->    message CHAR(20), INDEX(a))
    ->    TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;
@end example

Note that the @code{a} column is indexed in the @code{MERGE} table, but is
not declared as a @code{PRIMARY KEY} as it is in the underlying
@code{MyISAM} tables. This is necessary because a @code{MERGE} table cannot
enforce uniqueness over the set of underlying tables.

After creating the @code{MERGE} table, you can do things like this:

@example
mysql> SELECT * FROM total;
+---+---------+
| a | message |
+---+---------+
| 1 | Testing |
| 2 | table   |
| 3 | t1      |
| 1 | Testing |
| 2 | table   |
| 3 | t2      |
+---+---------+
@end example

Note that you can also manipulate the @file{.MRG} file directly from
outside of the MySQL server:

@example
shell> cd /@var{mysql-data-directory}/@var{current-database}
shell> ls -1 t1 t2 > total.MRG
shell> mysqladmin flush-tables
@end example

To remap a @code{MERGE} table to a different collection of @code{MyISAM}
tables, you can do one of the following:

@itemize @bullet

@item
@code{DROP} the table and re-create it.

@item
Use @code{ALTER TABLE @var{tbl_name} UNION=(...)} to change the list of underlying
tables.

@item
Change the @file{.MRG} file and issue a @code{FLUSH TABLE} statement for the
@code{MERGE} table and all underlying tables to force the storage engine to
read the new definition file.

@end itemize

@code{MERGE} tables can help you solve the following problems:

@itemize @bullet

@item
Easily manage a set of log tables. For example, you can put data from
different months into separate tables, compress some of them with
@command{myisampack}, and then create a @code{MERGE} table to use them as one.

@item
Obtain more speed. You can split a big read-only table based on some
criteria, and then put individual tables on different disks.
A @code{MERGE} table on this could be much faster than using
the big table. (You can also use a RAID table to get the same
kind of benefits.)

@item
Do more efficient searches. If you know exactly what you are looking
for, you can search in just one of the split tables for some queries
and use a @code{MERGE} table for others.  You can even have many
different @code{MERGE} tables that use overlapping sets of tables.

@item
Do more efficient repairs. It's easier to repair the individual tables that
are mapped to a @code{MERGE} table than to repair a single really big table.

@item
Instantly map many tables as one. A @code{MERGE} table need not maintain
an index of its own because it uses the indexes of the individual tables.
As a result, @code{MERGE} table collections are @emph{very} fast to create
or remap.  (Note that you must still specify the index definitions when
you create a @code{MERGE} table, even though no indexes are created.)

@item
If you have a set of tables that you join as a big table on demand or
batch, you should instead create a @code{MERGE} table on them on demand.
This is much faster and will save a lot of disk space.

@item
Exceed the file size limit for the operating system. Each @code{MyISAM} table
is bound by this limit, but a collection of @code{MyISAM} tables is not.

@item
You can create an alias or synonym for a @code{MyISAM} table by defining a
@code{MERGE} table that maps to that single table.  There should be no
really notable performance impact of doing this (only a couple of indirect
calls and @code{memcpy()} calls for each read).

@end itemize

The disadvantages of @code{MERGE} tables are:

@itemize @bullet

@item
You can use only identical @code{MyISAM} tables for a @code{MERGE} table.

@item
@code{MERGE} tables use more file descriptors. If 10 clients are using a
@code{MERGE} table that maps to 10 tables, the server uses
(10*10) + 10 file descriptors.  (10 data file descriptors for each of the 10
clients, and 10 index file descriptors shared among the clients.)

@item
Key reads are slower. When you read a key, the @code{MERGE}
storage engine needs to issue a read on all underlying tables to check
which one most closely matches the given key.  If you then do a ``read-next,''
the @code{MERGE} storage engine needs to search the read buffers
to find the next key. Only when one key buffer is used up, the storage engine
will need to read the next key block. This makes @code{MERGE} keys much slower
on @code{eq_ref} searches, but not much slower on @code{ref} searches.
See @ref{EXPLAIN,  , @code{EXPLAIN}} for more information about @code{eq_ref}
and @code{ref}.

@end itemize

@node MERGE table problems,  , MERGE storage engine, MERGE storage engine
@subsection @code{MERGE} Table Problems

The following are the known problems with @code{MERGE} tables:

@itemize @bullet

@item
If you use @code{ALTER TABLE} to change a @code{MERGE} table to another
table type, the mapping to the underlying tables is lost. Instead, the rows
from the underlying @code{MyISAM} tables are copied into the altered table,
which then is assigned the new type.

@item
Before MySQL 4.1.1, all underlying tables and the @code{MERGE} table itself
had to be in the same database.

@item
@code{REPLACE} doesn't work.

@item
You can't use
@code{DROP TABLE},
@code{ALTER TABLE},
@code{DELETE FROM} without a @code{WHERE} clause,
@code{REPAIR TABLE},
@code{TRUNCATE TABLE},
@code{OPTIMIZE TABLE}, or
@code{ANALYZE TABLE}
on any of the tables that are
mapped into a @code{MERGE} table that is ``open.''  If you do this, the
@code{MERGE} table may still refer to the original table and you will
get unexpected results. The easiest way to work around this deficiency
is to issue a @code{FLUSH TABLES} statement to ensure that no @code{MERGE}
tables remain ``open.''

@item
A @code{MERGE} table cannot maintain @code{UNIQUE} constraints over the
whole table.  When you perform an @code{INSERT}, the data goes into the
first or last @code{MyISAM} table (depending on the value of the
@code{INSERT_METHOD} option). MySQL ensures that unique key values remain
unique within that @code{MyISAM} table, but not across all the tables in the
collection.

@item
Before MySQL 3.23.49, @code{DELETE FROM merge_table} used without a
@code{WHERE} clause only clears the mapping for the table. That is, it
incorrectly empties the @file{.MRG} file rather than deleting records from
the mapped tables.

@item
Using @code{RENAME TABLE} on an active @code{MERGE} table may corrupt the
table.  This will be fixed in MySQL 4.1.x.

@item
When you create a @code{MERGE} table, there is no check whether the
underlying tables exist and have identical structure.  When the @code{MERGE}
table is used, MySQL does a quick check that the record length for all
mapped tables is equal, but this is not foolproof.  If you create a
@code{MERGE} table from dissimilar @code{MyISAM} tables, you are very likely
to run into strange problems.

@item
Index order in the @code{MERGE} table and its underlying tables should be
the same.  If you use @code{ALTER TABLE} to add a @code{UNIQUE} index
to a table used in a @code{MERGE} table, and then use @code{ALTER TABLE} to
add a non-unique index on the @code{MERGE} table, the index order will be
different for the tables if there was an old non-unique index in the
underlying table. (This is because @code{ALTER TABLE} puts @code{UNIQUE}
indexes before non-unique indexes to be able to detect duplicate keys as early
as possible.)  Consequently, queries may return unexpected results.

@item
@code{DROP TABLE} on a table that is in use by a @code{MERGE} table does
not work on Windows because the @code{MERGE} storage engine does the table
mapping hidden from the upper layer of MySQL.  Because Windows doesn't allow
you to delete files that are open, you first must flush all @code{MERGE}
tables (with @code{FLUSH TABLES}) or drop the @code{MERGE} table before
dropping the table.

@end itemize


@node MEMORY storage engine, BDB storage engine, MERGE storage engine, Storage engines
@section The @code{MEMORY} (@code{HEAP}) Storage Engine

@c TODO: parts of this may be true only for hash indexes. Now that
@c MEMORY supports BTREE indexes, some statements may need to be qualified.

@cindex @code{HEAP} storage engine
@cindex @code{HEAP} table type
@cindex @code{MEMORY} storage engine
@cindex @code{MEMORY} table type
@cindex tables, @code{MEMORY}
@cindex tables, @code{HEAP}

The @code{MEMORY} storage engine creates tables with contents that are stored
in memory. Before MySQL 4.1, @code{MEMORY} tables are called @code{HEAP}
tables. As of 4.1, @code{HEAP} is a synonym for @code{MEMORY}, and
@code{MEMORY} is the preferred term.

Each @code{MEMORY} table is associated with one disk file.  The filename
begins with the table name and has an extension of @file{.frm} to indicate
that it stores the table definition.

To specify explicitly that you want a @code{MEMORY} table, indicate that with
an @code{ENGINE} or @code{TYPE} table option:

@example
CREATE TABLE t (i INT) ENGINE = MEMORY;
CREATE TABLE t (i INT) TYPE = HEAP;
@end example

@code{MEMORY} tables are stored in memory and use hash indexes.  This makes
them very fast, and very useful for creating temporary tables!  However,
when the server shuts down, all data stored in @code{MEMORY} tables is lost.
The tables continue to exist because their definitions are stored in the
@file{.frm} files on disk, but their contents will be empty when the server
restarts.

Here is an example that shows how you might create, use, and remove a
@code{MEMORY} table:

@example
mysql> CREATE TABLE test TYPE=MEMORY
    ->     SELECT ip,SUM(downloads) AS down
    ->     FROM log_table GROUP BY ip;
mysql> SELECT COUNT(ip),AVG(down) FROM test;
mysql> DROP TABLE test;
@end example

@code{MEMORY} tables have the following characteristics:

@itemize @bullet

@item
Space for @code{MEMORY} tables is allocated in small blocks. The tables use
100% dynamic hashing (on inserting). No overflow areas and no extra key
space are needed.  There is no extra space needed for free lists.  Deleted
rows are put in a linked list and are reused when you insert new data into
the table.  @code{MEMORY} tables also don't have problems with deletes plus
inserts, which is common with hashed tables.

@item
@code{MEMORY} tables allow up to 32 indexes per table, 16 columns per index,
and a maximum key length of 500 bytes.

@item
Before MySQL 4.1, the @code{MEMORY} storage engine implements only hash
indexes.  From MySQL 4.1 on,
hash indexes are still the default, but
you can specify explicitly that a @code{MEMORY}
table index should be @code{HASH} or @code{BTREE} by adding a @code{USING}
clause:

@example
CREATE TABLE lookup
    (id INT, INDEX USING HASH (id))
    ENGINE = MEMORY;
CREATE TABLE lookup
    (id INT, INDEX USING BTREE (id))
    ENGINE = MEMORY;
@end example

General characteristics of B-tree and hash indexes are described in
@ref{MySQL indexes}.

@item
You can have non-unique keys in a @code{MEMORY} table.
(This is an uncommon feature for implementations of hash indexes.)

@item
If you have a hash index on a @code{MEMORY} table that has a high degree of
key duplication (many index entries containing the same value), updates to
the table that affect key values and all deletes will be significantly
slower.  The degree of slowdown is proportional to the degree of duplication
(or, inversely proportional to the index cardinality).  You can use a
@code{BTREE} index to avoid this problem.

@item
@code{MEMORY} tables use a fixed record length format.

@item
@code{MEMORY} doesn't support @code{BLOB} or @code{TEXT} columns.

@item
@code{MEMORY} doesn't support @code{AUTO_INCREMENT} columns before MySQL
4.1.0.

@item
Prior to MySQL 4.0.2, @code{MEMORY} doesn't support indexes on columns that
can contain @code{NULL} values.

@item
@code{MEMORY} tables are shared between all clients (just like any other
non-@code{TEMPORARY}
table).

@item
@code{MEMORY} table contents are stored in memory, which is a property that
@code{MEMORY} tables share with internal tables that the server creates on
the fly while processing queries.  However, the two types of tables differ in
that @code{MEMORY} tables are not subject to storage conversion, whereas
internal tables are:

@itemize @bullet
@item
If an internal table becomes too large, the server automatically converts it
to an on-disk table.  The size limit is determined by the value of the
@code{tmp_table_size} system variable.

@item
@code{MEMORY} tables are never converted to disk tables.  To ensure that you
don't accidentally do anything foolish, you can set the
@code{max_heap_table_size} system variable to impose a maximum size on
@code{MEMORY} tables.  For individual tables, you can also specify a
@code{MAX_ROWS} table option in the @code{CREATE TABLE} statement.
@end itemize

@item
The server needs enough extra memory to maintain all @code{MEMORY} tables
that are in use at the same time.

@item
To free memory used by a @code{MEMORY} table if you no longer require its
contents, you should execute @code{DELETE} or
@code{TRUNCATE TABLE}, or else remove the table with @code{DROP TABLE}.

@item
If you want to populate a @code{MEMORY} table when the MySQL server starts,
you can use the @code{--init-file} option.  For example, you can put
statements such as @code{INSERT INTO ... SELECT} or @code{LOAD DATA INFILE}
into the file to load the table from some persistent data source.
@xref{Server options}.

@item
If you are using replication, the master server's @code{MEMORY} tables
become empty when it is shut down and restarted.  However, a slave is not
aware that these tables have become empty, so it will return out-of-date
content if you select data from them.  Beginning with MySQL 4.0.18, when a
@code{MEMORY} table is used on the master for the first time since the master's
startup, a @code{DELETE FROM} statement is written to the master's binary
log automatically, thus synchronizing the slave to the master again.  Note
that even with this strategy, the slave still has out-of-date data in the
table during the interval between the master's restart and its first use of
the table.  But if you use the @code{--init-file} option to populate the
@code{MEMORY} table on the master at startup, it ensures that the failing
time interval is zero.

@item
The memory needed for one row in a @code{MEMORY} table is calculated using the
following expression:

@example
SUM_OVER_ALL_KEYS(@var{max_length_of_key} + sizeof(char*) * 2)
+ ALIGN(@var{length_of_row}+1, sizeof(char*))
@end example

@code{ALIGN()} represents a round-up factor to cause the row length to be an
exact multiple of the @code{char} pointer size.
@code{sizeof(char*)} is 4 on 32-bit machines and 8 on 64-bit machines.

@end itemize


@node BDB storage engine, EXAMPLE storage engine, MEMORY storage engine, Storage engines
@section The @code{BDB} (@code{BerkeleyDB}) Storage Engine

@cindex @code{BDB} storage engine
@cindex @code{BDB} table type
@cindex @code{BerkeleyDB} storage engine
@cindex @code{BerkeleyDB} table type
@cindex tables, @code{BDB}
@cindex tables, @code{Berkeley DB}

@menu
* BDB portability::             Operating Systems Supported by @code{BDB}
* BDB install::                 Installing @code{BDB}
* BDB start::                   @code{BDB} Startup Options
* BDB characteristics::         Characteristics of @code{BDB} Tables
* BDB TODO::                    Things We Need to Fix for @code{BDB}
* BDB restrictions::            Restrictions on @code{BDB} Tables
* BDB errors::                  Errors That May Occur When Using @code{BDB} Tables
@end menu

Sleepycat Software has provided MySQL with the Berkeley DB transactional
storage engine. This storage engine typically is called @code{BDB} for short.
Support for the @code{BDB} storage engine is included in MySQL source
distributions starting from version 3.23.34a and is activated in MySQL-Max
binary distributions.

@code{BDB} tables may have a greater chance of surviving crashes and are also
capable of @code{COMMIT} and @code{ROLLBACK} operations on transactions.
The MySQL source distribution comes with a @code{BDB} distribution that has a
couple of small patches to make it work more smoothly with MySQL.
You can't use a non-patched @code{BDB} version with MySQL.

We at MySQL AB are working in close cooperation with Sleepycat to keep the
quality of the MySQL/BDB interface high.  (Even though Berkeley DB is in
itself very tested and reliable, the MySQL interface is still considered
gamma quality.  We are improving and optimizing it.)

When it comes to support for any problems involving @code{BDB} tables, we
are committed to helping our users locate the problem and create a
reproducible test case.  Any such test case will be forwarded to Sleepycat,
which in turn will help us find and fix the problem.  As this is a two-stage
operation, any problems with @code{BDB} tables may take a little longer for
us to fix than for other storage engines.  However, we anticipate no
significant difficulties with this procedure because the Berkeley DB code
itself is used in many applications other than MySQL.

For general information about Berkeley DB, please visit the Sleepycat Web site,
@uref{http://www.sleepycat.com/}.


@node BDB portability, BDB install, BDB storage engine, BDB storage engine
@subsection Operating Systems Supported by @code{BDB}

Currently, we know that the @code{BDB} storage engine works with the following
operating systems:

@itemize @bullet
@item
Linux 2.x Intel
@item
Sun Solaris (SPARC and x86)
@item
FreeBSD 4.x/5.x (x86, sparc64)
@item
IBM AIX 4.3.x
@item
SCO OpenServer
@item
SCO UnixWare 7.1.x
@end itemize

@code{BDB} does not work with the following operating systems:

@itemize @bullet
@item
Linux 2.x Alpha
@item
Linux 2.x AMD64
@item
Linux 2.x IA-64
@item
Linux 2.x s390
@item
Mac OS X
@end itemize

Note: The preceding lists are not complete. We will update them as we
receive more information.

If you build MySQL from source with support for @code{BDB} tables, but the
following error occurs when you start @command{mysqld}, it means @code{BDB}
is not supported for your architecture:

@example
bdb: architecture lacks fast mutexes: applications cannot be threaded
Can't init databases
@end example

In this case, you must rebuild MySQL without @code{BDB} table support or
start the server with the @code{--skip-bdb} option.


@node BDB install, BDB start, BDB portability, BDB storage engine
@subsection Installing @code{BDB}

If you have downloaded a binary version of MySQL that includes support for
Berkeley DB, simply follow the usual binary distribution installation
instructions. (MySQL-Max distributions include @code{BDB} support.)

If you build MySQL from source, you can enable @code{BDB} support by running
@command{configure} with the @code{--with-berkeley-db} option in addition
to any other options that you normally use.  Download a distribution for
MySQL 3.23.34 or newer, change location into its top-level directory,
and run this command:

@example
shell> ./configure --with-berkeley-db [other-options]
@end example

For more information, see
@ref{Installing binary},
@ref{mysqld-max, , @command{mysqld-max}}, and
@xref{Installing source}.


@node BDB start, BDB characteristics, BDB install, BDB storage engine
@subsection @code{BDB} Startup Options

The following options to @command{mysqld} can be used to change the behavior of
the @code{BDB} storage engine:

@table @code

@item --bdb-home=@var{path}

The base directory for @code{BDB} tables.  This should be the same directory
you
use for @code{--datadir}.

@item --bdb-lock-detect=@var{method}

The @code{BDB} lock detection method. The option value should be 
@code{DEFAULT}, @code{OLDEST}, @code{RANDOM}, or @code{YOUNGEST}.

@item --bdb-logdir=@var{path}

The @code{BDB} log file directory.

@item --bdb-no-recover

Don't start Berkeley DB in recover mode.

@item --bdb-no-sync

Don't synchronously flush the @code{BDB} logs.

@item --bdb-shared-data

Start Berkeley DB in multi-process mode.  (Don't use @code{DB_PRIVATE} when
initializing Berkeley DB.)

@item --bdb-tmpdir=@var{path}

The @code{BDB} temporary file directory.

@item --skip-bdb

Disable the @code{BDB} storage engine.

@end table

@xref{Server options}.

The following system variable affects the behavior of
@code{BDB} tables:

@table @code

@item bdb_max_lock

The maximum number of locks you can have active on a @code{BDB} table.

@end table

@xref{Server system variables}.

If you use the @code{--skip-bdb} option, MySQL will not initialize the Berkeley DB
library and this will save a lot of memory.  However, if you use this
option, you cannot use @code{BDB} tables.  If you try to create a @code{BDB}
table, MySQL will create a @code{MyISAM} table instead.

Normally, you should start @command{mysqld} without the @code{--bdb-no-recover}
option if you intend to use @code{BDB} tables.  However, this may give you
problems when you try to start @command{mysqld} if the @code{BDB} log files are
corrupted.
@xref{Starting server}.

With the @code{bdb_max_lock} variable, you can specify the maximum number of
locks that can be active on a @code{BDB} table.  The default is
10,000. You should increase this if errors such as the following occur
when you perform long transactions or when @command{mysqld} has to examine
many rows to execute a query:

@example
bdb: Lock table is out of available locks
Got error 12 from ...
@end example

You may also want to change the @code{binlog_cache_size} and
@code{max_binlog_cache_size} variables if you are using large
multiple-statement transactions.
@xref{Binary log}.


@node BDB characteristics, BDB TODO, BDB start, BDB storage engine
@subsection Characteristics of @code{BDB} Tables

Each @code{BDB} table is stored on disk in two files.  The files have
names that begin with the table name and have an extension to indicate the
file type.  An @file{.frm} file stores the table definition, and a @file{.db}
file contains the table data and indexes.

To specify explicitly that you want a @code{BDB} table, indicate that with
an @code{ENGINE} or @code{TYPE} table option:

@example
CREATE TABLE t (i INT) ENGINE = BDB;
CREATE TABLE t (i INT) TYPE = BDB;
@end example

@code{BerkeleyDB} is a synonym for @code{BDB} in the @code{ENGINE} or
@code{TYPE} option.

The @code{BDB} storage engine provides transactional tables. The way you use
these tables depends on the autocommit mode:

@itemize @bullet

@item
If you are running with autocommit enabled (which is the default),
changes to @code{BDB} tables are committed immediately and cannot be rolled
back.

@item
If you are running with autocommit disabled, changes do not become
permanent until you execute a @code{COMMIT} statement.  Instead of
committing, you can execute @code{ROLLBACK} to forget the changes.

You can start a transaction with
the @code{BEGIN WORK} statement to suspend autocommit, or with
@code{SET AUTOCOMMIT=0} to disable autocommit explicitly.

@end itemize

@xref{COMMIT,  , @code{COMMIT}}.

The @code{BDB} storage engine has the following characteristics:

@itemize @bullet

@item
@code{BDB} tables can have up to 31 indexes per table, 16 columns per index,
and a maximum key size of 1024 bytes (500 bytes before MySQL 4.0).

@item
MySQL requires a @code{PRIMARY KEY} in each @code{BDB} table so that each row
can be uniquely identified.  If you don't create one explicitly,
MySQL creates and maintains a hidden @code{PRIMARY KEY} for
you.  The hidden key has a length of five bytes and is incremented for each
insert attempt.

@item
The @code{PRIMARY KEY} will be faster than any other index, because the
@code{PRIMARY KEY} is stored together with the row data.  The other indexes
are stored as the key data + the @code{PRIMARY KEY}, so it's important to
keep the @code{PRIMARY KEY} as short as possible to save disk space and get
better speed.

This behavior is similar to that of @code{InnoDB}, where shorter primary
keys save space not only in the primary index but in secondary indexes as
well.

@item
If all columns you access in a @code{BDB} table are part of the same index or
part of the primary key, MySQL can execute the query
without having to access the actual row.  In a @code{MyISAM} table, this can
be done only if the columns are part of the same index.

@item
Sequential scanning is slower than for @code{MyISAM} tables because the data
in @code{BDB} tables is stored in B-trees and not in a separate data file.

@item
Key values are not prefix- or suffix-compressed like key values in
@code{MyISAM} tables. In other words, key information takes a little more
space in @code{BDB} tables compared to @code{MyISAM} tables.

@item
There are often holes in the @code{BDB} table to allow you to insert
new rows in the middle of the index tree.  This makes @code{BDB} tables
somewhat larger than @code{MyISAM} tables.

@item
@code{SELECT COUNT(*) FROM @var{tbl_name}} is slow for @code{BDB} tables, because
no row count is maintained in the table.

@item
The optimizer needs to know the approximate number of rows in the table.
MySQL solves this by counting inserts and maintaining this in a separate
segment in each @code{BDB} table.  If you don't issue a lot of @code{DELETE}
or @code{ROLLBACK} statements, this number should be accurate enough for
the MySQL optimizer. However, MySQL stores the number only on close, so
it may be incorrect if the server terminates unexpectedly. It should not
be fatal even if this number is not 100% correct.  You can update the row
count by using @code{ANALYZE TABLE} or @code{OPTIMIZE TABLE}.
See @ref{ANALYZE TABLE,  , @code{ANALYZE TABLE}} and
@ref{OPTIMIZE TABLE,  , @code{OPTIMIZE TABLE}}.

@item
Internal locking in @code{BDB} tables is done at the page level.

@item
@code{LOCK TABLES} works on @code{BDB} tables as with other tables.  If you
don't use @code{LOCK TABLE}, MySQL issues an internal multiple-write lock on
the table (a lock that doesn't block other writers) to ensure that the
table will be properly locked if another thread issues a table lock.

@item
To be able to roll back transactions, the @code{BDB} storage engine
maintains log files.  For maximum performance, you can use the
@code{--bdb-logdir} option to place the @code{BDB} logs on a different disk
than the one where your databases are located.

@item
MySQL performs a checkpoint each time a new @code{BDB} log file is started,
and removes any @code{BDB} log files that are not needed for current
transactions.  You can also use @code{FLUSH LOGS} at any time to checkpoint
the Berkeley DB tables.

For disaster recovery, you should use table backups plus MySQL's binary log.
@xref{Backup}.

@strong{Warning:} If you delete old log files that are still in use,
@code{BDB} will not be able to do recovery at all and you may lose data if
something goes wrong.

@item
Applications must always be prepared to handle cases where
any change of a @code{BDB} table may cause an automatic rollback and any
read may fail with a deadlock error.

@item
If you get full disk with a @code{BDB} table, you will get an error
(probably error 28) and the transaction should roll back.  This contrasts
with @code{MyISAM} and @code{ISAM} tables, for which @command{mysqld} will wait
for enough free disk before continuing.

@end itemize


@node BDB TODO, BDB restrictions, BDB characteristics, BDB storage engine
@subsection Things We Need to Fix for @code{BDB}

@itemize @bullet

@item
It's very slow to open many @code{BDB} tables at the same time. If you are
going to use @code{BDB} tables, you should not have a very large table cache
(for example, with a size larger than 256) and you should use the
@code{--no-auto-rehash} option when you use the @command{mysql} client.  We
plan to partly fix this in 4.0.

@item
@code{SHOW TABLE STATUS} doesn't yet provide very much information for
@code{BDB}
tables.

@item
Optimize performance.

@item
Change to not use page locks at all for table scanning operations.
@end itemize


@node BDB restrictions, BDB errors, BDB TODO, BDB storage engine
@subsection Restrictions on @code{BDB} Tables

The following list indicates restrictions that you must observe when using
@code{BDB} tables:

@itemize @bullet
@item
Each
@code{BDB} table stores in the @file{.db} file the path to the file as it
was created.  This was done to be able to detect locks in a multi-user
environment that supports symlinks.  However, the consequence is that
@code{BDB} table files cannot be moved from one database directory to
another.

@item
When making backups of @code{BDB} tables, you must either use
@command{mysqldump} or else make a backup that includes the files for each
@code{BDB} table (the @file{.frm} and @file{.db} files) as well as the
@code{BDB} log files.  The @code{BDB} storage engine stores unfinished
transactions in its log files and requires them to be present when
@command{mysqld} starts.  The @code{BDB} logs are the files in the data
directory with names of the form @file{log.XXXXXXXXXX} (ten digits).

@item
If a column that allows @code{NULL} values has a unique index, only a single
@code{NULL} value is allowed. This differs from other storage engines.

@end itemize

@node BDB errors,  , BDB restrictions, BDB storage engine
@subsection Errors That May Occur When Using @code{BDB} Tables

@itemize @bullet
@item
If the following error occurs when you start @command{mysqld}, it means that
the new @code{BDB} version doesn't support the old log file format:

@example
bdb:  Ignoring log file: .../log.XXXXXXXXXX:
unsupported log version #
@end example

In this case, you must delete all @code{BDB} logs from your data directory
(the files with names that have the format @file{log.XXXXXXXXXX}) and
restart @command{mysqld}.  We also recommend that you then use @command{mysqldump
--opt} to dump your @code{BDB} tables, drop the tables, and restore them
from the dump file.

@item
If autocommit mode is disabled and you drop a @code{BDB} table that
is referenced in another transaction, you may get error messages of the
following form in your MySQL error log:

@example
001119 23:43:56  bdb:  Missing log fileid entry
001119 23:43:56  bdb:  txn_abort: Log undo failed for LSN:
                       1 3644744: Invalid
@end example

This is not fatal, but until the problem is fixed, we recommend that you
not drop @code{BDB} tables except while autocommit mode is enabled.  (The
fix is not trivial.)

@end itemize


@node EXAMPLE storage engine, ARCHIVE storage engine, BDB storage engine, Storage engines
@section The @code{EXAMPLE} Storage Engine

@cindex @code{EXAMPLE} storage engine
@cindex @code{EXAMPLE} table type
@cindex tables, EXAMPLE

The @code{EXAMPLE} storage engine was added in MySQL 4.1.3.  It is a
``stub'' engine that does nothing.  Its purpose is to serve as an example in
the MySQL source code that illustrates how to begin writing new storage
engines. As such, it is primarily of interest to developers.

To examine the source for the @code{EXAMPLE} engine, look in the
@file{sql/examples} directory of a source distribution for MySQL 4.1.3 or
newer.

To enable this storage engine, use the @code{--with-example-storage-engine}
option to @command{configure} when you build MySQL.

When you create an @code{EXAMPLE} table, the server creates a table
definition file in the database directory. The file begins with the table
name and has an @file{.frm} extension.  No other files are created.  No data
can be stored into the table or retrieved from it.

@example
mysql> CREATE TABLE test (i INT) ENGINE = EXAMPLE;
Query OK, 0 rows affected (0.78 sec)

mysql> INSERT INTO test VALUES(1),(2),(3);
ERROR 1031 (HY000): Table storage engine for 'test' doesn't have this option

mysql> SELECT * FROM test;
Empty set (0.31 sec)
@end example

The @code{EXAMPLE} storage engine does not support indexing.


@node ARCHIVE storage engine, CSV storage engine, EXAMPLE storage engine, Storage engines
@section The @code{ARCHIVE} Storage Engine

@cindex @code{ARCHIVE} storage engine
@cindex @code{ARCHIVE} table type
@cindex tables, ARCHIVE

The @code{ARCHIVE} storage engine was added in MySQL 4.1.3.
It is used for storing large amounts of data without indexes in a very
small footprint.

To enable this storage engine, use the @code{--with-archive-storage-engine}
option to @command{configure} when you build MySQL.

When you create an @code{ARCHIVE} table, the server creates a table definition
file in the database directory. The file begins with the table name and has
an @file{.frm} extension.  The storage engine creates other files, all having
names beginning with the table name.  The data and metadata files have
extensions of @file{.ARZ} and @file{.ARM}. An @file{.ARN} file may appear
during optimization operations.

The @code{ARCHIVE} engine supports only @code{INSERT} and @code{SELECT}.  (No
deletes, replaces, or updates.)  A @code{SELECT} performs a complete table
scan. Records are compressed as they are inserted.  Use of @code{OPTIMIZE
TABLE} can analyze the table and pack it into a smaller format.

The @code{ARCHIVE} engine uses row-level locking.


@node CSV storage engine, ISAM storage engine, ARCHIVE storage engine, Storage engines
@section The @code{CSV} Storage Engine

@cindex @code{CSV} storage engine
@cindex @code{CSV} table type
@cindex tables, CSV

The @code{CSV} storage engine was added in MySQL 4.1.4. This engine stores
data in text files using comma-separated-values format.

To enable this storage engine, use the @code{--with-csv-storage-engine}
option to @command{configure} when you build MySQL.

When you create a @code{CSV} table, the server creates a table definition
file in the database directory. The file begins with the table name and has
an @file{.frm} extension.  The storage engine also creates a data file. Its
name begins with the table name and has a @file{.CSV} extension.  The data
file is a plain text file. When you store data into the table, the storage
engine saves it into the data file in CSV format.

@example
mysql> CREATE TABLE test(i INT, c CHAR(10)) ENGINE = CSV;
Query OK, 0 rows affected (0.12 sec)

mysql> INSERT INTO test VALUES(1,'record one'),(2,'record two');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM test;
+------+------------+
| i    | c          |
+------+------------+
|    1 | record one |
|    2 | record two |
+------+------------+
2 rows in set (0.00 sec)
@end example

If you examine the @file{test.CSV} file in the database directory after
executing the preceding statements, its contents look like this:

@example
"1","record one"
"2","record two"
@end example

The @code{CSV} storage engine does not support indexing.


@node ISAM storage engine,  , CSV storage engine, Storage engines
@section The @code{ISAM} Storage Engine

@cindex @code{ISAM} storage engine
@cindex @code{ISAM} table type
@cindex tables, ISAM

The original storage engine in MySQL was the @code{ISAM} engine. It was the
only storage engine available until MySQL 3.23, when the improved
@code{MyISAM} engine was introduced as the default. @code{ISAM} now is
deprecated.  As of MySQL 4.1, it's included in the source but not enabled in
binary distributions.  It will disappear in MySQL 5.0.
Embedded MySQL server versions do not support @code{ISAM} tables by default.

Due to the deprecated status of @code{ISAM}, and because @code{MyISAM} is
an improvement over @code{ISAM}, you are advised to convert any remaining
@code{ISAM} tables to @code{MySAM} as soon as possible.  To convert an
@code{ISAM} table to a @code{MyISAM} table, use an @code{ALTER TABLE}
statement:

@example
mysql> ALTER TABLE @var{tbl_name} TYPE = MYISAM;
@end example

For more information about @code{MyISAM}, see
@ref{MyISAM storage engine,  , @code{MyISAM} storage engine}.

Each @code{ISAM} table is stored on disk in three files.  The files have
names that begin with the table name and have an extension to indicate the
file type.  An @file{.frm} file stores the table definition.  The data file
has an @file{.ISD} extension.  The index file has an @file{.ISM}
extension.

@code{ISAM} uses B-tree indexes.

You can check or repair @code{ISAM} tables with the @command{isamchk} utility.
@xref{Crash recovery}.

@code{ISAM} has the following properties:

@itemize @bullet
@item Compressed and fixed-length keys
@item Fixed and dynamic record length
@item 16 indexes per table, with 16 key parts per key
@item Maximum key length 256 bytes (default)
@item Data values are stored in machine format; this is fast, but machine/OS dependent
@end itemize

Many of the properties of @code{MyISAM} tables are also true for @code{ISAM}
tables. However, there are also many differences. The following list
describes some of the ways that @code{ISAM} is distinct from @code{MyISAM}:

@itemize @bullet

@item
Not binary portable across OS/platforms.

@item
Can't handle tables larger than 4GB.

@item
Only supports prefix compression on strings.

@item
Smaller (more restrictive) key limits.

@item
Dynamic tables become more fragmented.

@item
Doesn't support @code{MERGE} tables.

@item
Tables are checked and repaired with @command{isamchk} rather than with
@command{myisamchk}.

@item
Tables are compressed with @command{pack_isam} rather than with @command{myisampack}.

@item
Cannot be used with the @code{BACKUP TABLE} or  @code{RESTORE TABLE}
backup-related statements.

@item
Cannot be used with the @code{CHECK TABLE}, @code{REPAIR TABLE}, @code{OPTIMIZE
TABLE}, or @code{ANALYZE TABLE} table-maintenance statements.

@item
No support for full-text searching or spatial data types.

@item
No support for multiple character sets per table.

@item
Indexes cannot be assigned to specific key caches.

@end itemize


@node InnoDB, NDBCluster, Storage engines, Top
@chapter The @code{InnoDB} Storage Engine

@c TODO: A number of node names in this chapter are very generic (e.g.,
@c "Backing up" and could apply in non-InnoDB contexts. Might be best
@c to rename a bunch of them.

@cindex @code{InnoDB} storage engine
@cindex @code{InnoDB} table type
@cindex tables, @code{InnoDB}

@menu
* InnoDB overview::             @code{InnoDB} Overview
* InnoDB contact information::  @code{InnoDB} Contact Information
* InnoDB in MySQL 3.23::        @code{InnoDB} in MySQL 3.23
* InnoDB configuration::        @code{InnoDB} Configuration
* InnoDB start::                @code{InnoDB} Startup Options
* InnoDB init::                 Creating the @code{InnoDB} Tablespace
* Using InnoDB tables::         Creating @code{InnoDB} Tables
* Adding and removing::         Adding and Removing @code{InnoDB} Data and Log Files
* Backing up::                  Backing Up and Recovering an @code{InnoDB} Database
* Moving::                      Moving an @code{InnoDB} Database to Another Machine
* InnoDB transaction model::    @code{InnoDB} Transaction Model and Locking
* InnoDB tuning::               @code{InnoDB} Performance Tuning Tips
* Implementation::              Implementation of Multi-Versioning
* Table and index::             Table and Index Structures
* File space management::       File Space Management and Disk I/O
* InnoDB Error handling::       Error Handling
* InnoDB restrictions::         Restrictions on @code{InnoDB} Tables
* InnoDB troubleshooting::      @code{InnoDB} Troubleshooting
@end menu

@node InnoDB overview, InnoDB contact information, InnoDB, InnoDB
@section @code{InnoDB} Overview

@cindex InnoDB
@cindex transactions, support
@cindex transaction-safe tables
@cindex ACID

@code{InnoDB} provides MySQL with a transaction-safe (@code{ACID} compliant)
storage engine with commit, rollback, and crash recovery capabilities.
@code{InnoDB} does locking on the row level and also provides an Oracle-style
consistent
non-locking read in @code{SELECT} statements. These features increase
multi-user concurrency and performance. There is no need for
lock escalation in @code{InnoDB}
because row-level locks in @code{InnoDB} fit in very little space.
@code{InnoDB} also supports @code{FOREIGN KEY} constraints.
In SQL queries you can freely mix @code{InnoDB} type tables with other
table types of MySQL, even within the same query.

@code{InnoDB} has been designed for maximum performance when processing
large data volumes. Its CPU efficiency is probably not
matched by any other disk-based relational database engine.

Fully integrated with MySQL Server, the @code{InnoDB} storage engine maintains
its own buffer pool for caching data and indexes in main memory.
@code{InnoDB} stores its tables and indexes in a tablespace, which
may consist of several files (or raw disk partitions).
This is different from, for example,
@code{MyISAM} tables where each table is stored using separate files.
@code{InnoDB} tables can be of any size even on operating
systems where file size is limited to 2GB.

@code{InnoDB} is included in binary distributions by default as of MySQL 4.0.
For information about @code{InnoDB} support in MySQL 3.23, see
@ref{InnoDB in MySQL 3.23}. Starting from MySQL 4.1.5, the new
Windows installer makes @code{InnoDB} the MySQL default table type on
Windows.

@code{InnoDB} is used in production at numerous
large database sites requiring high performance.
The famous Internet news site Slashdot.org runs on @code{InnoDB}.
Mytrix, Inc. stores over 1TB of data in @code{InnoDB},
and another site handles an average
load of 800 inserts/updates per second in @code{InnoDB}.

@code{InnoDB} is published under the same GNU GPL License Version 2
(of June 1991) as MySQL. For more information on MySQL licensing, 
see @uref{http://www.mysql.com/company/legal/licensing/}.


@node InnoDB contact information, InnoDB in MySQL 3.23, InnoDB overview, InnoDB
@section @code{InnoDB} Contact Information

Contact information for Innobase Oy, producer of the @code{InnoDB} engine:

@example
Web site: @uref{http://www.innodb.com/}
Email: @email{sales@@innodb.com}
Phone: +358-9-6969 3250 (office)
       +358-40-5617367 (mobile)

Innobase Oy Inc.
World Trade Center Helsinki
Aleksanterinkatu 17
P.O.Box 800
00101 Helsinki
Finland
@end example


@node InnoDB in MySQL 3.23, InnoDB configuration, InnoDB contact information, InnoDB
@section @code{InnoDB} in MySQL 3.23

Beginning with MySQL 4.0, @code{InnoDB} is enabled by default, so
the following information applies only to MySQL 3.23.

@code{InnoDB} tables are included in the MySQL source distribution
starting from 3.23.34a and are activated in the MySQL-Max
binaries of the 3.23 series.
For Windows, the MySQL-Max binaries are included in the
standard distribution.

If you have downloaded a binary version of MySQL that includes support for
@code{InnoDB}, simply follow the instructions of the MySQL manual for
installing a binary version of MySQL. If you already have MySQL 3.23
installed, the simplest way to install MySQL-Max is to replace the
executable @command{mysqld} server with the corresponding executable from the
MySQL-Max distribution.  MySQL and MySQL-Max differ only in the server
executable.
See @ref{Installing binary} and
@ref{mysqld-max, , @command{mysqld-max}}.

To compile the MySQL source code with @code{InnoDB} support,
download MySQL 3.23.34a or newer from
@uref{http://www.mysql.com/}
and configure MySQL with the
@code{--with-innodb} option. 
@xref{Installing source}.

To use @code{InnoDB} tables with MySQL 3.23, you must specify configuration
parameters in the @code{[mysqld]} section of the @file{my.cnf} option file.
On Windows, you can use @file{my.ini} instead. If you do not configure
@code{InnoDB} in the option file, @code{InnoDB} will not start. (From MySQL
4.0 on, @code{InnoDB} uses default parameters if you do not specify any.
However, to get best performance, it is still recommended that
you use
parameters appropriate for your system, as discussed in
@ref{InnoDB configuration,  , @code{InnoDB} configuration}.)

In MySQL 3.23, you must specify at the minimum an @code{innodb_data_file_path}
value to configure the @code{InnoDB} data files. For example, to configure
@code{InnoDB} to use a single 500MB data file, place the
following setting in the @code{[mysqld]} section of your option file:

@example
[mysqld]
innodb_data_file_path=ibdata1:500M
@end example

@code{InnoDB} will create the @file{ibdata1} file in the MySQL data directory
by default. To specify the location explicitly, specify an
@code{innodb_data_home_dir} setting.
@xref{InnoDB configuration,  , @code{InnoDB} configuration}.


@node InnoDB configuration, InnoDB start, InnoDB in MySQL 3.23, InnoDB
@section @code{InnoDB} Configuration

To enable @code{InnoDB} tables in MySQL 3.23, see
@ref{InnoDB in MySQL 3.23}.

From MySQL 4.0 on, the @code{InnoDB} storage engine is enabled
by default. If you don't want to use @code{InnoDB} tables, you can
add the @code{skip-innodb} option to your MySQL option file.

Two important disk-based resources managed by the @code{InnoDB} storage
engine are its tablespace data files and its log files.

If you specify no @code{InnoDB} configuration options, MySQL 4.0 and
above creates an auto-extending 10MB data file named @file{ibdata1} and
two 5MB log files named @file{ib_logfile0} and @file{ib_logfile1} in the MySQL data directory.
(In MySQL 4.0.0 and 4.0.1, the data file is 64MB and not auto-extending.)
In MySQL 3.23, @code{InnoDB} will not start if you provide no configuration
options.

@strong{Note}: To get good performance, you should explicitly provide
@code{InnoDB} parameters as discussed in the following examples. Naturally,
you should edit the settings to suit your hardware and requirements.

To set up the @code{InnoDB} tablespace files, use the
@code{innodb_data_file_path} option in the @code{[mysqld]} section of the
@file{my.cnf} option file.  On Windows, you can use @file{my.ini} instead.
The value of @code{innodb_data_file_path} should be a list of one or more
data file specifications.  If you name more than one data file, separate them
by semicolon (@samp{;}) characters:

@example
innodb_data_file_path=@var{datafile_spec1}[;@var{datafile_spec2}]...
@end example

For example, a setting that explicitly creates a tablespace having the
same characteristics as the MySQL 4.0 default is as follows:

@example
[mysqld]
innodb_data_file_path=ibdata1:10M:autoextend
@end example

This setting configures a single 10MB data file named @file{ibdata1} that is
auto-extending.  No location for the file is given, so the default is the
MySQL data directory.

Sizes are specified using @code{M} or @code{G} suffix letters to indicate
units of MB or GB.

A tablespace containing a fixed-size 50MB data file named @file{ibdata1} and
a 50MB auto-extending file named @code{ibdata2} in the data directory can be
configured like this:

@example
[mysqld]
innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend
@end example

The full syntax for a data file specification includes the filename, its size,
and several optional attributes:

@example
@var{file_name}:@var{file_size}[:autoextend[:max:@var{max_file_size}]]
@end example

The @code{autoextend} attribute and those following can be used only for the
last data file in the @code{innodb_data_file_path} line.  @code{autoextend}
is available starting from MySQL 3.23.50 and 4.0.2.

If you specify the @code{autoextend} option for the last data file,
@code{InnoDB} extends the data file if it runs out of free space in the
tablespace. The increment is 8MB at a time.

If the disk becomes full, you might want to add another data file on
another disk. Instructions for reconfiguring an existing tablespace are
given in @ref{Adding and removing}.

@code{InnoDB} is not aware of the maximum file size, so
be cautious on filesystems where the maximum file size is 2GB.
To specify a maximum size for an auto-extending data file, use the @code{max}
attribute. The following configuration allows @file{ibdata1} to grow up to a
limit of 500MB:

@example
[mysqld]
innodb_data_file_path=ibdata1:10M:autoextend:max:500M
@end example

@code{InnoDB} creates tablespace files in the MySQL data directory by default.
To specify a location explicitly, use the @code{innodb_data_home_dir} option.
For example, to use two files named @file{ibdata1} and @file{ibdata2} but
create them in the @file{/ibdata} directory, configure @code{InnoDB} like this:

@example
[mysqld]
innodb_data_home_dir = /ibdata
innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend
@end example

@strong{Note}: @code{InnoDB} does not create directories, so make sure that
the @file{/ibdata} directory exists before you start the server.  This is
also true of any log file directories that you configure.  Use the Unix or
DOS @code{mkdir} command to create any necessary directories.

@code{InnoDB} forms the directory path for each data file by textually
concatenating the value of @code{innodb_data_home_dir} to the data file name,
adding a slash or backslash between if needed.  If the
@code{innodb_data_home_dir} option is not mentioned in @file{my.cnf} at all,
the default value is the ``dot'' directory @file{./}, which means the MySQL
data directory.

If you specify @code{innodb_data_home_dir} as an empty string, you can
specify absolute paths for the data files listed in the
@code{innodb_data_file_path} value. The following example is equivalent to
the preceding one:

@example
[mysqld]
innodb_data_home_dir =
innodb_data_file_path=/ibdata/ibdata1:50M;/ibdata/ibdata2:50M:autoextend
@end example

@strong{A simple @file{my.cnf} example.}
Suppose that you have a computer
with 128MB RAM and one hard disk. The following example shows
possible configuration parameters in @file{my.cnf} or
@file{my.ini} for @code{InnoDB}. The example assumes the use of
MySQL-Max 3.23.50 or later or MySQL 4.0.2 or later because it uses the
@code{autoextend} attribute.

This example suits most users, both on Unix and Windows,
who do not want to distribute @code{InnoDB} data files and
log files on several disks. It creates an
auto-extending data file @file{ibdata1} and two @code{InnoDB} log files
@file{ib_logfile0} and @file{ib_logfile1} in the
MySQL data directory.  Also, the small archived @code{InnoDB} log file
@file{ib_arch_log_0000000000} that @code{InnoDB} creates automatically ends
up in the data directory.

@example
[mysqld]
# You can write your other MySQL server options here
# ...
# Data files must be able to hold your data and indexes.
# Make sure that you have enough free disk space.
innodb_data_file_path = ibdata1:10M:autoextend
#
# Set buffer pool size to 50-80% of your computer's memory
set-variable = innodb_buffer_pool_size=70M
set-variable = innodb_additional_mem_pool_size=10M
#
# Set the log file size to about 25% of the buffer pool size
set-variable = innodb_log_file_size=20M
set-variable = innodb_log_buffer_size=8M
#
innodb_flush_log_at_trx_commit=1
@end example

Make sure that the MySQL server has the proper access rights to create files
in the data directory. More generally, the server must have access rights in
any directory where it needs to create data files or log files.

Note that data files must be less than 2GB in some filesystems.
The combined size of the log files must be less than 4GB. The combined
size of data files must be at least 10MB.

When you create an @code{InnoDB} tablespace for the first time, it is
best that you start the MySQL server from the command prompt.
@code{InnoDB} will then print the information about the database
creation to the screen, so you can see what is happening.
For example, on Windows, if @command{mysqld-max} is located in
@file{C:\mysql\bin}, you can start it like this:

@example
C:\> C:\mysql\bin\mysqld-max --console
@end example

If you do not send server output to the screen, check the server's error log
to see what @code{InnoDB} prints during the startup process.

See @ref{InnoDB init,  , @code{InnoDB} init} for an example of what the
information displayed by @code{InnoDB} should look like.

@strong{Where to specify options on Windows?}
The rules for option files on Windows are as follows:

@itemize @bullet

@item
Only one of @file{my.cnf} or @file{my.ini} should be created.

@item
The @file{my.cnf} file should be placed in the root
directory of the @file{C:} drive.

@item
The @file{my.ini} file should be placed in the @code{WINDIR} directory; for
example, @file{C:\WINDOWS} or @file{C:\WINNT}. You can use the @code{SET}
command at the command prompt in a console window to print the value of
@code{WINDIR}:

@example
C:\> SET WINDIR
windir=C:\WINNT
@end example

@item
If your PC uses a boot loader where the @file{C:} drive
is not the boot drive, your only option is to use the @file{my.ini} file.

@end itemize

@strong{Where to specify options on Unix?}
On Unix, @command{mysqld} reads options from the following files, if they exist,
in the following order: 

@c Note: Do not remove blank lines following the @item lines

@itemize @bullet

@item @file{/etc/my.cnf}

Global options.  

@item @file{@var{DATADIR}/my.cnf}

Server-specific options.  

@item @file{defaults-extra-file}

The file specified with the @code{--defaults-extra-file} option.

@item @file{~/.my.cnf}

User-specific options.

@end itemize

@var{DATADIR} represents the MySQL data directory that was
specified as a @command{configure} option when @command{mysqld}
was compiled
(typically @file{/usr/local/mysql/data} for a binary installation or @file{/usr/local/var} for a source installation).

If you want to make sure that @command{mysqld} reads options only from a
specific file, you can use the @code{--defaults-option} as the first option
on the command line when starting the server:

@example
mysqld --defaults-file=your_path_to_my_cnf
@end example

@strong{An advanced @file{my.cnf} example.}
Suppose that you have a Linux computer
with 2GB RAM and three 60GB hard disks
(at directory paths @file{/}, @file{/dr2} and
@file{/dr3}). The following example shows possible
configuration parameters in @file{my.cnf} for @code{InnoDB}. 

@example
[mysqld]
# You can write your other MySQL server options here
# ...
innodb_data_home_dir =
#
# Data files must be able to hold your data and indexes
innodb_data_file_path = /ibdata/ibdata1:2000M;/dr2/ibdata/ibdata2:2000M:autoextend
#
# Set buffer pool size to 50-80% of your computer's memory,
# but make sure on Linux x86 total memory usage is < 2GB
set-variable = innodb_buffer_pool_size=1G
set-variable = innodb_additional_mem_pool_size=20M
innodb_log_group_home_dir = /dr3/iblogs
#
# innodb_log_arch_dir must be the same as innodb_log_group_home_dir
# (starting from 4.0.6, you can omit it)
innodb_log_arch_dir = /dr3/iblogs
set-variable = innodb_log_files_in_group=2
#
# Set the log file size to about 25% of the buffer pool size
set-variable = innodb_log_file_size=250M
set-variable = innodb_log_buffer_size=8M
#
innodb_flush_log_at_trx_commit=1
set-variable = innodb_lock_wait_timeout=50
#
# Uncomment the next lines if you want to use them
#innodb_flush_method=fdatasync
#set-variable = innodb_thread_concurrency=5
@end example

Note that the example places the two data files on different disks.
@code{InnoDB} will fill the tablespace beginning with the first data file.
In some cases, it will
improve the performance of the database if all data is not placed
on the same physical disk. Putting log files on a different disk from
data is very often beneficial for performance.
You can also use raw disk partitions (raw devices)
as @code{InnoDB} data files, which may speed up I/O. @xref{InnoDB Raw Devices}.

@strong{Warning:} On 32-bit GNU/Linux x86, you must be careful not to set
memory usage too high.  @code{glibc} may allow the process heap to grow over
thread stacks, which will crash your server. It is a risk if the value of
the following expression is close to or exceeds 2GB:

@example
innodb_buffer_pool_size
+ key_buffer_size
+ max_connections*(sort_buffer_size+read_buffer_size+binlog_cache_size)
+ max_connections*2MB
@end example

Each thread will use a stack (often 2MB, but only 256KB in MySQL AB binaries)
and in the worst case also uses @code{sort_buffer_size + read_buffer_size}
additional memory.

Starting from MySQL 4.1, by compiling MySQL yourself,
you can use up to 64GB of physical memory in 32-bit
Windows.  See the description for @code{innodb_buffer_pool_awe_mem_mb} in
@ref{InnoDB start,  , @code{InnoDB} start}.

@strong{How to tune other @command{mysqld} server parameters?}
The following values are typical and suit most users:

@example
[mysqld]
skip-external-locking
set-variable = max_connections=200
set-variable = read_buffer_size=1M
set-variable = sort_buffer_size=1M
#
# Set key_buffer to 5 - 50% of your RAM depending on how much
# you use MyISAM tables, but keep key_buffer_size + InnoDB
# buffer pool size < 80% of your RAM
set-variable = key_buffer_size=...
@end example


@node InnoDB start, InnoDB init, InnoDB configuration, InnoDB
@section @code{InnoDB} Startup Options

@c TODO: Have separate lists for options and variables?

This section describes the @code{InnoDB}-related server options.  In MySQL
4.0 and up, all of them can be specified in @code{--@var{opt_name}=@var{value}} form on
the command line or in option files.  Before MySQL 4.0, numeric options
should be specified using @code{--set-variable=@var{opt_name}=@var{value}} or @code{-O
@var{opt_name}=@var{value}} syntax.

@c TODO: these should be listed using --opt_name=type_of_value syntax

@table @code

@item innodb_additional_mem_pool_size
The size of a memory pool @code{InnoDB} uses to store data dictionary
information and other internal data structures.  The more tables you have in
your application, the more memory you will need to allocate here. If
@code{InnoDB} runs out of memory in this pool, it will start to allocate
memory from the operating system, and write warning messages to the MySQL
error log. The default value is 1MB.

@item innodb_autoextend_increment
The increment size (in megabytes) for extending the size of an autoextending
tablespace when it becomes full.  The default value is 8.
This option is available starting from MySQL 4.1.5.

@item innodb_buffer_pool_awe_mem_mb
The size of the buffer pool (in MB), if it is placed in the AWE memory of
32-bit Windows. Available from MySQL 4.1.0 and relevant only in 32-bit Windows. If
your 32-bit Windows operating system supports more than 4GB memory, so-called ``Address
Windowing Extensions,'' you can allocate the @code{InnoDB} buffer pool into the
AWE physical memory using this parameter. The maximum possible value for this
is 64000. If this parameter is specified, @code{innodb_buffer_pool_size}
is the window in the 32-bit address space of @command{mysqld} where @code{InnoDB}
maps that AWE memory. A good value for @code{innodb_buffer_pool_size}
is 500MB.

@item innodb_buffer_pool_size
The size of the memory buffer @code{InnoDB} uses to cache data and indexes
of its tables.  The larger you set this value, the less disk I/O is needed
to access data in tables. On a dedicated database server, you may set this
to up to 80% of the machine physical memory size. However, do not set it
too large because competition for the physical memory might cause paging
in the operating system.

@item innodb_data_file_path
The paths to individual data files and their sizes. The full directory path
to each data file is acquired by concatenating @code{innodb_data_home_dir}
to each path specified here. The file sizes are specified in megabytes
or gigabytes (1024MB) by appending @code{M} or @code{G} to the size
value.  The sum of the sizes of the files must be at least 10MB. On some
operating systems, files must be less than 2GB. If you do not specify
@code{innodb_data_file_path}, the default behavior starting from 4.0 is to
create a single 10MB auto-extending data file named @file{ibdata1}. Starting
from 3.23.44, you can set the file size bigger than 4GB on those operating
systems that support big files. You can also use raw disk partitions as
data files. @xref{InnoDB Raw Devices}.

@item innodb_data_home_dir
The common part of the directory path for all @code{InnoDB} data files. If
you do not set this value, the default is the MySQL data directory. You can
specify this also as an empty string, in which case you can use absolute
file paths in @code{innodb_data_file_path}.

@item innodb_fast_shutdown
By default, @code{InnoDB} does a full purge and an insert buffer merge
before a shutdown. These operations can take minutes, or even hours in extreme
cases.  If you set this parameter to 1, @code{InnoDB}
skips these operations at shutdown. This option is available starting from
MySQL 3.23.44 and 4.0.1. Its default value is 1 starting from 3.23.50.

@item innodb_file_io_threads
The number of file I/O threads in @code{InnoDB}. Normally this should be
left at the default value of 4, but disk I/O on Windows may benefit from
a larger number. On Unix, increasing the number has no effect; @code{InnoDB}
always uses the default value.
This option is available as of MySQL 3.23.37.

@item innodb_file_per_table
@strong{NOTE: CRITICAL BUG in 4.1.2 if you specify innodb_file_per_table in
@file{my.cnf} on Unix.} In crash recovery InnoDB will skip the crash recovery
for all @file{.ibd} files and those tables become CORRUPT! The symptom is
a message
@code{Unable to lock ...ibd with lock 1, error: 9: fcntl: Bad file descriptor}
in the @file{.err} log in crash recovery.
This option causes @code{InnoDB} to create each new table
using its own @file{.ibd} file for storing data and indexes, rather than in
the shared tablespace. @xref{Multiple tablespaces}.
This option is available as of MySQL 4.1.1.

@item innodb_locks_unsafe_for_binlog

This option turns off next-key locking in @code{InnoDB} searches
and index scans. Default value for this option is false. 

Normally @code{InnoDB} uses an algorithm called ``next-key locking.'' 
@code{InnoDB} does the row-level locking in such a way that when it 
searches or scans an index of a table, it sets shared or exclusive 
locks on the index records it encounters. Thus the row-level locks 
are actually index record locks. The locks @code{InnoDB} sets on index 
records also affect the ``gap'' before that index record. 
If a user has a shared or exclusive lock on record R in an index, 
another user cannot insert a new index record immediately before 
R in the index order. This option causes @code{InnoDB} not to 
use next-key locking in searches or index scans. Next-key locking is 
still used to ensure foreign key constraints and duplicate key checking.
Note that using this option may cause phantom problems: Suppose that you 
want to read and lock all children from the @code{child} table with an 
identifier value larger than 100, with the intent of updating 
some column in the selected rows later:

@example
SELECT * FROM child WHERE id > 100 FOR UPDATE;
@end example

Suppose that there is an index on the @code{id} column. The query will scan 
that index starting from the first record where id is bigger than 100. 
Now, if the locks set on the index records do not lock out inserts 
made in the gaps, a new row will meanwhile be inserted to the table. 
If you now execute the same @code{SELECT} within the same transaction, 
you will see a new row in the result set returned by the query. 
This also means, that if new items are added to the database, 
InnoDB does not guarantee serializability instead conflict
serializability is still guaranteed. Therefore, if this option is
used InnoDB guarantees at most isolation level @code{READ COMMITTED}. 
This option is available as of MySQL 4.1.4. 

Starting from MySQL 5.0.2 this option is even more unsafe. InnoDB in
an @code{UPDATE} or a @code{DELETE} only locks rows that it updates or
deletes. This greatly reduces the probability of deadlocks but they
can happen. Note that this option still does not allow
e.g. @code{UPDATE} to overtake other @code{UPDATE} even the case 
when both updates different rows. Consider following example:

@example
CREATE TABLE A(A INT NOT NULL, B INT);
INSERT INTO A VALUES (1,2),(2,3),(3,2),(4,3),(5,2);
COMMIT;
@end example

Now if one connection executes a query:

@example
SET AUTOCOMMIT = 0;
UPDATE A SET B = 5 WHERE B = 3;
@end example

and the other connection executes after the first one a query:

@example
SET AUTOCOMMIT = 0;
UPDATE A SET B = 4 WHERE B = 2;
@end example

Then query two has to wait for a commit or rollback of query one, because
query one has an exclusive lock to a row (2,3), and query two while
scanning rows also tries to take an exclusive lock to
the row (2,3) which it cannot have. This is because query two first
takes an exclusive lock to a row and then checks does this row
belong to the result set and if not then releases the unnecessary
lock when option @code{innodb_locks_unsafe_for_binlog} is used.

Therefore, query one is executed as follows:

@example
x-lock(1,2)
unlock(1,2)
x-lock(2,3)
update(2,3) to (2,5)
x-lock(3,2)
unlock(3,2)
x-lock(4,3)
update(4,3) to (4,5)
x-lock(5,2)
unlock(5,2)
@end example

and then query two is executed as follows:

@example
x-lock(1,2)
update(1,2) to (1,4)
x-lock(2,3) - wait for query one to commit or rollback
@end example

@item innodb_flush_log_at_trx_commit
Normally you set this to 1, meaning that at a transaction commit, the log
is flushed to disk, and the modifications made by the transaction become
permanent and survive a database crash. If you are willing to compromise
this safety, and you are running small transactions, you may set this to
0 or 2 to reduce disk I/O to the logs. A value of 0 means that the log is
only written to the log file and the log file flushed to disk approximately
once per second. A value of 2 means the log is written to the log file at
each commit, but the log file is only flushed to disk approximately once
per second.  The default value is 1 (prior to MySQL 4.0.13, the default is 0).

@item innodb_flush_method
This option is relevant only on Unix systems. If set to @code{fdatasync},
@code{InnoDB} uses @code{fsync()} to flush both the data and log
files. If set to @code{O_DSYNC}, @code{InnoDB} uses @code{O_SYNC}
to open and flush the log files, but uses @code{fsync()} to flush the
data files. If @code{O_DIRECT} is specified (available on some GNU/Linux
versions  starting from MySQL 4.0.14), @code{InnoDB} uses @code{O_DIRECT}
to open the data files, and uses @code{fsync()} to flush both the data
and log files. Note that @code{InnoDB} does not use @code{fdatasync} or
@code{O_DSYNC} by default because there have been problems with them on
many Unix flavors.  This option is available as of MySQL 3.23.40.

@item innodb_force_recovery
Warning: This option should be defined only in an emergency situation when
you want to dump your tables from a corrupt database! Possible values are
from 1 to 6. The meanings of these values are described in @ref{Forcing
recovery}. As a safety measure, @code{InnoDB} prevents a user from modifying
data when this option is greater than 0. This option is available starting
from MySQL 3.23.44.

@item innodb_lock_wait_timeout
The timeout in seconds an @code{InnoDB} transaction may wait for a lock
before being rolled back.  @code{InnoDB} automatically detects transaction
deadlocks in its own lock table and rolls back the transaction. Beginning
with MySQL 4.0.20 and 4.1.2, InnoDB notices locks set using the @code{LOCK
TABLES} statement. Before that, if you
use the @code{LOCK TABLES} statement, or other transaction-safe storage
engines than @code{InnoDB} in the same transaction, a deadlock may arise
that @code{InnoDB} cannot notice. In cases like this, the timeout is useful
to resolve the situation. The default is 50 seconds.

@item innodb_log_arch_dir
The directory where fully written log files would be archived if we used log
archiving.  The value of this parameter should currently be set the same as
@code{innodb_log_group_home_dir}. Starting from MySQL 4.0.6, you may omit
this option.

@item innodb_log_archive
This value should currently be set to 0.  Because recovery from a backup
is done by MySQL using its own log files, there is currently no need to
archive @code{InnoDB} log files. The default for this option is 0.

@item innodb_log_buffer_size
The size of the buffer that @code{InnoDB} uses to write to the log files
on disk.  Sensible values range from 1MB to 8MB.  The default is 1MB. A large
log buffer allows large transactions to run without a need to write the log
to disk before the transactions commit. Thus, if you have big transactions,
making the log buffer larger will save disk I/O.

@item innodb_log_file_size
The size of each log file in a log group. The combined size of
log files must be less than 4GB on 32-bit computers. The default is 5MB.
Sensible values range from 1MB to 1/@var{N}-th of the size of the buffer pool,
below, where @var{N} is the number of log files in the group. The larger
the value, the less checkpoint flush activity is needed in the buffer
pool, saving disk I/O. But larger log files also mean that recovery will
be slower in case of a crash.

@item innodb_log_files_in_group
The number of log files in the log group. @code{InnoDB} writes to the
files in a circular fashion. The default is 2 (recommended).

@item innodb_log_group_home_dir
The directory path to the @code{InnoDB} log files.  It must have the same
value as @code{innodb_log_arch_dir}.  If you do not specify any @code{InnoDB}
log parameters, the default is to create two 5MB files names @file{ib_logfile0}
and @file{ib_logfile1} in the MySQL data directory.

@item innodb_max_dirty_pages_pct
This is an integer in the range from 0 to 100. The default is 90. The main
thread in @code{InnoDB} tries to flush pages from the buffer pool so that
at most this many percent of pages may not yet flushed been flushed at
any particular time. Available starting from 4.0.13 and 4.1.1. If you have the
@code{SUPER} privilege, this percentage can be changed while the server is
running:

@example
SET GLOBAL innodb_max_dirty_pages_pct = @var{value};
@end example

@item innodb_mirrored_log_groups
The number of identical copies of log groups we keep for the
database. Currently this should be set to 1.

@item innodb_open_files
This option is relevant only if you use multiple tablespaces in
@code{InnoDB}. It specifies the maximum number of @file{.ibd} files that
@code{InnoDB} can keep open at one time. The minimum value is 10. The
default is 300.  This option is available as of MySQL 4.1.1.

The file descriptors used for @file{.ibd} files are for @code{InnoDB} only.
They are independent of those specified by the @code{--open-files-limit}
server option, and do not affect the operation of the table cache.

@item innodb_thread_concurrency
@code{InnoDB} tries to keep the number of operating system threads
concurrently inside @code{InnoDB} less than or equal to the limit given
by this parameter. The default value is 8. If you have low performance
and @code{SHOW INNODB STATUS} reveals many threads waiting for semaphores,
you may have thread thrashing and should try setting this parameter lower
or higher.  If you have a computer with many processors and disks, you
can try setting the value higher to better utilize the resources of you
computer. A recommended value is the sum of the number of processors and
disks your system has.  A value of 500 or greater disables the concurrency
checking.  This option is available starting from MySQL 3.23.44 and 4.0.1.

@item innodb_table_locks
Starting from MySQL 4.0.20, and 4.1.2,
@code{InnoDB} honors @code{LOCK TABLES};
MySQL will not return from @code{LOCK TABLE .. WRITE} until all other
threads have released all their locks to the table.  In MySQL 4.0.19
and before, InnoDB ignored table locks, which allowed one to more easily
simulate transactions with a combination of MyISAM and InnoDB tables.
The default value is 1, which means that
@code{LOCK TABLES} causes also InnoDB internally to take a table lock.
In applications using @code{AUTOCOMMIT=1}, InnoDB's
internal table locks can cause deadlocks. You can set
@code{innodb_table_locks=0} in @file{my.cnf} to remove that problem.

@item innodb_status_file
This option causes @code{InnoDB} to create a file
@file{@var{<datadir>}/innodb_status.@var{<pid>}} for periodical
@code{SHOW INNODB STATUS} output.  This option is available as of MySQL 4.0.21.

@end table


@node InnoDB init, Using InnoDB tables, InnoDB start, InnoDB
@section Creating the @code{InnoDB} Tablespace

Suppose that you have installed MySQL and have edited your option file so
that it contains the necessary @code{InnoDB} configuration parameters.
Before starting MySQL, you should verify that the directories you have
specified for @code{InnoDB} data files and log files exist and that the
MySQL server has access rights to those directories. @code{InnoDB} cannot
create directories, only files. Check also that you have enough disk space
for the data and log files.

It is best to run the MySQL server @command{mysqld} from the command prompt
when you create an @code{InnoDB} database, not from the @command{mysqld_safe}
wrapper or as a Windows service. When you run from a command prompt you
see what @command{mysqld} prints and what is happening. On Unix, just invoke
@command{mysqld}. On Windows, use the @code{--console} option.

When you start the MySQL server after initially configuring @code{InnoDB} in
your option file, @code{InnoDB} creates your
data files and log files. @code{InnoDB} will print something like the following:

@example
InnoDB: The first specified datafile /home/heikki/data/ibdata1
did not exist:
InnoDB: a new database to be created!
InnoDB: Setting file /home/heikki/data/ibdata1 size to 134217728
InnoDB: Database physically writes the file full: wait...
InnoDB: datafile /home/heikki/data/ibdata2 did not exist:
new to be created
InnoDB: Setting file /home/heikki/data/ibdata2 size to 262144000
InnoDB: Database physically writes the file full: wait...
InnoDB: Log file /home/heikki/data/logs/ib_logfile0 did not exist:
new to be created
InnoDB: Setting log file /home/heikki/data/logs/ib_logfile0 size
to 5242880
InnoDB: Log file /home/heikki/data/logs/ib_logfile1 did not exist:
new to be created
InnoDB: Setting log file /home/heikki/data/logs/ib_logfile1 size
to 5242880
InnoDB: Doublewrite buffer not found: creating new
InnoDB: Doublewrite buffer created
InnoDB: Creating foreign key constraint system tables
InnoDB: Foreign key constraint system tables created
InnoDB: Started
mysqld: ready for connections
@end example

A new @code{InnoDB} database has now been created. You can connect to the MySQL
server with the usual MySQL client programs like @command{mysql}.
When you shut down the MySQL server with @command{mysqladmin shutdown},
the output will be like the following:

@example
010321 18:33:34  mysqld: Normal shutdown
010321 18:33:34  mysqld: Shutdown Complete
InnoDB: Starting shutdown...
InnoDB: Shutdown completed
@end example

You can now look at the data file and log directories and you
will see the files created. The log directory will also contain
a small file named @file{ib_arch_log_0000000000}. That file
resulted from the database creation, after which @code{InnoDB} switched off
log archiving.
When MySQL is started again, the data files and log files will already have
been created, so the output will be much briefer:

@example
InnoDB: Started
mysqld: ready for connections
@end example

Starting from MySQL 4.1.1, you can add the option @code{innodb_file_per_table}
to @file{my.cnf}, and make InnoDB to store each table into its own
@file{.ibd} file in a database directory of MySQL.
@xref{Multiple tablespaces}.

@menu
* Error creating InnoDB::       Dealing with @code{InnoDB} Initialization Problems
@end menu


@node Error creating InnoDB,  , InnoDB init, InnoDB init
@subsection Dealing with @code{InnoDB} Initialization Problems

If @code{InnoDB} prints an operating system error in a file operation,
usually the problem is one of the following:

@itemize @bullet
@item You did not create the @code{InnoDB} data file or log directories.
@item @command{mysqld} does not have access rights to create files in those
directories.
@item @command{mysqld} does not read the proper @file{my.cnf} or @file{my.ini}
option file, and consequently does not see the options you specified.
@item The disk is full or a disk quota is exceeded.
@item You have created a subdirectory whose name is equal to a data file
you specified.
@item There is a syntax error in @code{innodb_data_home_dir}
or @code{innodb_data_file_path}.
@end itemize

If something goes wrong when @code{InnoDB} attempts to initialize
its tablespace or its log files, you should delete all files created
by @code{InnoDB}. This means all data files, all log files, and the small
archived log file. In case you already created some @code{InnoDB} tables,
delete the corresponding @file{.frm} files for these tables (and any
@file{.ibd} files if you are using multiple tablespaces) from the
MySQL database directories as well. Then you can try the @code{InnoDB}
database creation again.  It is best to start the MySQL server from a
command prompt so that you see what is happening.


@node Using InnoDB tables, Adding and removing, InnoDB init, InnoDB
@section Creating @code{InnoDB} Tables

Suppose that you have started the MySQL client with the command @code{mysql test}.
To create an @code{InnoDB} table, you must specify and @code{ENGINE = InnoDB}
or @code{TYPE = InnoDB} option in the table creation SQL statement:

@example
CREATE TABLE customers (a INT, b CHAR (20), INDEX (a)) ENGINE=InnoDB;
CREATE TABLE customers (a INT, b CHAR (20), INDEX (a)) TYPE=InnoDB;
@end example

The SQL statement creates a table and an index on column @code{a} in the
@code{InnoDB} tablespace that consists of the data files you specified in
@file{my.cnf}. In addition, MySQL creates a file @file{customers.frm}
in the @file{test} directory under the MySQL database directory.
Internally, @code{InnoDB} adds to its own data dictionary an entry for
table @code{'test/customers'}. This means you can create a table of the same
name @code{customers} in some other database, and the table names will
not collide inside @code{InnoDB}.

You can query the amount of free space in the @code{InnoDB} tablespace
by issuing a @code{SHOW TABLE STATUS} statement for any @code{InnoDB} table.
The amount of free
space in the tablespace appears in the @code{Comment} section in the
output of @code{SHOW TABLE STATUS}. An example:

@example
SHOW TABLE STATUS FROM test LIKE 'customers'
@end example

Note that the statistics @code{SHOW} gives about @code{InnoDB} tables
are only approximate. They are used in SQL optimization.  Table and index
reserved sizes in bytes are accurate, though.


@menu
* InnoDB transactions with different APIs::  How to Use Transactions in @code{InnoDB} with Different APIs
* Converting tables to InnoDB::  Converting @code{MyISAM} Tables to @code{InnoDB}
* InnoDB auto-increment column::  How an @code{AUTO_INCREMENT} Column Works in @code{InnoDB}
* InnoDB foreign key constraints::  @code{FOREIGN KEY} Constraints
* InnoDB and MySQL Replication::  @code{InnoDB} and MySQL Replication
* Multiple tablespaces::        Using Per-Table Tablespaces
@end menu


@node InnoDB transactions with different APIs, Converting tables to InnoDB, Using InnoDB tables, Using InnoDB tables
@subsection How to Use Transactions in @code{InnoDB} with Different APIs

By default, each client that connects to the MySQL server begins with autocommit
mode enabled, which automatically commits every SQL statement you run.
To use multiple-statement transactions, you can switch autocommit off
with the SQL statement @code{SET AUTOCOMMIT = 0} and use @code{COMMIT}
and @code{ROLLBACK} to commit or roll back your transaction.
If you want to leave autocommit on, you can enclose your transactions
between @code{START TRANSACTION} and @code{COMMIT} or @code{ROLLBACK}.
Before MySQL 4.0.11, you have to use the keyword @code{BEGIN}
instead of @code{START TRANSACTION}. The following example shows two
transactions. The first is committed and the second is rolled back.

@example
shell> mysql test
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5 to server version: 3.23.50-log
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> CREATE TABLE CUSTOMER (A INT, B CHAR (20), INDEX (A))
    -> TYPE=InnoDB;
Query OK, 0 rows affected (0.00 sec)
mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO CUSTOMER VALUES (10, 'Heikki');
Query OK, 1 row affected (0.00 sec)
mysql> COMMIT;
Query OK, 0 rows affected (0.00 sec)
mysql> SET AUTOCOMMIT=0;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO CUSTOMER VALUES (15, 'John');
Query OK, 1 row affected (0.00 sec)
mysql> ROLLBACK;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM CUSTOMER;
+------+--------+
| A    | B      |
+------+--------+
|   10 | Heikki |
+------+--------+
1 row in set (0.00 sec)
mysql>
@end example

In APIs like PHP, Perl DBI/DBD, JDBC, ODBC, or the standard C call
interface of MySQL, you can send transaction control statements such as
@code{COMMIT} to the MySQL server as strings just like any other
SQL statements such as @code{SELECT} or @code{INSERT}.
Some APIs also offer separate special transaction commit and rollback functions
or methods.


@node Converting tables to InnoDB, InnoDB auto-increment column, InnoDB transactions with different APIs, Using InnoDB tables
@subsection Converting @code{MyISAM} Tables to @code{InnoDB}

Important: You should not convert MySQL system tables in the @code{mysql}
database (such as @code{user} or @code{host}) to the @code{InnoDB} type. The
system tables must always be of the @code{MyISAM} type.

If you want all your (non-system) tables to be created as @code{InnoDB}
tables, you can, starting from the MySQL 3.23.43, add the line
@code{default-table-type=innodb} to the @code{[mysqld]} section of
your @file{my.cnf} or @file{my.ini} file.

@code{InnoDB} does not have a special optimization for separate index
creation the way the @code{MyISAM} storage engine does.  Therefore, it does
not pay to export and import the table and create indexes afterward.
The fastest way to alter a table to @code{InnoDB} is to do the inserts
directly to an @code{InnoDB} table. That is, use @code{ALTER TABLE
... TYPE=INNODB}, or create an empty @code{InnoDB} table with identical
definitions and insert the rows with @code{INSERT INTO ... SELECT *
FROM ...}.

If you have @code{UNIQUE} constraints on secondary keys, starting from
MySQL 3.23.52, you can speed up a table import by turning off the uniqueness
checks temporarily during the import session: @code{SET UNIQUE_CHECKS=0;}
For big tables, this saves a lot of disk I/O because @code{InnoDB} can then
use its insert buffer to write secondary index records in a batch.

To get better control over the insertion process, it might be good to insert
big tables in pieces:

@example
INSERT INTO newtable SELECT * FROM oldtable
   WHERE yourkey > something AND yourkey <= somethingelse;
@end example

After all records have been inserted, you can rename the tables.

During the conversion of big tables, you should increase the size of the
@code{InnoDB} buffer pool to reduce disk I/O. Do not use more than 80% of the
physical memory, though. You can also increase the sizes of the @code{InnoDB}
log files and the log files.

Make sure that you do not fill up the tablespace: @code{InnoDB} tables require
a lot more disk space than @code{MyISAM} tables. If an @code{ALTER TABLE}
runs out of space, it will start a rollback, and that can take hours if
it is disk-bound.  For inserts, @code{InnoDB} uses the insert buffer to
merge secondary index records to indexes in batches. That saves a lot of
disk I/O. In rollback, no such mechanism is used, and the rollback can take
30 times longer than the insertion.

In the case of a runaway rollback, if you do not have valuable data in your
database, it may be advisable to kill the database process rather than wait
for millions of disk I/O operations to complete.
For the complete procedure, see @ref{Forcing recovery}.


@node InnoDB auto-increment column, InnoDB foreign key constraints, Converting tables to InnoDB, Using InnoDB tables
@subsection How an @code{AUTO_INCREMENT} Column Works in @code{InnoDB}

If you specify an @code{AUTO_INCREMENT} column for a table, the @code{InnoDB}
table handle in the data dictionary will contain a special counter called
the auto-increment counter that is used in assigning new values for the
column. The auto-increment counter is stored only in main memory, not
on disk.

@code{InnoDB} uses the following algorithm to initialize the auto-increment
counter for a table @code{T} that contains an @code{AUTO_INCREMENT} column
named @code{ai_col}: After a server startup, when a user first does an insert
to a table @code{T}, @code{InnoDB} executes the equivalent of this statement:

@example
SELECT MAX(ai_col) FROM T FOR UPDATE;
@end example

The value retrieved by the statement is incremented by one and assigned to
the column and the auto-increment counter of the table. If the table is
empty, the value @code{1} is assigned. If the auto-increment counter is not
initialized and the user invokes a @code{SHOW TABLE STATUS} statement that
displays output for the table @code{T}, the counter is initialized (but not
incremented) and stored for use by later inserts.
Note that in this initialization
we do a normal exclusive-locking read on the table and the lock lasts to the end
of the transaction.

@code{InnoDB} follows the same procedure for initializing the auto-increment
counter for a freshly created table.

Note that if the user specifies @code{NULL} or @code{0} for the
@code{AUTO_INCREMENT} column in an @code{INSERT}, @code{InnoDB} treats the
row as if the value had not been specified and generates a new value for it.

After the auto-increment counter has been initialized, if a user inserts
a row that explicitly specifies the column value, and the value is
bigger than the current counter value, the counter is set to the specified
column value. If the user does not explicitly specify a value, @code{InnoDB}
increments the counter by one and assigns the new value to the column.

When accessing the auto-increment counter, @code{InnoDB} uses a special table
level @code{AUTO-INC} lock that it keeps to the end of the current SQL
statement, not to the end of the transaction.
The special lock release strategy was introduced to improve concurrency
for inserts into a table containing an @code{AUTO_INCREMENT} column. Two
transactions cannot have the @code{AUTO-INC} lock on the same table
simultaneously.

Note that you may see gaps in the sequence of values assigned to the
@code{AUTO_INCREMENT} column if you roll back transactions that have gotten
numbers from the counter.

The behavior of the auto-increment mechanism is not defined if a user
assigns a negative value to the column or if the value becomes bigger
than the maximum integer that can be stored in the specified integer type.


@node InnoDB foreign key constraints, InnoDB and MySQL Replication, InnoDB auto-increment column, Using InnoDB tables
@subsection @code{FOREIGN KEY} Constraints

Starting from MySQL 3.23.44, @code{InnoDB} features foreign key constraints.

@c description_for_help_topic CONSTRAINT  FOREIGN KEY REFERENCES NO ACTION ON DELETE CASCADE SET NULL RESTRICT UPDATE
The syntax of a foreign key constraint definition in @code{InnoDB} looks like
this:

@example
[CONSTRAINT @var{symbol}] FOREIGN KEY [@var{id}] (@var{index_col_name}, ...)
    REFERENCES @var{tbl_name} (@var{index_col_name}, ...)
    [ON DELETE @{RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT@}]
    [ON UPDATE @{RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT@}]
@end example
@c end_description_for_help_topic

Both tables must be @code{InnoDB} type.  In the referencing table, there must
be an index where the foreign key columns are listed as the @emph{first}
columns in the same order. In the referenced table, there must be an index
where the referenced columns are listed as the @emph{first} columns in
the same order. Index prefixes on foreign key columns are not supported.

@code{InnoDB} needs indexes on foreign keys and referenced keys so that
foreign key checks can be fast and not require a table scan.  Starting with
MySQL 4.1.2, these indexes are created automatically.  In older versions,
the indexes must be created explicitly or the creation of foreign key
constraints will fail.

Corresponding columns in the foreign key and the referenced key must
have similar internal data types inside @code{InnoDB} so that they can be
compared without a type conversion.
The @strong{size and the signedness of integer types has to be the same}.
The length of string types need not be the same.
If you specify a @code{SET NULL} action, make sure that you
have @strong{not declared the columns in the child table} as
@code{NOT NULL}.

If MySQL reports an error number 1005 from a @code{CREATE TABLE} statement,
and the error message string refers to errno 150, this means that the table
creation failed because a foreign key constraint was not correctly formed.
Similarly, if an @code{ALTER TABLE} fails and it refers to errno 150,
that means a foreign key definition would be incorrectly formed for the
altered table.  Starting from MySQL 4.0.13, you can use @code{SHOW INNODB
STATUS} to display a detailed explanation of the latest @code{InnoDB}
foreign key error in the server.

Starting from MySQL 3.23.50, @code{InnoDB} does not check foreign key
constraints on those foreign key or referenced key values
that contain a @code{NULL} column.

@strong{A deviation from SQL standards:} If in the parent table
there are several rows that have the same referenced key value,
then @code{InnoDB} acts in foreign key checks as if the other parent
rows with the same key value do not exist. For example,
if you have defined a @code{RESTRICT} type constraint, and there
is a child row with several parent rows, @code{InnoDB} does not allow
the deletion of any of those parent rows. 

Starting from MySQL 3.23.50, you can also associate the
@code{ON DELETE CASCADE} or @code{ON DELETE SET NULL} clause with
the foreign key constraint. Corresponding @code{ON UPDATE} options
are available starting from 4.0.8. If @code{ON DELETE CASCADE} is
specified, and a row in the parent table is deleted, @code{InnoDB}
automatically deletes also all those rows in the child table
whose foreign key values are equal to the referenced key value in
the parent row. If @code{ON DELETE SET NULL} is specified, the
child rows are automatically updated so that the columns in the
foreign key are set to the SQL @code{NULL} value.
@code{SET DEFAULT} is parsed but ignored.

@code{InnoDB} performs cascading operations through a depth-first algorithm,
based on records in the indexes corresponding to the foreign key
constraints.

@strong{A deviation from SQL standards:} If
@code{ON UPDATE CASCADE} or @code{ON UPDATE SET NULL} recurses to
update the @emph{same table} it has already updated during the cascade,
it acts like @code{RESTRICT}. This means that you cannot use
self-referential @code{ON UPDATE CASCADE} or
@code{ON UPDATE SET NULL} operations.
This is to prevent infinite loops resulting from cascaded updates.
A self-referential @code{ON DELETE SET NULL}, on the other hand,
is possible from 4.0.13.
A self-referential @code{ON DELETE CASCADE} has been possible since @code{ON
DELETE} was implemented.  Since 4.0.21, cascading operations may not be nested
more than 15 levels.

@strong{A deviation from SQL standards:}
Like MySQL in general, in an SQL statement that inserts, deletes, or
updates many rows, InnoDB checks @code{UNIQUE} and @code{FOREIGN KEY}
constraints row-by-row. According to the SQL standard, the default behavior
should be that constraints are only checked after the WHOLE SQL statement
has been processed.

A simple example that relates @code{parent} and @code{child} tables through a
single-column foreign key:

@example
CREATE TABLE parent(id INT NOT NULL,
                    PRIMARY KEY (id)
) TYPE=INNODB;
CREATE TABLE child(id INT, parent_id INT,
                   INDEX par_ind (parent_id),
                   FOREIGN KEY (parent_id) REFERENCES parent(id)
                     ON DELETE CASCADE
) TYPE=INNODB;
@end example

A more complex example in which a @code{product_order} table has foreign keys
for two other tables. One foreign key references a two-column index in the
@code{product} table. The other references a single-column index in the
@code{customer} table:

@c example_for_help_topic CONSTRAINT
@example
CREATE TABLE product (category INT NOT NULL, id INT NOT NULL,
                      price DECIMAL,
                      PRIMARY KEY(category, id)) TYPE=INNODB;
CREATE TABLE customer (id INT NOT NULL,
                      PRIMARY KEY (id)) TYPE=INNODB;
CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT,
                      product_category INT NOT NULL,
                      product_id INT NOT NULL,
                      customer_id INT NOT NULL,
                      PRIMARY KEY(no),
                      INDEX (product_category, product_id),
                      FOREIGN KEY (product_category, product_id)
                        REFERENCES product(category, id)
                        ON UPDATE CASCADE ON DELETE RESTRICT,
                      INDEX (customer_id),
                      FOREIGN KEY (customer_id)
                        REFERENCES customer(id)) TYPE=INNODB;
@end example

Starting from MySQL 3.23.50, @code{InnoDB} allows you to add a new
foreign key constraint to a table by using @code{ALTER TABLE}:

@example
ALTER TABLE yourtablename
    ADD [CONSTRAINT @var{symbol}] FOREIGN KEY [@var{id}] (@var{index_col_name}, ...)
    REFERENCES @var{tbl_name} (@var{index_col_name}, ...)
    [ON DELETE @{RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT@}]
    [ON UPDATE @{RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT@}]
@end example

@strong{Remember to create the required indexes first}.
You can also add a self-referential foreign key constraint to a
table using @code{ALTER TABLE}.

@findex DROP FOREIGN KEY
@cindex deleting, foreign key
@cindex foreign key, deleting
Starting from MySQL 4.0.13, @code{InnoDB} supports the use of @code{ALTER
TABLE} to drop foreign keys:

@example
ALTER TABLE @var{yourtablename} DROP FOREIGN KEY @var{fk_symbol};
@end example

If the @code{FOREIGN KEY} clause included a @code{CONSTRAINT} name when you
created the foreign key, you can refer to that name to drop the foreign key.
(A constraint name can be given as of MySQL 4.0.18.)  Otherwise, the
@code{fk_symbol} value is internally generated by @code{InnoDB} when the
foreign key is created. To find out the symbol when you want to drop a foreign
key, use the @code{SHOW CREATE TABLE} statement.
An example:

@example
mysql> SHOW CREATE TABLE ibtest11c\G
*************************** 1. row ***************************
       Table: ibtest11c
Create Table: CREATE TABLE `ibtest11c` (
  `A` int(11) NOT NULL auto_increment,
  `D` int(11) NOT NULL default '0',
  `B` varchar(200) NOT NULL default '',
  `C` varchar(175) default NULL,
  PRIMARY KEY  (`A`,`D`,`B`),
  KEY `B` (`B`,`C`),
  KEY `C` (`C`),
  CONSTRAINT `0_38775` FOREIGN KEY (`A`, `D`)
REFERENCES `ibtest11a` (`A`, `D`)
ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `0_38776` FOREIGN KEY (`B`, `C`)
REFERENCES `ibtest11a` (`B`, `C`)
ON DELETE CASCADE ON UPDATE CASCADE
) TYPE=InnoDB CHARSET=latin1
1 row in set (0.01 sec)

mysql> ALTER TABLE ibtest11c DROP FOREIGN KEY 0_38775;
@end example

Starting from MySQL 3.23.50, the @code{InnoDB} parser allows you to use
backticks around table and column names in a
@code{FOREIGN KEY ... REFERENCES ...} clause.
Starting from MySQL 4.0.5, the @code{InnoDB} parser also takes into account
the @code{lower_case_table_names} system variable setting.

Before MySQL 3.23.50, @code{ALTER TABLE} or @code{CREATE INDEX}
should not be used in connection with tables that have foreign
key constraints or that are referenced in foreign key constraints:
Any @code{ALTER TABLE} removes all foreign key
constraints defined for the table. You should not use
@code{ALTER TABLE} with the referenced table, either. Instead,
use @code{DROP TABLE} and @code{CREATE TABLE} to modify the
schema. When MySQL does an @code{ALTER TABLE} it may internally
use @code{RENAME TABLE}, and that will confuse the
foreign key constraints that refer to the table.
In MySQL, a @code{CREATE INDEX} statement is processed as an
@code{ALTER TABLE}, so the same considerations apply.

Starting from MySQL 3.23.50, @code{InnoDB} returns the foreign key
definitions of a table as part of the output of the @code{SHOW CREATE TABLE}
statement:

@example
SHOW CREATE TABLE @var{tbl_name};
@end example

From this version, @command{mysqldump} also produces correct definitions
of tables to the dump file, and does not forget about the foreign keys.

You can display the foreign key constraints for a table like this:
@example
SHOW TABLE STATUS FROM @var{db_name} LIKE '@var{tbl_name}'
@end example

The foreign key constraints are listed in the @code{Comment} column of
the output.

When performing foreign key checks, @code{InnoDB} sets shared row
level locks on child or parent records it has to look at.
@code{InnoDB} checks foreign key constraints immediately; the check
is not deferred to transaction commit.

To make it easier to reload dump files for tables that have foreign key
relationships, @command{mysqldump} automatically includes a statement in the
dump output to set @code{FOREIGN_KEY_CHECKS} to 0 as of MySQL 4.1.1. This
avoids problems with tables having to be reloaded in a particular order
when the dump is reloaded.  For earlier versions, you can disable the
variable manually within @command{mysql} when loading the dump file like this:

@example
mysql> SET FOREIGN_KEY_CHECKS = 0;
mysql> SOURCE @var{dump_file_name}
mysql> SET FOREIGN_KEY_CHECKS = 1;
@end example

This allows you to import the tables in any order if the dump file contains
tables that are not correctly ordered for foreign keys. It also speeds
up the import operation.  @code{FOREIGN_KEY_CHECKS} is available starting
from MySQL 3.23.52 and 4.0.3.

Setting @code{FOREIGN_KEY_CHECKS} to 0 can also be useful for ignoring
foreign key constraints during @code{LOAD DATA} operations.

@code{InnoDB} does not allow you to drop a table that is
referenced by a @code{FOREIGN KEY} constraint, unless
you do @code{SET FOREIGN_KEY_CHECKS=0}.
When you drop a table, the constraints that
were defined in its create statement are also dropped.

If you re-create a table that was dropped, it must have
a definition that conforms to the foreign key constraints
referencing it. It must have the right column names and types,
and it must have indexes on the referenced keys, as stated earlier.
If these are not satisfied, MySQL returns error number 1005
and refers to errno 150 in the error message string.


@node InnoDB and MySQL Replication, Multiple tablespaces, InnoDB foreign key constraints, Using InnoDB tables
@subsection @code{InnoDB} and MySQL Replication

@c TODO: Add xref to here from replication chapter.

MySQL replication works for @code{InnoDB} tables as it does
for @code{MyISAM} tables. It is also possible to use replication in
a way where the table type on the slave is not the same as the original
table type on the master.  For example, you can replicate modifications to
an @code{InnoDB} table on the master to a @code{MyISAM} table on the slave.

To set up a new slave for a master, you have to make a copy of the
@code{InnoDB} tablespace and the log files, as well as the @file{.frm} files
of the @code{InnoDB} tables, and move the copies to the slave.
For the proper procedure to do this, see @ref{Moving}.

If you can shut down the master or an existing slave, you can take a
cold backup of the @code{InnoDB} tablespace and log files and use that to
set up a slave.
To make a new slave without taking down any server you can also use
the non-free (commercial) @uref{http://www.innodb.com/order.html,@code{InnoDB Hot Backup} tool}.

There are minor limitations in @code{InnoDB} replication:

@itemize @bullet
@item
@code{LOAD TABLE FROM MASTER} does not work for @code{InnoDB} type
tables. There are workarounds: 1) dump the table on the master and import the
dump file into the slave, or 2) use @code{ALTER TABLE @var{tbl_name} TYPE=MyISAM}
on the master before setting up replication with @code{LOAD TABLE @var{tbl_name}
FROM MASTER}, and then use @code{ALTER TABLE} to alter the master table
back to the @code{InnoDB} type afterward.

@c NOTE: do not change SLAVE STOP/START to its current syntax of STOP/START
@c SLAVE in next item.  4.0.6 does not understand STOP/START SLAVE.
@item
Before MySQL 4.0.6, @code{SLAVE STOP} did not
respect the boundary of a multiple-statement transaction.
An incomplete transaction would be rolled back, and the next
@code{SLAVE START} would only execute the remaining part of the half
transaction. That would cause replication to fail.

@c NOTE: do not change SLAVE STOP to its current syntax of STOP
@c SLAVE in next item.  4.0.6 does not understand STOP SLAVE.
@item
Before MySQL 4.0.6, a slave crash in the middle of a
multiple-statement transaction would cause the same problem as
@code{SLAVE STOP}.
@item
Before MySQL 4.0.11, replication of the
@code{SET FOREIGN_KEY_CHECKS=0} statement does not work properly.
@end itemize

Most of these limitations can be eliminated by using more recent server
versions for which the limitations do not apply.

Transactions that fail on the master do not affect replication at all.
MySQL replication is based on the binary log where MySQL writes SQL
statements that modify data. A slave reads the binary log of the master and
executes the same SQL statements. However, statements that occur within a
transaction are not written to the binary log until the transaction commits,
at which point all statements in the transaction are written at once.
If a statement fails, for example, because of a foreign key violation,
or if a transaction is rolled back, no SQL statements are written to the
binary log, and the transaction is not executed on the slave at all.


@node Multiple tablespaces,  , InnoDB and MySQL Replication, Using InnoDB tables
@subsection Using Per-Table Tablespaces

Starting from MySQL 4.1.1, you can store each @code{InnoDB} table and its
indexes into its own file. This feature is called ``multiple tablespaces''
because in effect each table has its own tablespace.

If you need to downgrade to 4.0, you have to take table dumps and
re-create the whole @code{InnoDB} tablespace. If you have not created new
@code{InnoDB} tables under MySQL 4.1.1 or later, and need to downgrade
quickly, you can also do a direct downgrade to the MySQL
4.0.18 or later in the 4.0 series.
Before doing the direct downgrade to 4.0.x, you have to end all client
connections to the @command{mysqld} server that is to be downgraded, and let it
run the purge and insert buffer merge operations to completion, so that
@code{SHOW INNODB STATUS} shows the main thread in the state
@code{waiting for server activity}. Then you can shut down
@command{mysqld} and start 4.0.18 or later in the 4.0 series.

You can enable multiple tablespaces by adding a line to the
@code{[mysqld]} section of @file{my.cnf}:

@example
[mysqld]
innodb_file_per_table
@end example

After restarting the server, @code{InnoDB} will store each newly created
table into its own file @file{@var{tbl_name}.ibd} in the database directory
where the table belongs.  This is similar to what the @code{MyISAM}
storage engine does, but @code{MyISAM} divides the table into a data
file @file{@var{tbl_name}.MYD} and the index file @file{@var{tbl_name}.MYI}.
For @code{InnoDB}, the data and the indexes are stored together in the
@file{.ibd} file.  The @file{@var{tbl_name}.frm} file is still created as usual.

If you remove the @code{innodb_file_per_table} line from @file{my.cnf} and
restart the server, @code{InnoDB} creates tables inside the shared tablespace
files again.

@code{innodb_file_per_table} affects only table creation. If you start the
server with this option, new tables are created using @file{.ibd} files, but you can still access tables that exist in the shared
tablespace. If you remove the option, new tables are created in the shared
tablespace, but you can still access any tables that
were created using multiple tablespaces.

@code{InnoDB} always needs the shared tablespace. The @file{.ibd}
files are not sufficient for @code{InnoDB} to operate. The shared tablespace
consists of the familiar @file{ibdata} files where @code{InnoDB} puts its
internal data dictionary and undo logs.

@strong{You cannot freely move @file{.ibd} files around} between database
directories the way you can with
@code{MyISAM} table files. This is because the table definition is stored
in the @code{InnoDB} shared tablespace, and also because @code{InnoDB}
must preserve the consistency of transaction IDs and log sequence numbers.

Within a given MySQL installation, you can move an @file{.ibd} file and the
associated table from one database to another with the familiar @code{RENAME
TABLE} statement:

@example
RENAME TABLE @var{old_db_name.tbl_name} TO @var{new_db_name.tbl_name};
@end example

@findex DISCARD TABLESPACE
@findex IMPORT TABLESPACE
If you have a ``clean'' backup of an @file{.ibd} file,
you can restore it to the MySQL installation from which it originated as
follows:

@enumerate
@item
Issue this @code{ALTER TABLE} statement:

@example
ALTER TABLE @var{tbl_name} DISCARD TABLESPACE;
@end example

Caution: This deletes the current @file{.ibd} file.

@item
Put the backup @file{.ibd} file back in the proper database directory.

@item
Issue this @code{ALTER TABLE} statement:

@example
ALTER TABLE @var{tbl_name} IMPORT TABLESPACE;
@end example

@end enumerate

In this context, a ``clean'' @file{.ibd} file backup means:

@itemize @bullet
@item
There are no uncommitted modifications by transactions in the @file{.ibd}
file. 
@item
There are no unmerged insert buffer entries in the @file{.ibd} file.
@item
Purge has removed all delete-marked index records from the @file{.ibd} file. 
@item
@command{mysqld} has flushed all modified pages of the @file{.ibd} file from
the buffer pool to the file. 
@end itemize

You can make such a clean backup @file{.ibd} file with the following method:

@enumerate
@item
Stop all activity from the @command{mysqld} server and commit all transactions.
@item 
Wait until @code{SHOW INNODB STATUS} shows that there are no active
transactions in the database, and the main thread status of @code{InnoDB} is
@code{Waiting for server activity}. Then you can make a copy of the
@file{.ibd} file. 
@end enumerate

Another method for making a clean copy of an @file{.ibd} file is to
use the commercial @code{InnoDB Hot Backup} tool:

@enumerate
@item
Use @code{InnoDB Hot Backup} to back up the @code{InnoDB} installation.
@item
Start a second @command{mysqld} server on the backup and let it clean up
the @file{.ibd} files in the backup. 
@end enumerate

It is in the TODO to also allow moving clean @file{.ibd} files to
another MySQL installation. This requires resetting of
transaction IDs and log sequence numbers in the @file{.ibd} file.


@node Adding and removing, Backing up, Using InnoDB tables, InnoDB
@section Adding and Removing @code{InnoDB} Data and Log Files

This section describes what you can do when your @code{InnoDB} tablespace runs
out of room or when you want to change the size of the log files.

From MySQL 3.23.50 and 4.0.2, the easiest way to increase the size of the
@code{InnoDB} tablespace is to configure it from the beginning to be
auto-extending.  Specify the @code{autoextend} attribute for the last
data file in the tablespace definition. Then @code{InnoDB} will increase the
size of that file automatically in 8MB increments when it runs out of space.
Starting with MySQL 4.1.5, the increment size can be
configured with the option @code{innodb_autoextend_increment}, in megabytes.
The default value is 8.

Alternatively, you can increase the size of your tablespace by adding another
data file. To do this, you have to shut down the MySQL server,
edit the @file{my.cnf} file to add a new data file to the end of
@code{innodb_data_file_path}, and start the server again.

If your last data file already was defined with the keyword @code{autoextend},
the procedure to edit @file{my.cnf} must take into account the size to
which the last data file has grown. You have to
look at the size of the data file, round the size downward to the
closest multiple of 1024 * 1024 bytes (= 1MB), and specify the rounded
size explicitly in @code{innodb_data_file_path}. Then you can add
another data file.  Remember that only the last data file in the
@code{innodb_data_file_path} can be specified as auto-extending.

As an example, assume that the tablespace has just one auto-extending data file
@file{ibdata1}:

@example
innodb_data_home_dir =
innodb_data_file_path = /ibdata/ibdata1:10M:autoextend
@end example

Suppose that that this data file, over time, has grown to 988MB. Below is the
configuration line after adding another auto-extending data file.

@example
innodb_data_home_dir =
innodb_data_file_path = /ibdata/ibdata1:988M;/disk2/ibdata2:50M:autoextend
@end example

When you add a new file to the tablespace, make sure that it does not
exist. @code{InnoDB} will create and initialize it when you restart
the server.

Currently, you cannot remove a data file from the tablespace. To decrease the
size of your tablespace, use this procedure:

@enumerate
@item
Use @command{mysqldump} to dump all your @code{InnoDB} tables.
@item
Stop the server.
@item
Remove all the existing tablespace files.
@item
Configure a new tablespace.
@item
Restart the server.
@item
Import the dump files.
@end enumerate

If you want to change the number or the size of your @code{InnoDB} log
files, you have to stop the MySQL server and make sure that it shuts down
without errors.  Then copy the old log files into a safe place just in case
something went wrong in the shutdown and you will need them to recover the
tablespace. Delete the old log files from the log file directory, edit
@file{my.cnf} to change the log file configuration, and start the MySQL
server again. @command{mysqld} will see that the no log files exist at startup
and tell you that it is creating new ones.


@node Backing up, Moving, Adding and removing, InnoDB
@section Backing Up and Recovering an @code{InnoDB} Database

The key to safe database management is taking regular backups.

@code{InnoDB Hot Backup} is an online backup tool you can use to backup
your @code{InnoDB} database while it is running. @code{InnoDB Hot Backup} does not
require you to shut down your database and it does not set any locks or
disturb your normal database processing. @code{InnoDB Hot Backup}
is a non-free (commercial) additional tool whose annual license fee is
390 euros per computer where the MySQL server is run.
See the @uref{http://www.innodb.com/order.html,@code{InnoDB Hot Backup} home page}
for detailed information and screenshots.

If you are able to shut down your MySQL server, you can make
a ``binary'' backup that consists of all files used by @code{InnoDB} to manage
its tables. Use the following procedure:

@enumerate
@item
Shut down your MySQL server and make sure that it shuts down without errors.
@item
Copy all your data files into a safe place.
@item
Copy all your @code{InnoDB} log files to a safe place.
@item
Copy your @file{my.cnf} configuration file or files to a safe place.
@item
Copy all the @file{.frm} files for your @code{InnoDB} tables to a safe place.
@end enumerate

Replication works with @code{InnoDB} type tables, so you can use MySQL
replication capabilities to keep a copy of your database at database sites
requiring high availability.

In addition to taking binary backups as just described,
you should also regularly take dumps of your tables with
@command{mysqldump}. The reason for this is that a binary file
might be corrupted without you noticing it. Dumped tables are stored
into text files that are human-readable, so spotting table corruption
becomes easier. Also, since the format is simpler, the chance for
serious data corruption is smaller.
@command{mysqldump} also has a @code{--single-transaction} option that
you can use to take a consistent snapshot without locking out other
clients.

To be able to recover your @code{InnoDB} database to the present from the
binary backup described above, you have to run your MySQL server
with binary logging turned on. Then you can apply the binary log to the
backup database to achieve point-in-time recovery:

@example
mysqlbinlog @var{yourhostname}-bin.123 | mysql
@end example

To recover from a crash of your MySQL server process, the only thing
you have to do is to restart it. @code{InnoDB} will automatically check the
logs and perform a roll-forward of the database to the present.
@code{InnoDB} will automatically roll back uncommitted transactions that were
present at the time of the crash. During recovery, @command{mysqld} will
display output something like this:

@example
InnoDB: Database was not shut down normally.
InnoDB: Starting recovery from log files...
InnoDB: Starting log scan based on checkpoint at
InnoDB: log sequence number 0 13674004
InnoDB: Doing recovery: scanned up to log sequence number 0 13739520
InnoDB: Doing recovery: scanned up to log sequence number 0 13805056
InnoDB: Doing recovery: scanned up to log sequence number 0 13870592
InnoDB: Doing recovery: scanned up to log sequence number 0 13936128
...
InnoDB: Doing recovery: scanned up to log sequence number 0 20555264
InnoDB: Doing recovery: scanned up to log sequence number 0 20620800
InnoDB: Doing recovery: scanned up to log sequence number 0 20664692
InnoDB: 1 uncommitted transaction(s) which must be rolled back
InnoDB: Starting rollback of uncommitted transactions
InnoDB: Rolling back trx no 16745
InnoDB: Rolling back of trx no 16745 completed
InnoDB: Rollback of uncommitted transactions completed
InnoDB: Starting an apply batch of log records to the database...
InnoDB: Apply batch completed
InnoDB: Started
mysqld: ready for connections
@end example

If your database gets corrupted or your disk fails, you have
to do the recovery from a backup. In the case of corruption, you should
first find a backup that is not corrupted. After restoring the base
backup, do the recovery from the binary log files.

In some cases of database corruption it is enough just to dump, drop,
and re-create one or a few corrupt tables. You can use the
@code{CHECK TABLE} SQL statement to check whether a table is corrupt, although
@code{CHECK TABLE} naturally cannot detect every possible kind of corruption.
You can use @code{innodb_tablespace_monitor} to check the integrity of
the file space management inside the tablespace files.

In some cases, apparent database page corruption is actually due to the
operating system corrupting its own file cache, and the data
on disk may be okay. It is best first to try restarting your computer.
It may eliminate errors that appeared to be database page corruption.


@menu
* Forcing recovery::            Forcing Recovery
* InnoDB checkpoints::          Checkpoints
@end menu


@node Forcing recovery, InnoDB checkpoints, Backing up, Backing up
@subsection Forcing Recovery

If there is database page corruption, you may want to dump
your tables from the database with @code{SELECT INTO OUTFILE},
and usually most of the data
is intact and correct. But the corruption may cause
@code{SELECT * FROM @var{tbl_name}} or @code{InnoDB}
background operations to crash or assert, or even the @code{InnoDB}
roll-forward recovery to crash. Starting from MySQL
3.23.44, there is an @code{InnoDB} variable that you can use to
force the @code{InnoDB} storage engine to start up, and you can also
prevent background operations from running, so that
you will be able to dump your tables. For example, you can add the following
line to the @code{[mysqld]} section of your option file before restarting the
server:

@example
[mysqld]
innodb_force_recovery = 4
@end example

Before MySQL 4.0, use this syntax instead:

@example
[mysqld]
set-variable = innodb_force_recovery=4
@end example

The allowable non-zero values for @code{innodb_force_recovery} follow.
A larger number includes all precautions of lower numbers. If you are
able to dump your tables with an option value of at most 4, then you are
relatively safe that only some data on corrupt individual pages
is lost. A value of 6 is more dramatic, because database pages are left
in an obsolete state, which in turn may introduce more corruption
into B-trees and other database structures.

@c Note: Do not remove blank lines following the @item lines

@itemize @bullet

@item @code{1} (@code{SRV_FORCE_IGNORE_CORRUPT})

Let the server run even if it detects a corrupt page; try to make
@code{SELECT * FROM @var{tbl_name}} jump over corrupt index records and pages,
which helps in dumping tables.

@item @code{2} (@code{SRV_FORCE_NO_BACKGROUND})

Prevent the main thread from running. If a crash would occur
in the purge operation, this prevents it.

@item @code{3} (@code{SRV_FORCE_NO_TRX_UNDO})

Do not run transaction rollbacks after recovery.

@item @code{4} (@code{SRV_FORCE_NO_IBUF_MERGE})

Prevent also insert buffer merge operations. If they would cause a
crash, better not do them; do not calculate table statistics.

@item @code{5} (@code{SRV_FORCE_NO_UNDO_LOG_SCAN})

Do not look at undo logs when starting the database: @code{InnoDB} will
treat even incomplete transactions as committed.

@item @code{6} (@code{SRV_FORCE_NO_LOG_REDO})

Do not do the log roll-forward in connection with recovery.

@end itemize

The database must not otherwise be used with any of these options enabled!  As a safety
measure, @code{InnoDB} prevents users from doing @code{INSERT},
@code{UPDATE}, or @code{DELETE} when @code{innodb_force_recovery} is set to
a value greater than 0.

Starting from MySQL 3.23.53 and 4.0.4, you are allowed to @code{DROP} or
@code{CREATE} a table even if forced recovery is used. If you know that a
certain table is causing a crash in rollback, you can drop it.  You can use
this also to stop a runaway rollback caused by a failing mass import or
@code{ALTER TABLE}.  You can kill the @command{mysqld} process and set
@code{innodb_force_recovery} to @code{3} to bring your database up without
the rollback.  Then @code{DROP} the table that is causing the runaway
rollback.


@node InnoDB checkpoints,  , Forcing recovery, Backing up
@subsection Checkpoints

@code{InnoDB} implements a checkpoint mechanism called a ``fuzzy
checkpoint.'' @code{InnoDB} will flush modified database pages from the buffer
pool in small batches. There is no need to flush the buffer pool
in one single batch, which would in practice stop processing
of user SQL statements for a while.

In crash recovery, @code{InnoDB} looks for a checkpoint label written
to the log files. It knows that all modifications to the database
before the label are already present in the disk image of the database.
Then @code{InnoDB} scans the log files forward from the place of the
checkpoint,
applying the logged modifications to the database.

@code{InnoDB} writes to the log files in a circular fashion.
All committed modifications that make the database pages in the buffer
pool different from the images on disk must be available in the log files
in case @code{InnoDB} has to do a recovery. This means that when @code{InnoDB} starts
to reuse a log file in the circular fashion, it has to make sure that the
database page images on disk already contain the modifications
logged in the log file @code{InnoDB} is going to reuse. In other words,
@code{InnoDB}
has to make a checkpoint and often this involves flushing of
modified database pages to disk.

The preceding description explains why making your log files very big may save
disk I/O in checkpointing. It can make sense to set
the total size of the log files as big as the buffer pool or even bigger.
The drawback of big log files is that crash recovery can take longer
because there will be more logged information to apply to the database.


@node Moving, InnoDB transaction model, Backing up, InnoDB
@section Moving an @code{InnoDB} Database to Another Machine

On Windows, @code{InnoDB} internally always stores database and
table names in lowercase. To move databases in a binary format 
from Unix to Windows or from Windows to Unix, you should have all table
and database names in lowercase. A convenient way to accomplish this
on Unix is to add the following line to the @code{[mysqld]} section of
your @file{my.cnf} before you start creating your databases and tables:

@example
[mysqld]
set-variable = lower_case_table_names=1
@end example

On Windows, @code{lower_case_table_names} is set to @code{1} by default.

Like @code{MyISAM} data files, @code{InnoDB} data and log files are
binary-compatible on all platforms if the floating-point number format on
the machines is the same.  You can move an @code{InnoDB} database simply by
copying all the relevant files, which were listed in @ref{Backing up}.  If
the floating-point formats on the machines are different but you have not
used @code{FLOAT} or @code{DOUBLE} data types in your tables, then the
procedure is the same: Just copy the relevant files. If the formats are
different and your tables contain floating-point data, you have to use
@command{mysqldump} to dump your tables on one machine and then import the dump
files on the other machine.

A performance tip is to switch off autocommit mode when you import
data into your database, assuming that your tablespace has enough space for
the big rollback segment the big import transaction will generate.
Do the commit only after importing a whole table or a segment of
a table.


@node InnoDB transaction model, InnoDB tuning, Moving, InnoDB
@section @code{InnoDB} Transaction Model and Locking

In the @code{InnoDB} transaction model, the goal has been to combine the
best properties of a multi-versioning database with traditional two-phase
locking.  @code{InnoDB} does locking on the row level and runs queries as
non-locking consistent reads by default, in the style of Oracle.  The lock
table in @code{InnoDB} is stored so space-efficiently that lock escalation
is not needed: Typically several users are allowed to lock every row in the
database, or any random subset of the rows, without @code{InnoDB} running
out of memory.


@menu
* InnoDB and AUTOCOMMIT::       @code{InnoDB} and @code{AUTOCOMMIT}
* InnoDB transaction isolation::  @code{InnoDB} and @code{TRANSACTION ISOLATION LEVEL}
* InnoDB consistent read::      Consistent Non-Locking Read
* InnoDB locking reads::        Locking Reads @code{SELECT ... FOR UPDATE} and @code{SELECT ... LOCK IN SHARE MODE}
* InnoDB Next-key locking::     Next-Key Locking: Avoiding the Phantom Problem
* InnoDB Consistent read example::  An Example of How the Consistent Read Works in @code{InnoDB}
* InnoDB Locks set::            Locks Set by Different SQL Statements in @code{InnoDB}
* InnoDB implicit command or rollback::  When Does MySQL Implicitly Commit or Roll Back a Transaction?
* InnoDB Deadlock detection::   Deadlock Detection and Rollback
* Innodb deadlocks::            How to Cope with Deadlocks
@end menu


@node InnoDB and AUTOCOMMIT, InnoDB transaction isolation, InnoDB transaction model, InnoDB transaction model
@subsection @code{InnoDB} and @code{AUTOCOMMIT}

In @code{InnoDB}, all user activity occurs inside a transaction. If the
autocommit mode is enabled, each SQL statement forms a
single transaction on its own. MySQL always starts a new connection
with autocommit enabled.

If the autocommit mode is switched off with @code{SET AUTOCOMMIT = 0},
then we can consider that a user always has a transaction open. An
SQL @code{COMMIT} or @code{ROLLBACK} statement ends the
current transaction and a new one starts. Both statements will release
all @code{InnoDB} locks that were set during the current transaction.
A @code{COMMIT} means that the changes made in the current transaction
are made permanent and become visible to other users.
A @code{ROLLBACK} statement, on the other hand, cancels all
modifications made by the current transaction.

If the connection has autocommit enabled, the user can still
perform a multiple-statement transaction by starting it with an
explicit @code{START TRANSACTION} or @code{BEGIN} statement and ending it with
@code{COMMIT} or @code{ROLLBACK}.


@node InnoDB transaction isolation, InnoDB consistent read, InnoDB and AUTOCOMMIT, InnoDB transaction model
@subsection @code{InnoDB} and @code{TRANSACTION ISOLATION LEVEL}

In terms of the SQL:1992 transaction isolation levels,
the @code{InnoDB} default is @code{REPEATABLE READ}.
Starting from MySQL 4.0.5, @code{InnoDB} offers all four different
transaction isolation levels described by the SQL standard.
You can set the default isolation level for all connections by using the
@code{--transaction-isolation} option on the command line or in option files.
For example, you can set the option
in the @code{[mysqld]} section of @file{my.cnf} like this:

@example
[mysqld]
transaction-isolation = @{READ-UNCOMMITTED | READ-COMMITTED
                         | REPEATABLE-READ | SERIALIZABLE@}
@end example

A user can change the isolation level of a single session or
all new incoming connections with the @code{SET TRANSACTION}
statement. Its syntax is as follows:

@example
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL
                       @{READ UNCOMMITTED | READ COMMITTED
                        | REPEATABLE READ | SERIALIZABLE@}
@end example

Note that there are hyphens in the level names for the
@code{--transaction-isolation} option, but not for the @code{SET
TRANSACTION} statement.

The default behavior is to set the isolation level for the next (not
started) transaction. If you use the @code{GLOBAL} keyword, the statement
sets the default transaction level globally for all new connections
created from that point on (but not existing connections).
You need the @code{SUPER} privilege to do this.  Using the @code{SESSION}
keyword sets the default transaction level for all future transactions
performed on the current connection.

Any client is free to change the session isolation level (even in the
middle of a transaction), or the isolation level for the next
transaction.

Before MySQL 3.23.50, @code{SET TRANSACTION} had no effect
on @code{InnoDB} tables. Before 4.0.5, only @code{REPEATABLE READ}
and @code{SERIALIZABLE} were available.

You can query the global and session transaction isolation levels with these
statements:

@example
SELECT @@@@global.tx_isolation;
SELECT @@@@tx_isolation;
@end example

In row-level locking, @code{InnoDB} uses so-called ``next-key locking.''
That means that besides index records, @code{InnoDB} can also lock
the ``gap'' before an index record to block insertions by other users
immediately before the index record. A next-key lock refers to
a lock that locks an index record and the gap before it.
A gap lock refers to a lock that only locks a gap before some
index record.

A detailed description of each isolation level in @code{InnoDB}:

@c Note: Do not remove blank lines following the @item lines

@itemize @bullet

@item @code{READ UNCOMMITTED}

@code{SELECT} statements are performed in a non-locking fashion, but a
possible earlier version of a record might be used. Thus, using this
isolation level, such reads are not ``consistent.'' This is also called
``dirty read.''  Other than that, this isolation level works like @code{READ
COMMITTED}.

@item @code{READ COMMITTED}

A somewhat Oracle-like isolation level.  All @code{SELECT ... FOR UPDATE}
and @code{SELECT ... LOCK IN SHARE MODE} statements lock only the index
records, not the gaps before them, and thus allow free inserting of new
records next to locked records.  @code{UPDATE} and @code{DELETE} statements
that use a unique index with a unique search condition lock only the index
record found, not the gap before it.  In range-type @code{UPDATE}
and @code{DELETE} statements, @code{InnoDB} must set next-key or gap locks
and block insertions by other users to the gaps covered by the range. This
is necessary because ``phantom rows'' must be blocked for MySQL replication
and recovery to work.

Consistent reads behave as in Oracle: Each consistent read,
even within the same transaction, sets and reads its own fresh
snapshot.
@xref{InnoDB consistent read}.

@item @code{REPEATABLE READ}

This is the default isolation level of @code{InnoDB}.
@code{SELECT ... FOR UPDATE}, @code{SELECT ... LOCK IN SHARE MODE},
@code{UPDATE}, and @code{DELETE} statements that use a unique index with a
unique search condition lock only the index record found, not the gap
before it.
With other search conditions, these operations employ next-key locking,
locking the index range scanned with next-key or gap locks, and block
new insertions by other users.

In consistent reads, there is an important difference from the
previous isolation level: In this level, all consistent reads within
the same transaction read the same snapshot established by the first
read. This convention means that if you issue several plain
@code{SELECT} statements within the same transaction, these
@code{SELECT} statements are consistent also with respect to each
other.
@xref{InnoDB consistent read}.

@item @code{SERIALIZABLE}

This level is like @code{REPEATABLE READ}, but all plain
@code{SELECT} statements are implicitly converted to
@code{SELECT ... LOCK IN SHARE MODE}.

@end itemize


@node InnoDB consistent read, InnoDB locking reads, InnoDB transaction isolation, InnoDB transaction model
@subsection Consistent Non-Locking Read

A consistent read means that @code{InnoDB} uses its multi-versioning to
present to a query a snapshot of the database at a point in time.
The query will see the changes made by exactly those transactions
that committed before that point of time, and no changes made by
later or uncommitted transactions. The exception to this rule
is that the query will see the changes made by the transaction
itself that issues the query. 

If you are running with the default @code{REPEATABLE READ} isolation level,
then all consistent reads within the same transaction read the snapshot
established by the first such read in that transaction. You can get a
fresher snapshot for your queries by committing the current transaction
and after that issuing new queries. 

Consistent read is the default mode in which @code{InnoDB} processes
@code{SELECT} statements in @code{READ COMMITTED} and
@code{REPEATABLE READ} isolation levels. A consistent read
does not set any locks on the tables it accesses, and
therefore other users are free to modify those tables at
the same time a consistent read is being performed on the table. 


@node InnoDB locking reads, InnoDB Next-key locking, InnoDB consistent read, InnoDB transaction model
@subsection Locking Reads @code{SELECT ... FOR UPDATE} and @code{SELECT ... LOCK IN SHARE MODE}

In some circumstances, a consistent read is not convenient.
For example, you might want to add a new row into your table @code{child},
and make sure that the child already has a parent in table
@code{parent}.  The following example shows how to implement referential
integrity in your application code.

Suppose that you use a consistent read to read the table @code{parent}
and indeed see the parent of the child in the table. Can you now safely
add the child row to table @code{child}? No, because it may
happen that meanwhile some other user deletes the parent row
from the table @code{parent}, without you being aware of it.

The solution is to perform the @code{SELECT} in a locking
mode using @code{LOCK IN SHARE MODE}:

@example
SELECT * FROM parent WHERE NAME = 'Jones' LOCK IN SHARE MODE;
@end example

Performing a read in share mode means that we read the latest
available data, and set a shared mode lock on the rows we read.
A shared mode lock prevents others from updating or deleting
the row we have read.  Also,
if the latest data belongs to a yet uncommitted transaction of another
client connection, we will wait until that transaction commits.
After we see that the preceding query returns
the parent @code{'Jones'}, we can safely add the child record
to the @code{child} table and commit our transaction.

Let us look at another example: We have an integer counter field in
a table @code{child_codes} that we use to assign
a unique identifier to each child added to table @code{child}.
Obviously, using a consistent read or a shared mode read
to read the present value of the counter is not a good idea, since
two users of the database may then see the same value for the
counter, and a duplicate-key error will occur if two users attempt to add
children with the same identifier to the table.

Here, @code{LOCK IN SHARE MODE} is not a good solution because if two
users read the counter at the same time, at least one of them
will end up in deadlock when attempting to update the counter.

In this case, there are two good ways to implement the reading and
incrementing of the counter:
(1) update the counter first by incrementing it by 1 and only after
that read it, or
(2) read the counter first with a lock mode @code{FOR UPDATE}, and
increment after that. The latter approach can be implemented as follows:

@example
SELECT counter_field FROM child_codes FOR UPDATE;
UPDATE child_codes SET counter_field = counter_field + 1;
@end example

A @code{SELECT ... FOR UPDATE} reads the latest
available data, setting exclusive locks on each row it reads.
Thus it sets the same locks a searched SQL @code{UPDATE} would set
on the rows.

Please note that the above is merely an example of how @code{SELECT ... FOR
UPDATE} works. In MySQL, the specific task of generating a unique identifier
actually can be accomplished using only a single access to the table:

@example
UPDATE child_codes SET counter_field = LAST_INSERT_ID(counter_field + 1);
SELECT LAST_INSERT_ID();
@end example

The @code{SELECT} statement merely retrieves the identifier information
(specific to the current connection). It does not access any table.


@node InnoDB Next-key locking, InnoDB Consistent read example, InnoDB locking reads, InnoDB transaction model
@subsection Next-Key Locking: Avoiding the Phantom Problem

In row-level locking, @code{InnoDB} uses an algorithm called ``next-key locking.''
@code{InnoDB} does the row-level locking in such a way that when it searches
or scans an index of a table, it sets shared or exclusive locks
on the index records it encounters. Thus the row-level locks are
actually index record locks.

The locks @code{InnoDB} sets on index records also affect the ``gap'' before
that index record. If a user has a shared or exclusive lock on record
@code{R} in an index, another user cannot insert a new index record
immediately before @code{R} in the index order.  This locking of gaps is
done to prevent the so-called ``phantom problem.'' Suppose that you want to read and
lock all children from the @code{child} table with an identifier value
larger than 100, with the intent of updating some column in the selected
rows later:

@example
SELECT * FROM child WHERE id > 100 FOR UPDATE;
@end example

Suppose that there is an index on the @code{id} column. The query will scan that
index starting from the first record where @code{id} is bigger than 100.
Now, if the locks set on the index records would not lock out inserts made
in the gaps, a new row might meanwhile be inserted to the table. If you now
execute the same @code{SELECT} within the same transaction, you would see a
new row in the result set returned by the query.  This is contrary the
isolation principle of transactions: A transaction should be able to run so
that the data it has read does not change during the transaction. If we
regard a set of rows as a data item, the new ``phantom'' child would violate
this isolation principle.

When @code{InnoDB} scans an index, it can also lock the gap
after the last record in the index. Just that happens in the previous
example: The locks set by @code{InnoDB} prevent any insert to
the table where @code{id} would be bigger than 100.

You can use next-key locking to implement a uniqueness
check in your application: If you read your data in share mode
and do not see a duplicate for a row you are going to insert,
then you can safely insert your row and know that the next-key
lock set on the successor of your row during the read will prevent
anyone meanwhile inserting a duplicate for your row. Thus the next-key
locking allows you to ``lock'' the non-existence of something in your
table.


@node InnoDB Consistent read example, InnoDB Locks set, InnoDB Next-key locking, InnoDB transaction model
@subsection An Example of How the Consistent Read Works in @code{InnoDB}

Suppose that you are running in the default @code{REPEATABLE READ} isolation level.
When you issue a consistent read, that is, an ordinary @code{SELECT}
statement, @code{InnoDB} will give your transaction a timepoint according
to which your query sees the database. If another transaction deletes
a row and commits after your timepoint was assigned, you will
not see the row as having been deleted. Inserts and updates are treated
similarly.

You can advance your timepoint by committing your transaction
and then doing another @code{SELECT}.

This is called ``multi-versioned concurrency control.''

@example
               User A                 User B

           SET AUTOCOMMIT=0;      SET AUTOCOMMIT=0;
time
|          SELECT * FROM t;
|          empty set
|                                 INSERT INTO t VALUES (1, 2);
|
v          SELECT * FROM t;
           empty set
                                  COMMIT;

           SELECT * FROM t;
           empty set

           COMMIT;

           SELECT * FROM t;
           ---------------------
           |    1    |    2    |
           ---------------------
           1 row in set
@end example

In this example,
user A sees the row inserted by B only when B has committed the
insert and A has committed as well, so that the timepoint
is advanced past the commit of B.

If you want to see the ``freshest'' state of the database, you should
use either the @code{READ COMMITTED} isolation level or a locking read:

@example
SELECT * FROM t LOCK IN SHARE MODE;
@end example


@node InnoDB Locks set, InnoDB implicit command or rollback, InnoDB Consistent read example, InnoDB transaction model
@subsection Locks Set by Different SQL Statements in @code{InnoDB}

A locking read, an @code{UPDATE}, or a @code{DELETE}
generally set record locks on every index record that is scanned in
the processing of the SQL query. It does not matter if there are
@code{WHERE} conditions in the query that would exclude the row
from the result set of the query. @code{InnoDB} does not remember the exact
@code{WHERE} condition, but only knows which index ranges were
scanned. The record locks are normally next-key locks that also block
inserts to the ``gap'' immediately before the record.

If the locks to be set are exclusive,
then @code{InnoDB} always retrieves also the clustered index record and sets
a lock on it.

If you do not have indexes suitable for your query and
MySQL has to scan the whole table to process the query,
every row of the table will become locked, which in turn blocks all
inserts by other users to the table. It is important to create good indexes
so that your queries do not unnecessarily need to scan many rows.

@itemize @bullet

@item
@code{SELECT ... FROM} is a consistent read, reading a snapshot of the
database and setting no locks unless the transaction isolation level is set
to @code{SERIALIZABLE}. For @code{SERIALIZABLE} level, this sets shared
next-key locks on the index records it encounters.

@item
@code{SELECT ... FROM ... LOCK IN SHARE MODE}
sets shared next-key locks on all index records the read encounters.

@item
@code{SELECT ... FROM ... FOR UPDATE}
sets exclusive next-key locks on all index records the read
encounters.

@item
@code{INSERT INTO ... VALUES (...)}
sets an exclusive lock on the inserted row. Note that this lock is not
a next-key lock and does not prevent other users from inserting to the
gap before the inserted row. If a duplicate-key error occurs, a shared
lock on the duplicate index record is set.

@item
While initializing a previously specified @code{AUTO_INCREMENT} column
on a table, @code{InnoDB} sets an exclusive lock on the end of the index
associated with the @code{AUTO_INCREMENT} column.
In accessing the auto-increment counter, @code{InnoDB} uses a specific table
lock mode @code{AUTO-INC} where the lock lasts only to the end of the
current SQL statement, instead of to the end of the whole transaction.
@xref{InnoDB and AUTOCOMMIT,  , @code{InnoDB} and @code{AUTOCOMMIT}}.

Before MySQL 3.23.50, @code{SHOW TABLE STATUS} applied to a table
with an @code{AUTO_INCREMENT} column sets an exclusive row-level lock
to the high end of the @code{AUTO_INCREMENT} index. This means
also that @code{SHOW TABLE STATUS} could cause a deadlock of transactions,
something that may surprise users. Starting from MySQL 3.23.50,
@code{InnoDB} fetches the value of a previously initialized
@code{AUTO_INCREMENT} column without setting any locks.

@item
@code{INSERT INTO T SELECT ... FROM S WHERE ...}
sets an exclusive (non-next-key) lock on each row inserted into
@code{T}. It does the search on @code{S} as a consistent read, but
sets shared next-key locks on @code{S} if MySQL binary logging is turned
on. @code{InnoDB} has to set locks in the latter case: In
roll-forward recovery from a backup, every SQL statement has to be
executed in exactly the same way it was done originally.

@item
@code{CREATE TABLE ... SELECT ...}
performs the @code{SELECT} as a consistent read or with shared locks,
as in the previous item.

@item
@code{REPLACE}
is done like an insert if there is no collision on a unique key.
Otherwise, an exclusive next-key lock is placed on the row that has
to be updated.

@item
@code{UPDATE ... WHERE ...}
sets an exclusive next-key lock on every record the search encounters.

@item
@code{DELETE FROM ... WHERE ...}
sets an exclusive next-key lock on every record the search encounters.

@item
If a @code{FOREIGN KEY} constraint is defined on a table, any insert,
update, or delete that requires checking of the constraint condition
sets shared record-level locks on the records it looks at to check the
constraint.  @code{InnoDB} also sets these locks
in the case where the constraint fails.

@item
@code{LOCK TABLES} sets table locks, but it is the higher MySQL layer
above the @code{InnoDB} layer that sets these locks. Beginning with MySQL
4.0.20 and 4.1.2, @code{InnoDB} is aware of table locks if
@code{innodb_table_locks=1}, and the MySQL
layer above @code{InnoDB} knows about row-level locks.  Before that,
the automatic deadlock detection of @code{InnoDB} cannot detect deadlocks
where such table locks are involved.  Also, since the higher MySQL layer
does not know about row-level locks, it is possible to get a table lock
on a table where another user currently has row-level locks. But that does
not put transaction integrity in danger.
@xref{InnoDB Deadlock detection}.
@xref{InnoDB restrictions}.
@end itemize


@node InnoDB implicit command or rollback, InnoDB Deadlock detection, InnoDB Locks set, InnoDB transaction model
@subsection When Does MySQL Implicitly Commit or Roll Back a Transaction?

@c TODO: probably should merge this into the SQL chapter section that
@c also lists these conditions.

MySQL begins each client connection with autocommit mode enabled by default.
When autocommit is enabled, MySQL does a commit after each SQL statement if
that statement did not return an error.

If you have the autocommit mode off and close a connection
without calling an explicit commit of your transaction,
then MySQL will roll back your transaction.

If an SQL statement returns an error, the commit/rollback
behavior depends on the error.
@xref{InnoDB Error handling}.

The following SQL statements (and any synonyms for them) cause an implicit
commit of the current transaction in MySQL:

@itemize @bullet
@item
@code{ALTER TABLE}, @code{BEGIN}, @code{CREATE INDEX}, @code{DROP DATABASE},
@code{DROP INDEX}, @code{DROP TABLE}, @code{LOAD MASTER DATA}, @code{LOCK
TABLES}, @code{RENAME TABLE}, @code{SET AUTOCOMMIT=1}, @code{START
TRANSACTION}, @code{TRUNCATE}, @code{UNLOCK TABLES}.
@item
@code{CREATE TABLE} (this commits only if before MySQL 4.0.13 and MySQL
binary logging is used).
@item
The @code{CREATE TABLE} statement in @code{InnoDB} is processed as a single
transaction. This means that a @code{ROLLBACK} from the user does not
undo @code{CREATE TABLE} statements the user made during that
transaction.
@end itemize


@node InnoDB Deadlock detection, Innodb deadlocks, InnoDB implicit command or rollback, InnoDB transaction model
@subsection Deadlock Detection and Rollback

@code{InnoDB} automatically detects a deadlock of transactions and rolls back a
transaction or transactions to prevent the deadlock. Starting from
MySQL 4.0.5, @code{InnoDB} tries to pick small transactions to roll
back. The size of a transaction is determined by the number of rows
it has inserted, updated, or deleted. Prior to 4.0.5, @code{InnoDB}
always rolled back the transaction whose lock request was the last
one to build a deadlock, that is, a cycle in the ``waits-for'' graph
of transactions. 

Beginning with MySQL 4.0.20 and 4.1.2, @code{InnoDB} is aware of
table locks if @code{innodb_table_locks=1} (1 is the default), and the MySQL
layer above @code{InnoDB} knows about row-level locks.  Before that,
@code{InnoDB} cannot detect deadlocks where a table lock set by a MySQL
@code{LOCK TABLES} statement is involved, or if a lock set
by another storage engine than @code{InnoDB} is involved. You have to resolve
these situations by setting the value of the  @code{innodb_lock_wait_timeout}
system variable.

When @code{InnoDB} performs a complete rollback of a transaction, all the
locks of the transaction are released. However, if just a single SQL
statement is rolled back as a result of an error, some of the locks
set by the SQL statement may be preserved. This is because @code{InnoDB}
stores row locks in a format such it cannot know afterward which lock was
set by which SQL statement.


@node Innodb deadlocks,  , InnoDB Deadlock detection, InnoDB transaction model
@subsection How to Cope with Deadlocks

Deadlocks are a classic problem in transactional databases, but they
are not dangerous unless they are so frequent that you cannot run
certain transactions at all. Normally, you must write your
applications so that they are always prepared to re-issue a
transaction if it gets rolled back because of a deadlock. 

@code{InnoDB} uses automatic row-level locking. You can get deadlocks
even in the case of transactions that just insert or delete a
single row. That is because these operations are not really ``atomic'';
they automatically set locks on the (possibly several) index
records of the row inserted or deleted.

You can cope with deadlocks and reduce the likelihood of their occurrence
with the following techniques: 

@itemize @bullet
@item
Use @code{SHOW INNODB STATUS} to determine the cause of the latest deadlock.
That can help you to tune your application to avoid deadlocks.  This
strategy can be used as of MySQL 3.23.52 and 4.0.3, depending on your MySQL
series.
@item
Always be prepared to re-issue a transaction if it fails due to
deadlock. Deadlocks are not dangerous. Just try again. 
@item
Commit your transactions often. Small transactions are less prone to collide. 
@item
If you are using locking reads (@code{SELECT ... FOR UPDATE}
or @code{... LOCK IN SHARE MODE}), try using a lower isolation
level such as @code{READ COMMITTED}. 
@item
Access your tables and rows in a fixed order. Then transactions
form nice queues and do not deadlock. 
@item
Add well-chosen indexes to your tables. Then your queries need to
scan fewer index records and consequently set fewer locks.
Use @code{EXPLAIN SELECT} to determine which indexes the MySQL
server regards as the most appropriate for your queries.
@item
Use less locking. If you can afford to allow a @code{SELECT} to return data
from an old snapshot, do not add the clause @code{FOR UPDATE}
or @code{LOCK IN SHARE MODE} to it. Using @code{READ COMMITTED}
isolation level is good here, because each consistent read
within the same transaction reads from its own fresh snapshot. 
@item
If nothing helps, serialize your transactions with table-level locks.
The correct way to use @code{LOCK TABLES} with transactional
tables, like InnoDB, is to set @code{AUTOCOMMIT = 0} and not to call
@code{UNLOCK TABLES} until you commit the transaction explicitly.
For example, if you need to write table @code{t1} and read table @code{t2},
you can do this:

@example
SET AUTOCOMMIT=0;
LOCK TABLES t1 WRITE, t2 READ, ...;
[do something with tables t1 and t2 here];
COMMIT;
UNLOCK TABLES;
@end example

Table-level locks make your transactions queue nicely,
and deadlocks are avoided.
@item
Another way to serialize transactions is to create
an auxiliary ``semaphore'' table that contains just a
single row. Have each transaction update that row before
accessing other tables. In that way, all transactions
happen in a serial fashion. Note that the @code{InnoDB} instant
deadlock detection algorithm also works in this case,
because the serializing lock is a row-level lock.
With MySQL table-level locks, the timeout method must be used to
resolve deadlocks.
@item
In applications using @code{AUTOCOMMIT=1} and MySQL's @code{LOCK TABLES}
command, InnoDB's internal table locks that were added in 4.0.20
can cause deadlocks. Starting from 4.0.22, you can set
@code{innodb_table_locks=0} in @file{my.cnf} to fall back to the
old behavior and remove the problem.
@end itemize


@node InnoDB tuning, Implementation, InnoDB transaction model, InnoDB
@section @code{InnoDB} Performance Tuning Tips

@itemize @bullet
@item
If the Unix @file{top} tool or the Windows Task Manager shows
that the CPU usage percentage with your workload is less than 70%,
your workload is probably
disk-bound. Maybe you are making too many transaction commits, or the
buffer pool is too small.
Making the buffer pool bigger can help, but do not set
it bigger than 80% of physical memory.

@item
Wrap several modifications into one transaction. @code{InnoDB} must
flush the log to disk at each transaction commit if that transaction
made modifications to the database. Since the rotation speed of a disk
is typically
at most 167 revolutions/second, that constrains the number of commits
to the same 167th/second if the disk does not fool the operating system.

@item
If you can afford the loss of some of the latest committed transactions, you can
set the @file{my.cnf} parameter @code{innodb_flush_log_at_trx_commit}
to 0. @code{InnoDB} tries to flush the log once per second anyway,
although the flush is not guaranteed.

@item
Make your log files big, even as big as the buffer pool. When @code{InnoDB}
has written the log files full, it has to write the modified contents
of the buffer pool to disk in a checkpoint. Small log files will cause many
unnecessary disk writes. The drawback of big log files is that recovery
time will be longer.

@item
Make the log buffer quite big as well (say, 8MB).

@item
Use the @code{VARCHAR} column type instead of @code{CHAR} if you are
storing variable-length strings or if the column may contain many
@code{NULL} values. A @code{CHAR(@var{N})} column always takes @var{N} bytes to
store data, even if the string is shorter or its value is
@code{NULL}. Smaller tables fit better in the buffer pool and reduce
disk I/O.

@item
(Relevant from 3.23.39 up.)
In some versions of GNU/Linux and Unix, flushing files to disk with the
Unix @code{fsync()} and other similar methods is surprisingly slow.
The default method @code{InnoDB} uses is the @code{fsync()} function.
If you are not satisfied with the database write performance, you might
try setting @code{innodb_flush_method} in @file{my.cnf} to
@code{O_DSYNC}, although @code{O_DSYNC} seems to be slower on most
systems.

@item
When importing data into @code{InnoDB}, make sure that MySQL does not have
autocommit mode enabled because that would require a log flush to disk for
every insert.
To disable autocommit during your import operation, surround it with @code{SET
AUTOCOMMIT} and @code{COMMIT} statements:

@example
SET AUTOCOMMIT=0;
/* SQL import statements ... */
COMMIT;
@end example

If you use the @command{mysqldump} option @code{--opt}, you will get dump
files that are fast to import into an @code{InnoDB} table, even without
wrapping them with the @code{SET AUTOCOMMIT} and @code{COMMIT} statements.

@item
Beware of big rollbacks of mass inserts: @code{InnoDB} uses the insert
buffer to save disk I/O in inserts, but no such mechanism is used in a
corresponding rollback.  A disk-bound rollback can take 30 times the time
of the corresponding insert. Killing the database process will not help
because the rollback will start again at the server startup. The only
way to get rid of a runaway rollback is to increase the buffer pool so that
the rollback becomes CPU-bound and runs fast, or to use a special procedure.
@xref{Forcing recovery}.

@item
Beware also of other big disk-bound operations.
Use @code{DROP TABLE + CREATE TABLE} to empty a
table, not @code{DELETE FROM @var{tbl_name}}.

@item
Use the multiple-row @code{INSERT} syntax to reduce
communication overhead between the client and the server if you need
to insert many rows:

@example
INSERT INTO yourtable VALUES (1,2), (5,5), ...;
@end example

This tip is valid for inserts into any table type, not just @code{InnoDB}.

@item
If you have @code{UNIQUE} constraints on
secondary keys, starting from MySQL 3.23.52 and 4.0.3, you
can speed up table imports by temporarily turning off the uniqueness
checks during the import session:

@example
SET UNIQUE_CHECKS=0;
@end example

For big tables, this saves a lot of disk I/O because @code{InnoDB} can
use its insert buffer to write secondary index records in a batch.

@item
If you have @code{FOREIGN KEY} constraints in your tables, starting
from MySQL 3.23.52 and 4.0.3, you can speed up table imports by turning the
foreign key checks off for a while in the import session:

@example
SET FOREIGN_KEY_CHECKS=0;
@end example

For big tables, this can save a lot of disk I/O.

@item
If you often have recurring queries to tables that are not
updated frequently, use the query cache available as of MySQL 4.0:

@example
[mysqld]
query_cache_type = ON
query_cache_size = 10M
@end example

In MySQL 4.0, the query cache works only with autocommit enabled. This
restriction is removed in MySQL 4.1.1 and up.
@end itemize


@menu
* InnoDB Monitor::              @code{SHOW INNODB STATUS} and the @code{InnoDB} Monitors
@end menu

@node InnoDB Monitor,  , InnoDB tuning, InnoDB tuning
@subsection @code{SHOW INNODB STATUS} and the @code{InnoDB} Monitors

Starting from MySQL 3.23.42, @code{InnoDB} includes @code{InnoDB} Monitors
that print information about the @code{InnoDB} internal state.  Starting from
MySQL 3.23.52 and 4.0.3, you can use the SQL statement @code{SHOW INNODB
STATUS} to fetch the output of the standard @code{InnoDB} Monitor to your
SQL client.  The information is useful in performance tuning. If you are
using the @command{mysql} interactive SQL client, the output is more readable
if you replace the usual semicolon statement terminator by @code{\G}:

@example
mysql> SHOW INNODB STATUS\G
@end example

Another way to use @code{InnoDB} Monitors is to let them continuously write
data to the standard output of the server @command{mysqld}.  In this case,
no output is sent to clients.  When switched on, @code{InnoDB} Monitors
print data about every 15 seconds. Server output usually is directed
to the @file{.err} log in the MySQL data directory.  This data is useful in
performance tuning.  On Windows, you must start the server from a command
prompt in a console window with the @code{--console} option if you want
to direct the output to the window rather than to the error log.

Monitor output includes information of the following types:

@itemize @bullet
@item Table and record locks held by each active transaction
@item Lock waits of a transactions
@item Semaphore waits of threads
@item Pending file I/O requests
@item Buffer pool statistics
@item Purge and insert buffer merge activity of the main @code{InnoDB} thread
@end itemize

To cause the standard @code{InnoDB} Monitor to write to the standard
output of @command{mysqld}, use the following SQL statement:

@example
CREATE TABLE innodb_monitor(a INT) TYPE=InnoDB;
@end example

The monitor can be stopped by issuing the following statement:

@example
DROP TABLE innodb_monitor;
@end example

The @code{CREATE TABLE} syntax is just a way to pass a command
to the @code{InnoDB} engine through the MySQL SQL parser: The only things
that matter are the table name @code{innodb_monitor} and that it be an
@code{InnoDB} table. The structure of the
table is not relevant at all for the @code{InnoDB} Monitor. If you shut down
the server when the monitor is running, and you want to start
the monitor again, you have to drop the
table before you can issue a new @code{CREATE TABLE}
statement to start the monitor.
This syntax may change in a future release.

In a similar way, you can start @code{innodb_lock_monitor}, which is
otherwise the same as @code{innodb_monitor} but also prints a
lot of lock information. A separate @code{innodb_tablespace_monitor}
prints a list of created file segments existing in the tablespace
and also validates the tablespace allocation data structures.
Starting from 3.23.44, there is @code{innodb_table_monitor} with which
you can print the contents of the @code{InnoDB} internal data dictionary.

A sample of @code{InnoDB} Monitor output:

@example
mysql> SHOW INNODB STATUS\G
*************************** 1. row ***************************
Status:
=====================================
030709 13:00:59 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 18 seconds
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 413452, signal count 378357
--Thread 32782 has waited at btr0sea.c line 1477 for 0.00 seconds the semaphore:
X-lock on RW-latch at 41a28668 created in file btr0sea.c line 135
a writer (thread id 32782) has reserved it in mode wait exclusive
number of readers 1, waiters flag 1
Last time read locked in file btr0sea.c line 731
Last time write locked in file btr0sea.c line 1347
Mutex spin waits 0, rounds 0, OS waits 0
RW-shared spins 108462, OS waits 37964; RW-excl spins 681824, OS waits 375485
------------------------
LATEST FOREIGN KEY ERROR
------------------------
030709 13:00:59 Transaction:
TRANSACTION 0 290328284, ACTIVE 0 sec, process no 3195, OS thread id 34831 inser
ting
15 lock struct(s), heap size 2496, undo log entries 9
MySQL thread id 25, query id 4668733 localhost heikki update
insert into ibtest11a (D, B, C) values (5, 'khDk' ,'khDk')
Foreign key constraint fails for table test/ibtest11a:
,
  CONSTRAINT `0_219242` FOREIGN KEY (`A`, `D`) REFERENCES `ibtest11b` (`A`, `D`)
 ON DELETE CASCADE ON UPDATE CASCADE
Trying to add in child table, in index PRIMARY tuple:
 0: len 4; hex 80000101; asc ....;; 1: len 4; hex 80000005; asc ....;; 2: len 4;
 hex 6b68446b; asc khDk;; 3: len 6; hex 0000114e0edc; asc ...N..;; 4: len 7; hex
 00000000c3e0a7; asc .......;; 5: len 4; hex 6b68446b; asc khDk;;
But in parent table test/ibtest11b, in index PRIMARY,
the closest match we can find is record:
RECORD: info bits 0 0: len 4; hex 8000015b; asc ...[;; 1: len 4; hex 80000005; a
sc ....;; 2: len 3; hex 6b6864; asc khd;; 3: len 6; hex 0000111ef3eb; asc ......
;; 4: len 7; hex 800001001e0084; asc .......;; 5: len 3; hex 6b6864; asc khd;;
------------------------
LATEST DETECTED DEADLOCK
------------------------
030709 12:59:58
*** (1) TRANSACTION:
TRANSACTION 0 290252780, ACTIVE 1 sec, process no 3185, OS thread id 30733 inser
ting
LOCK WAIT 3 lock struct(s), heap size 320, undo log entries 146
MySQL thread id 21, query id 4553379 localhost heikki update
INSERT INTO alex1 VALUES(86, 86, 794,'aA35818','bb','c79166','d4766t','e187358f'
,'g84586','h794',date_format('2001-04-03 12:54:22','%Y-%m-%d %H:%i'),7
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 48310 n bits 568 table test/alex1 index symbole
trx id 0 290252780 lock mode S waiting
Record lock, heap no 324 RECORD: info bits 0 0: len 7; hex 61613335383138; asc a
a35818;; 1:
*** (2) TRANSACTION:
TRANSACTION 0 290251546, ACTIVE 2 sec, process no 3190, OS thread id 32782 inser
ting
130 lock struct(s), heap size 11584, undo log entries 437
MySQL thread id 23, query id 4554396 localhost heikki update
REPLACE INTO alex1 VALUES(NULL, 32, NULL,'aa3572','','c3572','d6012t','', NULL,'
h396', NULL, NULL, 7.31,7.31,7.31,200)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 48310 n bits 568 table test/alex1 index symbole
trx id 0 290251546 lock_mode X locks rec but not gap
Record lock, heap no 324 RECORD: info bits 0 0: len 7; hex 61613335383138; asc a
a35818;; 1:
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 48310 n bits 568 table test/alex1 index symbole
trx id 0 290251546 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 82 RECORD: info bits 0 0: len 7; hex 61613335373230; asc aa
35720;; 1:
*** WE ROLL BACK TRANSACTION (1)
------------
TRANSACTIONS
------------
Trx id counter 0 290328385
Purge done for trx's n:o < 0 290315608 undo n:o < 0 17
Total number of lock structs in row lock hash table 70
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0 0, not started, process no 3491, OS thread id 42002
MySQL thread id 32, query id 4668737 localhost heikki
show innodb status
---TRANSACTION 0 290328384, ACTIVE 0 sec, process no 3205, OS thread id 38929 in
serting
1 lock struct(s), heap size 320
MySQL thread id 29, query id 4668736 localhost heikki update
insert into speedc values (1519229,1, 'hgjhjgghggjgjgjgjgjggjgjgjgjgjgggjgjgjlhh
gghggggghhjhghgggggghjhghghghghghhhhghghghjhhjghjghjkghjghjghjghjfhjfh
---TRANSACTION 0 290328383, ACTIVE 0 sec, process no 3180, OS thread id 28684 co
mmitting
1 lock struct(s), heap size 320, undo log entries 1
MySQL thread id 19, query id 4668734 localhost heikki update
insert into speedcm values (1603393,1, 'hgjhjgghggjgjgjgjgjggjgjgjgjgjgggjgjgjlh
hgghggggghhjhghgggggghjhghghghghghhhhghghghjhhjghjghjkghjghjghjghjfhjf
---TRANSACTION 0 290328327, ACTIVE 0 sec, process no 3200, OS thread id 36880 st
arting index read
LOCK WAIT 2 lock struct(s), heap size 320
MySQL thread id 27, query id 4668644 localhost heikki Searching rows for update
update ibtest11a set B = 'kHdkkkk' where A = 89572
------- TRX HAS BEEN WAITING 0 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 65556 n bits 232 table test/ibtest11a index PRIM
ARY trx id 0 290328327 lock_mode X waiting
Record lock, heap no 1 RECORD: info bits 0 0: len 9; hex 73757072656d756d00; asc
 supremum.;;
------------------
---TRANSACTION 0 290328284, ACTIVE 0 sec, process no 3195, OS thread id 34831 ro
llback of SQL statement
ROLLING BACK 14 lock struct(s), heap size 2496, undo log entries 9
MySQL thread id 25, query id 4668733 localhost heikki update
insert into ibtest11a (D, B, C) values (5, 'khDk' ,'khDk')
---TRANSACTION 0 290327208, ACTIVE 1 sec, process no 3190, OS thread id 32782
58 lock struct(s), heap size 5504, undo log entries 159
MySQL thread id 23, query id 4668732 localhost heikki update
REPLACE INTO alex1 VALUES(86, 46, 538,'aa95666','bb','c95666','d9486t','e200498f
','g86814','h538',date_format('2001-04-03 12:54:22','%Y-%m-%d %H:%i'),
---TRANSACTION 0 290323325, ACTIVE 3 sec, process no 3185, OS thread id 30733 in
serting
4 lock struct(s), heap size 1024, undo log entries 165
MySQL thread id 21, query id 4668735 localhost heikki update
INSERT INTO alex1 VALUES(NULL, 49, NULL,'aa42837','','c56319','d1719t','', NULL,
'h321', NULL, NULL, 7.31,7.31,7.31,200)
--------
FILE I/O
--------
I/O thread 0 state: waiting for i/o request (insert buffer thread)
I/O thread 1 state: waiting for i/o request (log thread)
I/O thread 2 state: waiting for i/o request (read thread)
I/O thread 3 state: waiting for i/o request (write thread)
Pending normal aio reads: 0, aio writes: 0,
 ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
Pending flushes (fsync) log: 0; buffer pool: 0
151671 OS file reads, 94747 OS file writes, 8750 OS fsyncs
25.44 reads/s, 18494 avg bytes/read, 17.55 writes/s, 2.33 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf for space 0: size 1, free list len 19, seg size 21,
85004 inserts, 85004 merged recs, 26669 merges
Hash table size 207619, used cells 14461, node heap has 16 buffer(s)
1877.67 hash searches/s, 5121.10 non-hash searches/s
---
LOG
---
Log sequence number 18 1212842764
Log flushed up to   18 1212665295
Last checkpoint at  18 1135877290
0 pending log writes, 0 pending chkp writes
4341 log i/o's done, 1.22 log i/o's/second
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 84966343; in additional pool allocated 1402624
Buffer pool size   3200
Free buffers       110
Database pages     3074
Modified db pages  2674
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages read 171380, created 51968, written 194688
28.72 reads/s, 20.72 creates/s, 47.55 writes/s
Buffer pool hit rate 999 / 1000
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
Main thread process no. 3004, id 7176, state: purging
Number of rows inserted 3738558, updated 127415, deleted 33707, read 755779
1586.13 inserts/s, 50.89 updates/s, 28.44 deletes/s, 107.88 reads/s
----------------------------
END OF INNODB MONITOR OUTPUT
============================
1 row in set (0.05 sec)
@end example

Some notes on the output:

@itemize @bullet
@item
If the @code{TRANSACTIONS} section reports lock waits, your
application may have lock contention. The output can also help to
trace the reasons for transaction deadlocks.

@item
The @code{SEMAPHORES} section reports threads waiting for a semaphore and
statistics on how many times threads have needed a spin or a wait on a
mutex or a rw-lock semaphore. A large number of threads waiting for
semaphores may be a result of disk I/O, or contention problems inside
@code{InnoDB}. Contention can be due to heavy parallelism of queries, or
problems in operating system thread scheduling. Setting
@code{innodb_thread_concurrency} smaller than the default value of @code{8} can
help in such situations.

@item
The @code{BUFFER POOL AND MEMORY} section gives you statistics on pages
read and written. You can calculate from these numbers how many data
file I/O operations your queries currently are doing.

@item
The @code{ROW OPERATIONS} section shows what the main thread is doing.

@end itemize


Beginning with MySQL 4.0.19, @code{InnoDB} sends diagnostic output to stderr
or files instead of stdout or fixed-size memory buffers, to avoid potential
buffer overflow errors.  As a side effect, the output of @code{SHOW INNODB
STATUS} is written to a status file every fifteen seconds.  The name of the
file is @file{innodb_status.@var{pid}}, where @var{pid} is the server
process ID. This file is created in the MySQL data directory.  @code{InnoDB}
removes the file for a normal shutdown.  If abnormal shutdowns have occurred,
instances of these status files may be present and must be removed manually.
Before removing them, you might want to examine them to see if they contain
useful information to the cause of abnormal shutdowns.  Beginning with
MySQL 4.0.21, the @file{innodb_status.@var{pid}} file will only be created
if the configuration option @code{innodb_status_file=1} is set.


@node Implementation, Table and index, InnoDB tuning, InnoDB
@section Implementation of Multi-Versioning

Because @code{InnoDB} is a multi-versioned database, it must keep information
about old versions of rows in the tablespace. This information is stored
in a data structure called a rollback segment after an analogous
data structure in Oracle.

Internally, @code{InnoDB} adds two fields to each row stored in the database.
A 6-byte field indicates the transaction identifier for the last
transaction that inserted or updated the row. Also, a deletion
is treated internally as an update where a special bit in the row
is set to mark it as deleted. Each row also contains a 7-byte
field called the roll pointer. The roll pointer points to an
undo log record written to the rollback segment. If the row was
updated, the undo log record contains the information necessary
to rebuild the content of the row before it was updated.

@code{InnoDB} uses the information in the rollback segment to perform the
undo operations needed in a transaction rollback. It also uses the
information to build earlier versions of a row for a consistent
read.

Undo logs in the rollback segment are divided into insert and update
undo logs. Insert undo logs are needed only in transaction rollback
and can be discarded as soon as the transaction commits. Update undo logs
are used also in consistent reads, and they can be discarded only after
there is no transaction present for which @code{InnoDB} has assigned
a snapshot that in a consistent read could need the information
in the update undo log to build an earlier version of a database
row.

You must remember to commit your transactions regularly, including those
transactions that only issue consistent reads.  Otherwise, @code{InnoDB}
cannot discard data from the update undo logs, and the rollback segment
may grow too big, filling up your tablespace.

The physical size of an undo log record in the rollback segment
is typically smaller than the corresponding inserted or updated
row. You can use this information to calculate the space need
for your rollback segment.

In the @code{InnoDB} multi-versioning scheme, a row is not physically removed from
the database immediately when you delete it with an SQL statement.
Only when @code{InnoDB} can discard the update undo log record written for
the deletion can it also physically remove the corresponding row and
its index records from the database. This removal operation is
called a purge, and it is quite fast, usually taking the same order of
time as the SQL statement that did the deletion.

In a scenario where the user inserts and deletes rows in smallish
batches at about the same rate in the table, it is possible that the
purge thread will start to lag behind, and the table grows bigger and
bigger, making everything disk-bound and very slow.  Even if the table
would carry just @w{10 MB} of useful data, it may grow to occupy
@w{10 GB} with all the dead rows.  In such a case, it would be good
to throttle new row operations, and allocate more resources for the
purge thread.

The InnoDB transaction system maintains a list of transactions that
have delete-marked index records by @code{UPDATE} or @code{DELETE}
operations.  Let the length of this list be @var{purge_lag}.

Starting with MySQL/InnoDB-4.1.6 and 4.0.22, there is a startup option
and settable global variable @code{innodb_max_purge_lag}, which is
zero by default.  When this parameter is nonzero, InnoDB may delay new
row operations.  When the @var{purge_lag} exceeds
@code{innodb_max_purge_lag}, each @code{INSERT}, @code{UPDATE} and
@code{DELETE} operation will be delayed by
@var{purge_lag}/@code{innodb_max_purge_lag}*10-5 milliseconds.  The
delay is computed in the beginning of a purge batch, every ten
seconds.  The operations will not be delayed if purge cannot run
because of an old consistent read view that could see the rows to be
purged.  A typical setting for a problematic workload might be 1
million, assuming that our transactions are small, only 100 bytes in
size, and we can allow @w{100 MB} of unpurged rows in our tables.

@node Table and index, File space management, Implementation, InnoDB
@section Table and Index Structures

MySQL stores its data dictionary information for tables in @file{.frm}
files in database directories. This is true for all MySQL storage engines.
But every @code{InnoDB} table
also has its own entry in @code{InnoDB} internal data dictionaries
inside the tablespace. When MySQL drops a table or a database,
it has to delete both an @file{.frm} file or files, and
the corresponding entries inside the @code{InnoDB} data dictionary.
This is the reason why you cannot move @code{InnoDB} tables between
databases simply by moving the @file{.frm} files. It is also the reason why
@code{DROP DATABASE} did not work for @code{InnoDB} type tables
before MySQL 3.23.44.

Every @code{InnoDB} table has a special index called the clustered index
where the data of the rows is stored. If you define a
@code{PRIMARY KEY} on your table, the index of the primary key
will be the clustered index.

If you do not define a @code{PRIMARY KEY} for
your table, MySQL picks the first @code{UNIQUE} index that has only
@code{NOT NULL} columns as the primary key and
@code{InnoDB} uses it as the clustered index.
If there is no such index in the table,
@code{InnoDB} internally generates a clustered index
where the rows are ordered by the row ID that @code{InnoDB} assigns
to the rows in such a table. The row ID is a 6-byte field that
increases monotonically as new rows are inserted. Thus the rows
ordered by the row ID will be physically in the insertion order.

Accessing a row through the clustered index is fast because the row data
will be on the same page where the index search leads.  If a table is large,
the clustered index architecture often saves a disk I/O when compared to
the traditional solution.  (In many databases, the data is traditionally
stored on a different page from the index record.)

In @code{InnoDB}, the records in non-clustered indexes (also called secondary
indexes) contain the primary key value for the row. @code{InnoDB} uses
this primary key value to search for the row from the clustered index. Note
that if the primary key is long, the secondary indexes use more space.

@code{InnoDB} compares @code{CHAR} and @code{VARCHAR} strings
of different lengths such that the remaining length in the shorter
string is treated as if padded with spaces.

@menu
* InnoDB physical structure::   Physical Structure of an Index
* InnoDB Insert buffering::     Insert Buffering
* InnoDB Adaptive hash::        Adaptive Hash Indexes
* InnoDB Physical record::      Physical Record Structure
@end menu

@node InnoDB physical structure, InnoDB Insert buffering, Table and index, Table and index
@subsection Physical Structure of an Index

All indexes in @code{InnoDB} are B-trees where the index records are
stored in the leaf pages of the tree. The default size of an index
page is 16KB. When new records are inserted, @code{InnoDB} tries to
leave 1/16 of the page free for future insertions and updates
of the index records.

If index records are inserted in a sequential order (ascending or descending),
the resulting index pages will be about 15/16 full.
If records are inserted in a random order, the pages will be from
1/2 to 15/16 full. If the fillfactor of an index page drops below 1/2,
@code{InnoDB} tries to contract the index tree to free the page.


@node InnoDB Insert buffering, InnoDB Adaptive hash, InnoDB physical structure, Table and index
@subsection Insert Buffering

It is a common situation in a database application that the
primary key is a unique identifier and new rows are inserted in the
ascending order of the primary key. Thus the insertions to the
clustered index do not require random reads from a disk.

On the other hand, secondary indexes are usually non-unique, and insertions
into secondary indexes happen in a relatively random order.  This would
cause a lot of random disk I/O operations without a special mechanism used
in @code{InnoDB}.

If an index record should be inserted to a non-unique secondary index,
@code{InnoDB} checks whether the secondary index page is already in the buffer
pool. If that is the case, @code{InnoDB} does the insertion directly to
the index page. If the index page is not found in the buffer
pool, @code{InnoDB} inserts the record to a special insert buffer structure.
The insert buffer is kept so small that it fits entirely in the buffer
pool, and insertions can be done very fast.

Periodically, the insert buffer is merged into the secondary index trees in
the database. Often it is possible to merge several insertions to the same
page of the index tree, saving disk I/O operations.  It has been measured
that the insert buffer can speed up insertions into a table up to 15 times.


@node InnoDB Adaptive hash, InnoDB Physical record, InnoDB Insert buffering, Table and index
@subsection Adaptive Hash Indexes

If a table fits almost entirely in main memory, the fastest way
to perform queries on it is to use hash indexes. @code{InnoDB} has an
automatic mechanism that monitors index searches made to the indexes
defined for a table. If @code{InnoDB} notices that queries could
benefit from building a hash index, it does so automatically.

Note that the hash index is always built based on an existing
B-tree index on the table. @code{InnoDB} can build a hash index on a prefix
of any length of the key defined for the B-tree, depending on the
pattern of searches that @code{InnoDB} observes for the B-tree index.
A hash index can be partial: It is not required that the whole
B-tree index is cached in the buffer pool. @code{InnoDB} will build
hash indexes on demand for those pages of the index that are
often accessed.

In a sense, @code{InnoDB} tailors itself through the adaptive hash index
mechanism to ample main memory, coming closer to the architecture of main
memory databases.


@node InnoDB Physical record,  , InnoDB Adaptive hash, Table and index
@subsection Physical Record Structure

Records in @code{InnoDB} tables have the following characteristics:

@itemize @bullet
@item
Each index record in @code{InnoDB} contains a header of six bytes. The header
is used to link consecutive records together, and also in row-level
locking.
@item
Records in the clustered index contain fields for all user-defined
columns. In addition, there is a six-byte field for the transaction ID
and a seven-byte field for the roll pointer.
@item
If no primary key was defined for a table, each clustered
index record also contains a six-byte row ID field.
@item
Each secondary index record contains also all the fields defined
for the clustered index key.
@item
A record contains also a pointer to each field of the record.
If the total length of the fields in a record is less than 128 bytes,
the pointer is one byte; otherwise, two bytes. The array of these
pointers is called the record directory. The area where these pointers
point is called the data part of the record.
@item
Internally, @code{InnoDB} stores fixed-length character columns such as
@code{CHAR(10)} in a fixed-length format.
@code{InnoDB} truncates trailing spaces
from @code{VARCHAR} columns.
Note that MySQL may internally convert @code{CHAR} columns to
@code{VARCHAR}. @xref{Silent column changes}.
@item
An SQL @code{NULL} value reserves 1 or 2 bytes in the record directory.
Besides that, an SQL @code{NULL} value reserves zero bytes in the data
part of the record if stored in a variable length column.
In a fixed-length column, it reserves the fixed length of the column
in the data part of the record.
The motivation behind reserving the fixed space for @code{NULL} values
is that then an update of the column from @code{NULL} to a
non-@code{NULL} value can be done in place and does not cause
fragmentation of the index page.
@end itemize


@node File space management, InnoDB Error handling, Table and index, InnoDB
@section File Space Management and Disk I/O

@menu
* InnoDB Disk I/O::             Disk I/O
* InnoDB Raw Devices::          Using Raw Devices for the Tablespace
* InnoDB File space::           File Space Management
* InnoDB File Defragmenting::   Defragmenting a Table
@end menu


@node InnoDB Disk I/O, InnoDB Raw Devices, File space management, File space management
@subsection Disk I/O

@code{InnoDB} uses simulated asynchronous disk I/O: @code{InnoDB} creates a number of
threads to take care of I/O operations, such as read-ahead.

There are two read-ahead heuristics in @code{InnoDB}:

@itemize @bullet
@item
In sequential read-ahead, if @code{InnoDB} notices that the access pattern to a
segment in the tablespace is sequential, it posts in
advance a batch of reads of database pages to the I/O system.
@item
In random read-ahead, if @code{InnoDB} notices that some area in a tablespace
seems to be in the process of being fully read into the buffer pool, it
posts the remaining reads to the I/O system.
@end itemize

Starting from MySQL 3.23.40b, @code{InnoDB} uses a novel file flush technique
called doublewrite.
It adds safety to crash recovery after an operating system crash
or a power outage, and improves performance on most Unix flavors
by reducing the need for @code{fsync()} operations.

Doublewrite means that before writing pages to a data file, @code{InnoDB}
first writes them to a contiguous tablespace area called the
doublewrite buffer. Only after the write and the flush to the doublewrite
buffer has completed does @code{InnoDB} write the pages to their proper
positions in the data file. If the operating system crashes in the
middle of a page write, @code{InnoDB} later will find a good
copy of the page from the doublewrite buffer during recovery.


@node InnoDB Raw Devices, InnoDB File space, InnoDB Disk I/O, File space management
@subsection Using Raw Devices for the Tablespace

Starting from MySQL 3.23.41, you can use raw disk partitions as tablespace
data files.
By using a raw disk, you can perform non-buffered I/O on Windows and on
some Unix systems without filesystem overhead, which might improve performance.

When you create a new data file, you must put the keyword @code{newraw}
immediately after the data file size in @code{innodb_data_file_path}.
The partition must be at least as large as the size that you specify.
Note that 1MB in @code{InnoDB} is 1024 * 1024 bytes, whereas 1MB usually
means 1,000,000 bytes in disk specifications.

@example
[mysqld]
innodb_data_home_dir=
innodb_data_file_path=/dev/hdd1:3Gnewraw;/dev/hdd2:2Gnewraw
@end example

The next time you start the server, @code{InnoDB} notices the @code{newraw}
keyword and initializes the new partition. However, do not create or change
any @code{InnoDB} tables yet. Otherwise, when you next restart the server,
@code{InnoDB} will reinitialize the partition and your changes will be lost.
(Starting from 3.23.44, as a safety measure @code{InnoDB} prevents users from
modifying data when any partition with @code{newraw} is specified.)

After @code{InnoDB} has initialized the new partition, stop the server, change
@code{newraw} in the data file specification to @code{raw}:

@example
[mysqld]
innodb_data_home_dir=
innodb_data_file_path=/dev/hdd1:5Graw;/dev/hdd2:2Graw
@end example

Then restart the server and @code{InnoDB} will allow changes to be made.

On Windows, starting from 4.1.1, you can allocate a disk partition
as a data file like this:

@example
[mysqld]
innodb_data_home_dir=
innodb_data_file_path=//./D::10Gnewraw
@end example

The
@file{//./}
corresponds to the Windows syntax of
@file{\\.\}
for accessing physical drives.

When you use raw disk partitions, be sure that they have permissions that
allow read and write access by the account used for running the MySQL
server.


@node InnoDB File space, InnoDB File Defragmenting, InnoDB Raw Devices, File space management
@subsection File Space Management

The data files you define in the configuration file form the tablespace of
@code{InnoDB}. The files are simply concatenated to form the tablespace.
There is no striping in use.  Currently you cannot define where in the
tablespace your tables will be allocated. However, in a newly created
tablespace, @code{InnoDB} allocates space starting from the first
data file.

The tablespace consists of database pages with a default size of 16KB.
The pages are grouped into extents of 64 consecutive pages. The ``files''
inside a tablespace are called segments in @code{InnoDB}.
The name of the ``rollback segment'' is somewhat confusing because it
actually contains many segments in the tablespace.

Two segments are allocated for each index in @code{InnoDB}.  One is for
non-leaf nodes of the B-tree, the other is for the leaf nodes. The idea
here is to achieve better sequentiality for the leaf nodes, which contain
the data.

When a segment grows inside the tablespace, @code{InnoDB} allocates the
first 32 pages to it individually. After that @code{InnoDB} starts
to allocate whole extents to the segment.
@code{InnoDB} can add to a large segment up to 4 extents at a time to ensure
good sequentiality of data.

Some pages in the tablespace contain bitmaps of other pages, and
therefore a few extents in an @code{InnoDB} tablespace cannot be
allocated to segments as a whole, but only as individual pages.

When you ask for available free space in the tablespace by issuing
a @code{SHOW TABLE STATUS}, @code{InnoDB}
reports the extents that are definitely free in the tablespace.
@code{InnoDB} always reserves some extents for clean-up and other internal
purposes; these reserved extents are not included in the free space.

When you delete data from a table, @code{InnoDB} will contract the corresponding
B-tree indexes. It depends on the pattern of deletes whether that frees
individual pages or extents to the tablespace, so that the freed
space becomes available for other users. Dropping a table or deleting
all rows from it is guaranteed to release the space to other users,
but remember that deleted rows will be physically removed only in an
(automatic) purge operation after they are no longer needed in
transaction rollback or consistent read.


@node InnoDB File Defragmenting,  , InnoDB File space, File space management
@subsection Defragmenting a Table

If there are random insertions into or deletions from
the indexes of a table, the indexes
may become fragmented. Fragmentation means that the physical ordering
of the index pages on the disk is not close to the index ordering
of the records on the pages, or that there are many unused pages in the
64-page blocks that were allocated to the index.

A symptom of fragmentation is that a table takes more space than it 'should
take'. How much exactly is that, is difficult to determine. All InnoDB data
and indexes are stored in B-trees, and their fillfactor may vary
50 % - 100 %. Another symptom of fragmentation is that a table scan:
@example
SELECT COUNT(*) FROM t WHERE a_non_indexed_column <> 12345;
@end example
takes more time than 'it should take'. (Above we are fooling the SQL
optimizer to
scan the clustered index, not a secondary index.) Most disks can read 10
- 50 MB/s. That can be used to estimate how fast a table scan should run.

It can speed up index scans if you periodically perform a ``null''
@code{ALTER TABLE} operation:

@example
ALTER TABLE @var{tbl_name} TYPE=InnoDB
@end example

That causes MySQL to rebuild the table. Another way to perform a
defragmention operation is to use @command{mysqldump} to dump the table to a text
file, drop the table, and reload it from the dump file.

If the insertions to an index are always ascending and records are deleted
only from the end, the @code{InnoDB} file space management algorithm
guarantees that fragmentation in the index will not occur.

@node InnoDB Error handling, InnoDB restrictions, File space management, InnoDB
@section Error Handling

Error handling in @code{InnoDB} is not always the same as specified in the
SQL standard. According to the standard, any error during an SQL statement
should cause the rollback of that statement. @code{InnoDB} sometimes rolls
back only part of the statement, or the whole transaction.  The following
items describe how @code{InnoDB} performs error handling:

@itemize @bullet
@item
If you run out of file space in the tablespace,
you will get the MySQL @code{Table is full} error
and @code{InnoDB} rolls back the SQL statement.
@item
A transaction deadlock or a timeout in a lock wait causes @code{InnoDB}
to roll back the whole transaction.
@item
A duplicate-key error rolls back only the insert of that particular row,
even in a statement like @code{INSERT INTO ... SELECT}.
This will probably change so that the SQL statement will be rolled
back if you have not specified the @code{IGNORE} option in your
statement.
@item
A ``row too long'' error rolls back the SQL statement.
@item
Other errors are mostly detected by the MySQL layer of code (above the
@code{InnoDB} storage engine level), and
they roll back the corresponding SQL statement.
@end itemize


@menu
* InnoDB error codes::          @code{InnoDB} Error Codes
* Operating System error codes::  Operating System Error Codes
@end menu

@node InnoDB error codes, Operating System error codes, InnoDB Error handling, InnoDB Error handling
@subsection @code{InnoDB} Error Codes

The following is a non-exhaustive list of common
@code{InnoDB}-specific errors that you may encounter, with information
about why they occur and how to resolve the problem.

@table @code
@item 1005 (@code{ER_CANT_CREATE_TABLE})
Cannot create table. If the error message string refers to
@code{errno} 150, table creation failed because a foreign key
constraint was not correctly formed.

@item 1016 (@code{ER_CANT_OPEN_FILE})
Cannot find the @code{InnoDB} table from the @code{InnoDB} data files though
the @file{.frm} file for the table exists.
@xref{InnoDB troubleshooting datadict}.

@item 1114 (@code{ER_RECORD_FILE_FULL})
@code{InnoDB} has run out of free space in the tablespace.
You should reconfigure the tablespace to add a new data file.

@item 1205 (@code{ER_LOCK_WAIT_TIMEOUT})
Lock wait timeout expired. Transaction was rolled back.

@item 1213 (@code{ER_LOCK_DEADLOCK})
Transaction deadlock. You should rerun the transaction.

@item 1216 (@code{ER_NO_REFERENCED_ROW})
You are trying to add a row but there is no parent row, and a
foreign key constraint fails. You should add the parent row first.

@item 1217 (@code{ER_ROW_IS_REFERENCED})
You are trying to delete a parent row that has children, and a
foreign key constraint fails. You should delete the children first.
@end table


@node Operating System error codes,  , InnoDB error codes, InnoDB Error handling
@subsection Operating System Error Codes

To print the meaning of an operating system error number,
use the @command{perror} program that comes with the MySQL distribution.

The following table provides a list of some common Linux system error codes.
For a more complete list, see
@uref{http://www.iglu.org.il/lxr/source/include/asm-i386/errno.h,Linux source code}.

@table @code
@item  1 (@code{EPERM})
Operation not permitted
@item  2 (@code{ENOENT})
No such file or directory
@item  3 (@code{ESRCH})
No such process
@item  4 (@code{EINTR})
Interrupted system call
@item  5 (@code{EIO})
I/O error
@item  6 (@code{ENXIO})
No such device or address
@item  7 (@code{E2BIG})
Arg list too long
@item  8 (@code{ENOEXEC})
Exec format error
@item  9 (@code{EBADF})
Bad file number
@item 10 (@code{ECHILD})
No child processes
@item 11 (@code{EAGAIN})
Try again
@item 12 (@code{ENOMEM})
Out of memory
@item 13 (@code{EACCES})
Permission denied
@item 14 (@code{EFAULT})
Bad address
@item 15 (@code{ENOTBLK})
Block device required
@item 16 (@code{EBUSY})
Device or resource busy
@item 17 (@code{EEXIST})
File exists
@item 18 (@code{EXDEV})
Cross-device link
@item 19 (@code{ENODEV})
No such device
@item 20 (@code{ENOTDIR})
Not a directory
@item 21 (@code{EISDIR})
Is a directory
@item 22 (@code{EINVAL})
Invalid argument
@item 23 (@code{ENFILE})
File table overflow
@item 24 (@code{EMFILE})
Too many open files
@item 25 (@code{ENOTTY})
Inappropriate ioctl for device
@item 26 (@code{ETXTBSY})
Text file busy
@item 27 (@code{EFBIG})
File too large
@item 28 (@code{ENOSPC})
No space left on device
@item 29 (@code{ESPIPE})
Illegal seek
@item 30 (@code{EROFS})
Read-only file system
@item 31 (@code{EMLINK})
Too many links
@end table


The following table provides a list of some common Windows system error codes.
For a complete list see the
@uref{http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/system_error_codes.asp,Microsoft website}.

@table @code
@item  1 (@code{ERROR_INVALID_FUNCTION})
Incorrect function.
@item  2 (@code{ERROR_FILE_NOT_FOUND})
The system cannot find the file specified.
@item  3 (@code{ERROR_PATH_NOT_FOUND})
The system cannot find the path specified.
@item  4 (@code{ERROR_TOO_MANY_OPEN_FILES})
The system cannot open the file.
@item  5 (@code{ERROR_ACCESS_DENIED})
Access is denied.
@item  6 (@code{ERROR_INVALID_HANDLE})
The handle is invalid.
@item  7 (@code{ERROR_ARENA_TRASHED})
The storage control blocks were destroyed.
@item  8 (@code{ERROR_NOT_ENOUGH_MEMORY})
Not enough storage is available to process this command.
@item  9 (@code{ERROR_INVALID_BLOCK})
The storage control block address is invalid.
@item 10 (@code{ERROR_BAD_ENVIRONMENT})
The environment is incorrect.
@item 11 (@code{ERROR_BAD_FORMAT})
An attempt was made to load a program with an incorrect format.
@item 12 (@code{ERROR_INVALID_ACCESS})
The access code is invalid.
@item 13 (@code{ERROR_INVALID_DATA})
The data is invalid.
@item 14 (@code{ERROR_OUTOFMEMORY})
Not enough storage is available to complete this operation.
@item 15 (@code{ERROR_INVALID_DRIVE})
The system cannot find the drive specified.
@item 16 (@code{ERROR_CURRENT_DIRECTORY})
The directory cannot be removed.
@item 17 (@code{ERROR_NOT_SAME_DEVICE})
The system cannot move the file to a different disk drive.
@item 18 (@code{ERROR_NO_MORE_FILES})
There are no more files.
@item 19 (@code{ERROR_WRITE_PROTECT})
The media is write protected.
@item 20 (@code{ERROR_BAD_UNIT})
The system cannot find the device specified.
@item 21 (@code{ERROR_NOT_READY})
The device is not ready.
@item 22 (@code{ERROR_BAD_COMMAND})
The device does not recognize the command.
@item 23 (@code{ERROR_CRC})
Data error (cyclic redundancy check).
@item 24 (@code{ERROR_BAD_LENGTH})
The program issued a command but the command length is incorrect.
@item 25 (@code{ERROR_SEEK})
The drive cannot locate a specific area or track on the disk.
@item 26 (@code{ERROR_NOT_DOS_DISK})
The specified disk or diskette cannot be accessed.
@item 27 (@code{ERROR_SECTOR_NOT_FOUND})
The drive cannot find the sector requested.
@item 28 (@code{ERROR_OUT_OF_PAPER})
The printer is out of paper.
@item 29 (@code{ERROR_WRITE_FAULT})
The system cannot write to the specified device.
@item 30 (@code{ERROR_READ_FAULT})
The system cannot read from the specified device.
@item 31 (@code{ERROR_GEN_FAILURE})
A device attached to the system is not functioning.
@item 32 (@code{ERROR_SHARING_VIOLATION})
The process cannot access the file because it is being used by another process.
@item 33 (@code{ERROR_LOCK_VIOLATION})
The process cannot access the file because another process has locked a portion of the file.
@item 34 (@code{ERROR_WRONG_DISK})
The wrong diskette is in the drive. Insert %2 (Volume Serial Number: %3) into drive %1.
@item 36 (@code{ERROR_SHARING_BUFFER_EXCEEDED})
Too many files opened for sharing.
@item 38 (@code{ERROR_HANDLE_EOF})
Reached the end of the file.
@item 39 (@code{ERROR_HANDLE_DISK_FULL})
The disk is full.
@item 112 (@code{ERROR_DISK_FULL})
The disk is full.
@item 123 (@code{ERROR_INVALID_NAME})
The filename, directory name, or volume label syntax is incorrect.
@item 1450 (@code{ERROR_NO_SYSTEM_RESOURCES})
Insufficient system resources exist to complete the requested service.
@end table


@node InnoDB restrictions, InnoDB troubleshooting, InnoDB Error handling, InnoDB
@section Restrictions on @code{InnoDB} Tables

@itemize @bullet

@item
A table cannot contain more than 1000 columns.

@item
The internal maximum key length is 3500 bytes, but MySQL itself
restricts this to 1024 bytes.

@item
The maximum row length, except for @code{BLOB} and @code{TEXT} columns,
is slightly less than half of a database page. That is, the maximum row
length is about 8000 bytes. @code{LONGBLOB} and @code{LONGTEXT} columns
must be less than 4GB, and the total row length, including also @code{BLOB}
and @code{TEXT} columns, must be less than 4GB.  @code{InnoDB} stores
the first 512 bytes of a @code{BLOB} or @code{TEXT} column in the row,
and the rest into separate pages.

@item
On some old operating systems, data files must be less than 2GB.

@item
The combined size of the @code{InnoDB} log files must be less than 4GB.

@item
The minimum tablespace size is 10MB.
The maximum tablespace size is four billion database pages (64TB).
This is also the maximum size for a table.

@item
@code{InnoDB} tables do not support @code{FULLTEXT} indexes.

@item
@code{InnoDB} tables do not support spatial column types.

@item
@code{ANALYZE TABLE} counts @code{cardinality} by doing 10 random
dives to each of the index trees and updating index cardinality
estimates accordingly.  Note that because these are only estimates,
repeated runs of @code{ANALYZE TABLE} may produce different numbers.
This makes @code{ANALYZE TABLE} fast on @code{InnoDB} tables but not 100%
accurate as it doesn't take all rows into account.

MySQL uses index cardinality estimates only in join optimization. If
some join is not optimized in the right way, you may try using
@code{ANALYZE TABLE}. In the few cases that @code{ANALYZE TABLE} doesn't
produce values good enough for your particular tables, you can use
@code{FORCE INDEX} with your queries to force the usage of a particular
index, or set @code{max_seeks_for_key} to ensure that MySQL prefers index
lookups over table scans. @xref{Server system
variables}. @xref{Optimizer Issues}.

@item
On Windows, @code{InnoDB} always stores database and table names
internally in lowercase. To move databases in binary format
from Unix to Windows or from Windows to Unix, you should have all database
and table names in lowercase.

@item
@strong{Warning:} Do @emph{not} convert MySQL system tables in the
@code{mysql} database from
@code{MyISAM} to @code{InnoDB} tables!  This is an unsupported operation.
If you do this, MySQL
will not restart until you restore the old system tables from a backup
or re-generate them with the @command{mysql_install_db} script.

@item
@code{InnoDB} does not keep an internal count of rows in a table. (This
would actually be somewhat complicated because of multi-versioning.)
To process a @code{SELECT COUNT(*) FROM T} statement, @code{InnoDB} must
scan an index of the table, which will take some time if the table
is not entirely in the buffer pool. To get a fast count, you have to
use a counter table you create yourself and let your application
update it according to the inserts and deletes it does. If your table
does not change often, using the MySQL query cache is a good
solution.
@code{SHOW TABLE STATUS} also can be used if an approximate row count is
sufficient.
@xref{InnoDB tuning}.

@item
For an @code{AUTO_INCREMENT} column, you must always define an index for
the table, and that index must contain just the @code{AUTO_INCREMENT}
column. In @code{MyISAM} tables, the @code{AUTO_INCREMENT} column may
be part of a multi-column index.

@item
@code{InnoDB} does not support the @code{AUTO_INCREMENT} table option for
setting the initial sequence value in a
@code{CREATE TABLE} or @code{ALTER TABLE} statement.
To set the value with @code{InnoDB}, insert a dummy row with a value
one less and delete that dummy row, or insert the first row with an
explicit value specified.

@item
When you restart the MySQL server, @code{InnoDB} may reuse an old
value for an @code{AUTO_INCREMENT} column (that is, a value that was
assigned to an old transaction that was rolled back).

@item
When an @code{AUTO_INCREMENT} column runs out of values, @code{InnoDB}
wraps a @code{BIGINT} to @code{-9223372036854775808} and @code{BIGINT
UNSIGNED} to @code{1}. However, @code{BIGINT} values have 64 bits, so do
note that if you were to insert one million rows per second, it would still
take nearly three hundred thousand years before @code{BIGINT} reached its upper bound.
With all other integer type columns, a duplicate-key error will result.
This is similar to how @code{MyISAM} works, because it is mostly general MySQL
behavior and not about any storage engine in particular.

@item
@code{DELETE FROM @var{tbl_name}} does not regenerate the table but
instead deletes all rows, one by one.

@item
@code{TRUNCATE @var{tbl_name}} is mapped to @code{DELETE FROM @var{tbl_name}}
for @code{InnoDB} and doesn't reset the @code{AUTO_INCREMENT} counter.

@item
@code{SHOW TABLE STATUS} does not give accurate statistics
on @code{InnoDB} tables, except for the physical size reserved by the table.
The row count is only a rough estimate used in SQL optimization.

@item
If you try to create a unique index on a prefix of a column you will get an
error:

@example
CREATE TABLE T (A CHAR(20), B INT, UNIQUE (A(5))) TYPE = InnoDB;
@end example

If you create a non-unique index on a prefix of a column, @code{InnoDB} will
create an index over the whole column.

These restrictions are removed starting from MySQL 4.0.14 and 4.1.1.

For @code{INSERT DELAYED}, the @code{DELAYED} keyword now is ignored for
@code{InnoDB} tables. It has no effect, but does not cause an error.

@item
Before MySQL 4.0.20 or 4.1.2, the MySQL @code{LOCK TABLES} operation
does not know about @code{InnoDB} row-level locks set by already
completed SQL statements. This means that you can get a table lock on
a table even if there still exist transactions by other users who have
row level locks on the same table. Thus your operations on the table
may have to wait if they collide with these locks of other users. Also
a deadlock is possible. However, this does not endanger transaction
integrity, because the row level locks set by @code{InnoDB} will
always take care of the integrity.  Also, a table lock prevents other
transactions from acquiring more row level locks (in a conflicting
lock mode) on the table.

@item Beginning with MySQL 4.0.20 and 4.1.2, the MySQL @code{LOCK
TABLES} operation acquires two locks on each table if
@code{innodb_table_locks=1}. (1 is the default.)
In addition to a table lock on the MySQL
layer, it will also acquire an @code{InnoDB} table lock.  Older
versions of MySQL do not acquire @code{InnoDB} table locks.  Beginning
with MySQL 4.0.22 and 4.1.7, the old behavior can be selected by
setting @code{innodb_table_locks=0}.  If no @code{InnoDB} table lock
is acquired, @code{LOCK TABLES} will complete even if some records of
the tables are being locked by other transactions.

@item
All @code{InnoDB} locks held by a transaction will be released when the
transaction is committed or aborted.  Thus, it does not make much
sense to invoke @code{LOCK TABLES} on @code{InnoDB} tables in
@code{AUTOCOMMIT=1} mode, because the acquired @code{InnoDB} table
locks would be released immediately.

@item
Sometimes it would be useful to lock further tables in the course of a
transaction.  Unfortunately, @code{LOCK TABLES} in MySQL performs an
implicit @code{COMMIT} and @code{UNLOCK TABLES}.  An InnoDB variant of
@code{LOCK TABLES} has been planned that can be executed in the middle
of a transaction.

@item
Before MySQL 3.23.52,
replication always ran with autocommit enabled. Therefore
consistent reads in the slave would also see partially processed
transactions, and thus the read would not be really consistent in the
slave. This restriction was removed in MySQL 3.23.52.

@item
The @code{LOAD TABLE FROM MASTER} statement for setting up replication
slave servers does not yet work for @code{InnoDB} tables. A workaround
is to alter the table to @code{MyISAM} on the master, do then the load,
and after that alter the master table back to @code{InnoDB}.

@item
The default database page size in @code{InnoDB} is 16KB. By recompiling the
code, you can set it to values ranging from 8KB to 64KB.
You have to update the values of @code{UNIV_PAGE_SIZE} and
@code{UNIV_PAGE_SIZE_SHIFT} in the @file{univ.i} source file.

@end itemize


@node InnoDB troubleshooting,  , InnoDB restrictions, InnoDB
@section @code{InnoDB} Troubleshooting

@itemize @bullet
@item
A general rule is that when an operation fails or you suspect a bug,
you should look at the MySQL server error log, which
typically has a name something like @file{@var{hostname}.err}, or
possibly @file{mysql.err} on Windows.

@item
When doing troubleshooting, it is usually best to run the MySQL server
from the command prompt, not through the
@command{mysqld_safe} wrapper or as a Windows service.
You will then see what @command{mysqld} prints to the command prompt
window, and you have a better grasp of what is going on.
On Windows, you must start the server with the @file{--console}
option to direct the output to the console window.

@item
Use the @code{InnoDB} Monitors to obtain information about a problem.
If the problem is performance-related, or your server appears to be
hung, you should use @code{innodb_monitor} to print information
about the internal state of @code{InnoDB}. If the problem is with locks, use
@code{innodb_lock_monitor}. If the problem is in creation of tables or
other data dictionary operations, use @code{innodb_table_monitor} to
print the contents of the @code{InnoDB} internal data dictionary.

@item
If you suspect a table is corrupt, run @code{CHECK TABLE} on that
table.
@end itemize


@menu
* InnoDB troubleshooting datadict::  Troubleshooting @code{InnoDB} Data Dictionary Operations
@end menu

@node InnoDB troubleshooting datadict,  , InnoDB troubleshooting, InnoDB troubleshooting
@subsection Troubleshooting @code{InnoDB} Data Dictionary Operations

A specific issue with tables is that the MySQL server keeps data
dictionary information in @file{.frm} files it stores in the database
directories, while @code{InnoDB} also stores the information into its own
data dictionary inside the tablespace files.
If you move @file{.frm} files around, or use @code{DROP DATABASE} in
MySQL versions before 3.23.44, or the server crashes in the middle of a
data dictionary operation, the @file{.frm} files may end up
out of sync with the @code{InnoDB} internal data dictionary.

A symptom of an out-of-sync data dictionary is that a @code{CREATE TABLE}
statement fails. If this occurs, you should look in the server's error
log. If the log says that the table already exists inside the @code{InnoDB}
internal data dictionary, you have an orphaned table inside the @code{InnoDB}
tablespace files that has no corresponding @file{.frm} file. The error message
looks like this:

@example
InnoDB: Error: table test/parent already exists in InnoDB internal
InnoDB: data dictionary. Have you deleted the .frm file
InnoDB: and not used DROP TABLE? Have you used DROP DATABASE
InnoDB: for InnoDB tables in MySQL version <= 3.23.43?
InnoDB: See the Restrictions section of the InnoDB manual.
InnoDB: You can drop the orphaned table inside InnoDB by
InnoDB: creating an InnoDB table with the same name in another
InnoDB: database and moving the .frm file to the current database.
InnoDB: Then MySQL thinks the table exists, and DROP TABLE will
InnoDB: succeed.
@end example

You can drop the orphaned table by following the instructions given in
the error message.

Another symptom of an out-of-sync data dictionary is that MySQL prints
an error that it cannot open an @file{.InnoDB} file:

@example
ERROR 1016: Can't open file: 'child2.InnoDB'. (errno: 1)
@end example

In the error log you will find a message like this:

@example
InnoDB: Cannot find table test/child2 from the internal data dictionary
InnoDB: of InnoDB though the .frm file for the table exists. Maybe you
InnoDB: have deleted and recreated InnoDB data files but have forgotten
InnoDB: to delete the corresponding .frm files of InnoDB tables?
@end example

This means that there is an orphaned @file{.frm} file without a
corresponding table inside @code{InnoDB}. You can drop the orphaned
@file{.frm} file by deleting it manually.

If MySQL crashes in the middle of an @code{ALTER TABLE} operation, you
may end up with an orphaned temporary table inside the @code{InnoDB}
tablespace. With @code{innodb_table_monitor} you see a table whose
name is @file{#sql-...}. Starting from MySQL 4.0.6, you can perform
SQL statements also on tables whose name contains the character @samp{#}
if you enclose the name in backticks.
Thus, you can drop such an orphaned table like any other orphaned
table with the method described above. Note that to copy or rename a file
in the Unix shell, you need to put the file name in double quotes if the
file name contains @samp{#}.

Older MySQL versions did not allow accessing any
table with a name containing @samp{#}. The solution in older MySQL
versions is to use a special InnoDB mechanism available starting from
MySQL 3.23.48. When you have an orphaned table @file{#sql-id} inside
the tablespace, you can cause @code{InnoDB} to rename it to
@file{rsql-id_recover_innodb_tmp_table} with the following statement:

@example
CREATE TABLE `rsql-id_recover_innodb_tmp_table`(...) TYPE=InnoDB;
@end example


@node NDBCluster, MaxDB, InnoDB, Top
@chapter MySQL Cluster

@c Authors: Arjen Lentz, Lars Thalmann, Mikael Ronström, Jon Stephens
@c Also integrates "MySQL Cluster for MySQL users" by Anders Karlsson

MySQL Cluster uses the new @code{NDB Cluster} storage engine to enable running
several MySQL servers in a cluster.
The @code{NDB Cluster} storage engine is available in BitKeeper from MySQL
release 4.1.2, and in binary releases from MySQL-Max 4.1.3.

Currently supported operating systems are Linux, Mac OS X, and Solaris.
We are working to make @code{NDB Cluster} run on all operating systems 
supported by MySQL, including Windows.

This chapter represents work in progress.
Other documents describing MySQL Cluster can be found at
@uref{http://www.mysql.com/cluster/}.

You may also wish to subscribe to the MySQL Cluster mailing list.
See @uref{http://lists.mysql.com/}. You may also find the MySQL forums
at @uref{http://forums.mysql.com/}to be useful.

@menu
* MySQL Cluster Overview::      MySQL Cluster Overview
* MySQL Cluster Basics::        Basic MySQL Cluster Concepts
* MySQL Cluster Configuration::  MySQL Cluster Configuration
* MySQL Cluster Process Management::  Process Management in MySQL Cluster
* MySQL Cluster Management::    Management of MySQL Cluster
* MySQL Cluster Interconnects::  Using High-Speed Interconnects with MySQL Cluster
* MySQL Cluster Limitations in 4.1::  MySQL Cluster Limitations in 4.1
@end menu

@node MySQL Cluster Overview, MySQL Cluster Basics, NDBCluster, NDBCluster
@section MySQL Cluster Overview

@code{MySQL Cluster} is a new technology to enable clustering of in-memory
databases in a share-nothing system. The share-nothing architecture allows
the system to work with very inexpensive hardware, and without any specific
requirements on hardware or software. It also does not have any single
point of failure because each component has its own memory and disk.

MySQL Cluster integrates the standard MySQL server with an
in-memory clustered storage engine called @code{NDB}. In our
documentation, the term @code{NDB} refers to the 
part of the setup that is specific to the storage engine, whereas 
@code{MySQL Cluster} refers to the combination
of MySQL and the new storage engine.

A MySQL Cluster consists of a set of computers, each running a number of processes
including MySQL servers, storage nodes for NDB Cluster, management servers
and (possibly) specialized data access programs. All these programs work
together to form MySQL Cluster. When data is stored in the NDB Cluster storage
engine, the tables are stored in the storage nodes for NDB Cluster.
Such tables are directly accessible from all other MySQL servers in
the cluster. Thus, in a payroll application storing data in a cluster, if one 
application updates the salary of an employee, all
other MySQL servers that query this data can see the change immediately.

The data stored in the storage nodes for MySQL Cluster can be mirrored;
the cluster can handle failures of individual storage nodes with no other impact than
that a number of transactions are aborted due to losing the transaction
state. Since transactional applications are expected to handle transaction 
failure, this should not be a source of problems.

By bringing MySQL Cluster to the Open Source world, MySQL makes clustered
data management with high availability, high performance, and scalability
available to all who need it.


@c @node MySQL Cluster History
@c @section History of MySQL Cluster


@c @node MySQL Cluster Licensing
@c @section Licensing and Support of MySQL Cluster


@node MySQL Cluster Basics, MySQL Cluster Configuration, MySQL Cluster Overview, NDBCluster
@section Basic MySQL Cluster Concepts

@code{NDB} is an in-memory storage engine offering high-availability
and data-persistence features.

The @code{NDB} storage engine can be configured with a range of failover and
load-balancing options, but it is easiest to start with the storage
engine at the cluster level. MySQL Cluster's @code{NDB} storage engine 
contains a complete set of data, dependent only on other data within
the cluster itself. 

We will now describe how to set up a MySQL Cluster consisting of an 
@code{NDB} storage engine and some MySQL servers.

The cluster portion of MySQL Cluster is currently configured independently
of the MySQL servers. In a MySQL Cluster, each part of the cluster
is considered to be a @code{node}.

@strong{Note}: A node is in many contexts a computer, but for
MySQL Cluster it is a process. There can be any number of nodes on
a single computer.

Each node has a type, and there can be multiple nodes of each type 
in a MySQL Cluster. In a minimal MySQL Cluster configuration, there
will be at least three nodes:

@itemize @bullet
@item 
The management (@code{MGM}) node: The role of this type of node is to
manage the other nodes within the MySQL Cluster, such as providing
configuration data, starting and stopping nodes, running backup, and so forth.
Because this node type manages the configuration of the other nodes, a
node of this type should be started first, before any other
node. With a running cluster, the MGM node does not necessarily have to
be running all the time. A MGM node is started with the command
@command{ndb_mgmd}; for this reason NDB_MGMD is provided as an alias for
MGM when configuring the cluster.

@item 
The storage or database (@code{DB}) node: This is the type of node that
manages and stores the database itself. There are as many DB nodes
as you have replicas times the number of fragments. For example, with
two replicas, each having two fragments, you will need four DB nodes.
It is not necessary to have more than one replica, so a minimal
MySQL Cluster may contain just one DB node. A DB node is started with the
command @command{ndbd}, and so NDBD is provided as an alias for
DB when configuring the cluster.

@item 
The client (@code{API}) node: This is the client node that will access
the cluster. In the case of MySQL Cluster, a client node is a traditional
MySQL server that uses the @code{NDB Cluster} storage engine, enabling
access to clustered tables. Basically, the MySQL server acts as a client 
of the NDB cluster. Applications using the NDB API directly are also 
considered API nodes. Since a MySQL server is typically started with the 
command @command{mysqld} or @command{mysqld_safe}, MYSQLD is provided as 
an alias for API when configuring the cluster.
@end itemize

Cluster processes are also referred to as cluster nodes. Configuration of 
the cluster involves configuring each individual node in the cluster and 
setting up individual communication links between nodes. MySQL Cluster 
is currently designed with the intention that storage nodes are homogenous 
in terms of processor power, memory space, and communication bandwidth. In 
addition, in order to provide a single point of configuration, all configuration 
data for the cluster as a whole is located in one configuration file.

The management server manages the cluster configuration file and the
cluster log.  Each node in the cluster retrieves the configuration data 
from the management server, and so requires a way to determine
where the management server resides. When interesting events occur in
the storage nodes, the nodes transfer information about these events to the
management server, which then writes the information to the cluster log.

In addition, there can be any number of clients to the cluster. These
are of two types.

@itemize @bullet

@item
@strong{Standard MySQL clients}: These are no different for MySQL Cluster than 
they are for standard (non-Cluster) MySQL. In other words, MySQL Cluster can 
be accessed from existing MySQL applications written in PHP, Perl, C, C++, Java, 
Python, Ruby, and so on.

@item
@strong{Management clients}: These clients connect to the management
server and provide commands for starting and stopping nodes gracefully, 
starting and stopping message tracing (debug versions only), showing node versions 
and status, starting and stopping backups, and so on.

@end itemize


@c @node MySQL Cluster HA
@c @section High Availability Features in MySQL Cluster


@c @node MySQL Cluster NF
@c @subsection Node Failure Handling


@c @node MySQL Cluster NR
@c @subsection Node Restart Handling


@c @node MySQL Cluster Logging
@c @subsection System Crash Recovery Model


@c @node MySQL Cluster SR
@c @subsection Handling a System Restart


@c @node MySQL Cluster NP
@c @subsection How MySQL Cluster Avoids Network Partitioning


@node MySQL Cluster Configuration, MySQL Cluster Process Management, MySQL Cluster Basics, NDBCluster
@section MySQL Cluster Configuration

A MySQL server that is part of a MySQL Cluster differs in only one 
respect from a normal (non-clustered) MySQL server, employing the 
@code{NDBCLUSTER}) storage engine. This engine is also referred to 
simply as @code{NDB}, and the two forms of the name are synonomous.

In order to avoid unnecessary resources allocation, the server is 
configured by default with the @code{NDB} storage engine disabled. To 
enable @code{NDB}, you will need to modify the server's @file{my.cnf} 
configuration file.

Since the MySQL server is a part of the cluster, it will also need to 
know how to access an MGM node in order to obtain the cluster 
configuration data. The default behavior is to look for the MGM node on 
@code{localhost}. However, should you need to specify its location 
elsewhere, this is can be done in @file{my.cnf} or on the MySQL server 
command line. Before the @code{NDB} storage engine can be used, at 
least one MGM node must be operational, as well as any desired DB 
nodes.


@menu
* MySQL Cluster building::      Building from Source Code
* MySQL Cluster installing::    Installing the Software
* MySQL Cluster quick::         Quick Test Setup of MySQL Cluster
* MySQL Cluster Config File::   Configuration File
@end menu

@node MySQL Cluster building, MySQL Cluster installing, MySQL Cluster Configuration, MySQL Cluster Configuration
@subsection Building from Source Code

@code{NDB}, the Cluster storage engine, is available in binary 
distributions beginning with MySQL-Max 4.1.3 for Linux, Mac OS X, and 
Solaris. It is not yet supported on Windows, but we intend to make it 
available for win32 platforms in the near future.

If you choose to build from a source tarball or the MySQL 4.1 BitKeeper 
tree, be sure to use the @code{--with-ndbcluster} option when running
@command{configure}. You can instead use the 
@code{BUILD/compile-pentium-max} build script. Note that this script 
includes OpenSSL, so you must have or obtain OpenSSL to build 
successfully; otherwise you will need to modify 
@code{compile-pentium-max} to exclude this requirement. Of course, you 
can also just follow the standard instructions for compiling your own 
binaries, then perform the usual tests and installation procedure.
 @xref{Installing source tree}.


@node MySQL Cluster installing, MySQL Cluster quick, MySQL Cluster building, MySQL Cluster Configuration
@subsection Installing the Software

In the next few sections, we assume that you are already familiar with 
installing MySQL, and here we cover only the differences between 
configuring MySQL Cluster and configuring MySQL without clustering. 
(See @ref{Installing} if you require more information about the 
latter.)

You will find Cluster configuration easiest if you have already have 
all MGM and DB nodes running first; this is likely to be the most 
time-consuming part of the configuration. Editing the @file{my.cnf} 
file is fairly straightforward, and this section will cover only any 
differences from configuring MySQL without clustering.

@node MySQL Cluster quick, MySQL Cluster Config File, MySQL Cluster installing, MySQL Cluster Configuration
@subsection Quick Test Setup of MySQL Cluster

In order to familiarise you with the basics, we will describe the 
simplest possible configuration for a functional MySQL Cluster. After 
this, you should be able to design your desired setup from the 
information provided in the other relevant sections of this chapter.

First, you need to create a configuration directory, for example 
@file{/var/lib/mysql-cluster}, by executing the following command as 
@code{root}:

@example
shell> mkdir /var/lib/mysql-cluster
@end example

In this directory, create a file named @file{config.ini} with the
following information, substituting appropriate values for 
@code{HostName} and @code{DataDir} as necessary for your system.

@example
# file "config.ini" - showing minimal setup consisting of 1 DB node,
# 1 management server, and 3 MySQL servers.
# The empty default sections are not required, and are shown only for 
# the sake of completeness.
# Storage nodes are required to provide a hostname but MySQL Servers 
# are not.
# If you don't know the hostname for your machine, use localhost.
# The DataDir parameter also has a default value, but it is recommended to
# set it explicitly.
# NDBD, MYSQLD, and NDB_MGMD are aliases for DB, API, and MGM respectively
#
[NDBD DEFAULT]
NoOfReplicas= 1

[MYSQLD DEFAULT]
[NDB_MGMD DEFAULT]
[TCP DEFAULT]

[NDB_MGMD]
HostName= myhost.example.com 

[NDBD]
HostName= myhost.example.com 
DataDir= /var/lib/mysql-cluster

[MYSQLD]
[MYSQLD]
[MYSQLD]
@end example

You can now start the management server as follows:

@example
shell> cd /var/lib/mysql-cluster
shell> ndb_mgmd
@end example

Then start a single DB node by running @command{ndbd}. When starting 
@command{ndbd} for a given DB node for the very first time, you should 
use the @code{--initial} option:

@example
shell> ndbd --initial
@end example

For subsequent @command{ndbd} starts, you will generally not want to use 
@code{--initial}:

@example
shell> ndbd
@end example
 
This is because the @code{--initial} option will delete all existing 
data and log files (as well as all table metadata) for this storage 
node and create new ones.

@c  TODO: xref here to startup options

By default, @command{ndbd} will look for the management server at
@code{localhost} at port 1186. (Prior to MySQL 4.1.8, the default port 
was 2200.)

@strong{Note}: If you have installed MySQL from a binary tarball, you 
will need to specify the path of the @command{ndb_mgmd} and @command{ndbd}
servers explicitly. (Normally, these will be found in 
@file{/usr/local/mysql/bin}.)

Finally, go to the MySQL data directory (usually @file{/var/lib/mysql} 
or @file{/usr/local/mysql/data}), and make sure that the @file{my.cnf} 
file contains the option necessary to enable the @code{NDB} storage 
engine:

@example
[mysqld]
ndbcluster
@end example

You can now start the MySQL server as usual:

@example
shell> mysqld_safe --user=mysql &
@end example

Wait a moment to make sure the MySQL server is running properly. If you 
see the notice @code{mysql ended}, check the server's @file{.err} file 
to find out what went wrong.
 
If all has gone well so far, you now can start using the cluster:

@example
shell> mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1 to server version: 4.1.7

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> SHOW ENGINES;
+------------+---------+------------------------------------------------------------+
| Engine     | Support | Comment                                                    |
+------------+---------+------------------------------------------------------------+
...
| NDBCLUSTER | DEFAULT | Clustered, fault-tolerant, memory-based tables             |
| NDB        | YES     | Alias for NDBCLUSTER                                       |
...

mysql> USE test;
Database changed

mysql> CREATE TABLE ctest (i INT) ENGINE=NDBCLUSTER;
Query OK, 0 rows affected (0.09 sec)

mysql> SHOW CREATE TABLE ctest \G
*************************** 1. row ***************************
       Table: ctest
Create Table: CREATE TABLE `ctest` (
  `i` int(11) default NULL
) ENGINE=ndbcluster DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
@end example

To check that your nodes were set up properly, start the management 
client as shown:

@example
shell> ndb_mgm
@end example

You can then use the @code{SHOW} command from within the management 
client in order to obtain a report on the cluster's status:

@example
NDB> SHOW
Cluster Configuration
---------------------
[ndbd(NDB)]     1 node(s)
id=2    @@127.0.0.1  (Version: 3.5.3, Nodegroup: 0, Master)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @@127.0.0.1  (Version: 3.5.3)

[mysqld(API)]   3 node(s)
id=3    @@127.0.0.1  (Version: 3.5.3)
id=4 (not connected, accepting connect from any host)
id=5 (not connected, accepting connect from any host)
@end example

At this point, you have successfully set up a working MySQL Cluster. 
You can now store data in the cluster by using any table created with 
@code{ENGINE=NDBCLUSTER} or its alias @code{ENGINE=NDB}.

@node MySQL Cluster Config File,  , MySQL Cluster quick, MySQL Cluster Configuration
@subsection Configuration File

@menu
* MySQL Cluster Config Example::  Example Configuration for a MySQL Cluster
* MySQL Cluster Connectstring::  The MySQL Cluster @code{connectstring}
* MySQL Cluster Computer Definition::  Defining the Computers Making up a MySQL Cluster
* MySQL Cluster MGM Definition::  Defining the MySQL Cluster Management Server
* MySQL Cluster DB Definition::  Defining MySQL Cluster Storage Nodes
* MySQL Cluster API Definition::  Defining the MySQL Servers for a MySQL Cluster
* MySQL Cluster TCP Definition::  MySQL Cluster TCP/IP Connections
* MySQL Cluster SHM Definition::  MySQL Cluster Shared-Memory Connections
* MySQL Cluster SCI Definition::  MySQL Cluster SCI Transport Connections
@end menu

Configuring MySQL Cluster requires working with two files:

@itemize @bullet

@item
@file{my.cnf}: Specifies options for all MySQL Cluster executables. This 
file, with which you should be familiar with from previous work with 
MySQL, must be accessible by each executable running in the cluster.

@item
@file{config.ini}: This file is read only by the MySQL Cluster 
management server, which then distributes the information contained in 
this file to all processes participating in the cluster. 
@file{config.ini} contains a description of each node involved in the 
cluster. This includes configuration parameters for storage nodes and
configuration parameters for connections between all nodes in the
cluster.

@end itemize

We are continuously making improvements in Cluster configuration and 
attempting to simplify this process. While we strive to maintain 
backwards compatibility, there may be times when introduce an 
incompatible change. In such cases we will try to let Cluster users
know in advance if a change is not backwards compatible. If you 
find such a change which we have not documented, please use our
@uref{http://bugs.mysql.com, Bugs Database} to report it.

@node MySQL Cluster Config Example, MySQL Cluster Connectstring, MySQL Cluster Config File, MySQL Cluster Config File
@subsubsection Example Configuration for a MySQL Cluster

In order to support MySQL Cluster, you will need to update 
@file{my.cnf} as shown in the example below.

From version 4.1.8 some simplifications in @file{my.cnf} were made, 
including new sections for the @code{ndbcluster} executables. However, 
these should not be confused with those occurring in @file{config.ini}
files. As always, you may specify these parameters when invoking those 
executables from the command line.

@example
# my.cnf
# example additions to my.cnf for MySQL Cluster 
# (valid from 4.1.8)

# enable ndbcluster storage engine, and provide connectstring for 
# management server host (default port is 1186) 
[mysqld]
ndbcluster
ndb-connectstring=ndb_mgmd.mysql.com


# provide connectstring for management server host (default port: 1186)
[ndbd]
connect-string=ndb_mgmd.mysql.com

# provide connectstring for management server host (default port: 1186)
[ndb_mgm]
connect-string=ndb_mgmd.mysql.com

# provide location of cluster configuration file
[ndb_mgmd]
config-file=/etc/config.ini
@end example

(For more information on connectstrings, see 
@ref{MySQL Cluster Connectstring}.)

@example
# my.cnf
# example additions to my.cnf for MySQL Cluster
# (will work on all versions)

# enable ndbcluster storage engine, and provide connectstring for management 
# server host to the default port 2200
[mysqld]
ndbcluster
ndb-connectstring=ndb_mgmd.mysql.com:2200
@end example

Also starting with MySQL 4.1.8, the @file{my.cnf} file supports a 
separate @code{[mysql_cluster]} section for settings to be read by and 
affecting all executables in the cluster:

@example
# cluster-specific settings
[mysql_cluster]
ndb-connectstring=ndb_mgmd.mysql.com:2200
@end example

@c more [mysql_cluster] settings to come later...

Currently the configuration file is in INI format, and is named
@file{config.ini} by default. It is read by @command{ndb_mgmd} at
startup and it can be placed anywhere. Its location and name are 
specified by using @code{--config-file=[<path>]<filename>} on the 
command line with @command{ndb_mgmd}. If the configuration file is not 
specified, @command{ndb_mgmd} will by default try to read a 
@file{config.ini} located in the current working directory.

Default values are defined for most parameters, and can also be 
specified in @file{config.ini}. To create a default value section, 
simply add the word @code{DEFAULT} to the section name. For example, DB 
nodes are configured using @code{[DB]} sections. If all DB nodes use the
same data memory size, and this is not the same as the default size, 
create a @code{[DB DEFAULT]} section containing a @code{DataMemory}
line to specify the default data memory size for all DB nodes.

The INI format consists of sections preceded by section headings 
(surrounded by square brackets), followed by the appropriate parameter 
names and values. One deviation from the standard format is that the 
parameter name and value can be separated by a colon (@samp{:}) as well 
as the equals sign (@samp{=}); another is that sections are not 
uniquely identified by name. Instead, unique entries (such as two 
different nodes of the same type) are identified by a unique ID.

At a minimum, the configuration file must define the computers and 
nodes involved in the cluster and on which computers these nodes are 
located. An example of a simple configuration file for a cluster 
consisting of one management server, two storage nodes and two MySQL 
servers is shown below:

@example
# file "config.ini" - 2 DB nodes and 2 mysqld
# This file is placed in the startup directory of ndb_mgmd,
# i.e., the management server.
# The first MySQL Server can be started from any host and the second
# can only be started at the host mysqld_5.mysql.com
# NDBD, MYSQLD, and NDB_MGMD are aliases for DB, API, and MGM respectively
#

[NDBD DEFAULT]
NoOfReplicas= 2
DataDir= /var/lib/mysql-cluster

[NDB_MGMD]
Hostname= ndb_mgmd.mysql.com
DataDir= /var/lib/mysql-cluster

[NDBD]
HostName= ndbd_2.mysql.com

[NDBD]
HostName= ndbd_3.mysql.com

[MYSQLD]
[MYSQLD]
HostName= mysqld_5.mysql.com
@end example

There are six different sections in this configuration file: 

@itemize @bullet

@item
@code{[COMPUTER]}: Defines the computers in the cluster. 

@item
@code{[DB|NDBD]}: Defines the cluster's storage nodes.

@item
@code{[API|MYSQLD]}: Defines the cluster's MySQL server nodes.

@item
@code{[MGM|NDB_MGMD]}: Defines the management server node in the cluster. 

@item
@code{[TCP]}: Defines TCP/IP connections between nodes in the cluster, 
with TCP/IP being the default connection protocol. 

@item
@code{[SHM]}: Defines shared-memory connections between nodes. This 
type of connection is available only in binaries
that have been built with @code{--with-ndb-shm}.

@end itemize

Note that each node has its own section in the @file{config.ini}. For 
instance, since this cluster has two storage nodes, the configuration 
file contains two sections defining these nodes. (In the example above, 
these sections are labelled with @code{[NDBD]}, but either or both of 
them could have been labelled with @code{[DB]} instead.)

One can define @code{DEFAULT} values for each section. As of MySQL 
4.1.5, all parameter names are case insensitive.

@node MySQL Cluster Connectstring, MySQL Cluster Computer Definition, MySQL Cluster Config Example, MySQL Cluster Config File
@subsubsection The MySQL Cluster @code{connectstring}

With the exception of the MySQL Cluster management server 
(@command{ndb_mgmd}), each node making up a MySQL Cluster requires a 
@code{connectstring} which points to the management server's location. 
This is used in establishing a connection to the management server as 
well as in performing other tasks depending on the node's role in the 
cluster. The syntax for a @code{connectstring} is as follows:

@example 
<connectstring> := [<nodeid-specification>,]<host-specification>[,<host-specification>]
<nodeid-specification> := nodeid=<id>
<host-specification> := <host>[:<port>]
<id> is an integer larger than 1 identifying a node in config.ini
<port> is an integer referring to a regular unix port
<host> is a string which is a valid Internet host address
@end example

@example
example 1 (long):    "nodeid=2,myhost1:1100,myhost2:1100,192.168.0.3:1200"
example 2 (short):   "myhost1"
@end example

All nodes will use @code{localhost:1186} as the default 
@code{connectstring} value if none is provided. If @code{<port>} is 
omitted from the @code{connectstring}, the default port is 1186. 
(@strong{Note}: Prior to MySQL 4.1.8, the default port was 2200.) This 
port should always be available on the network, since it has been 
assigned by IANA for this purpose (see 
@uref{http://www.iana.org/assignments/port-numbers} for details).

By listing multiple @code{<host-specification>} values, it is possible 
to designate several redundant management servers. A cluster node will 
attempt to contact succesive management servers on each host in the 
order specified, until a successful connection has been established.

There are a number of different ways to specify the connectstring:

@itemize @bullet

@item
Each executable has its own command line option which enables 
specifying the management server at startup. (See the documentation 
for the respective executable.)

@item
Beginning with MySQL 4.1.8, it is also possible to set the 
@code{connectstring} to be used by all nodes in the cluster by placing 
it in a @code{[mysql-cluster]} section in the management server's 
@file{my.cnf} file.

@item
For backwards compatibility, two other options are available, using the same
syntax:

@enumerate

@item 
Set the @code{NDB_CONNECTSTRING} environment variable to contain the 
connectstring. 

@item
Write the @code{connectstring} for each executable into a text file 
named @file{Ndb.cfg} and place this file in the executable's startup 
directory.

@end enumerate

@end itemize

The recommended method for specifying the @code{connectstring} is to 
set it on the command line or @file{my.cnf} fiel for each executable.

@node MySQL Cluster Computer Definition, MySQL Cluster MGM Definition, MySQL Cluster Connectstring, MySQL Cluster Config File
@subsubsection Defining the Computers Making up a MySQL Cluster

The @code{[COMPUTER]} section has no real significance other than serving as
a way to avoid the need of defining host names for each node in the system.
All parameters mentioned here are required.

@table @code
@item [COMPUTER]Id
This is an internal identity in the configuration file. Later on in the
file one refers to this computer by the ID. It is an integer.

@item [COMPUTER]HostName
This is the host name of the computer. It is also possible to use an
IP address rather than the host name.
@end table


@node MySQL Cluster MGM Definition, MySQL Cluster DB Definition, MySQL Cluster Computer Definition, MySQL Cluster Config File
@subsubsection Defining the MySQL Cluster Management Server

The @code{[MGM]} section (or its alias @code{[NDB_MGMD]}) is used to 
configure the behavior of the management server. Either the 
@code{ExecuteOnComputer} or @code{HostName} parameter must be present. 
All other parameters can be omitted and if so will assume their 
default values.

@table @code
@item [MGM]Id
Each node in the cluster has a unique identity represented by an 
integer value between 1 and 63 inclusive. This ID is used for 
addressing the node by all internal cluster messages.

@item [MGM]ExecuteOnComputer
This refers to one of the computers defined in the @code{[COMPUTER]} 
section.

@item [MGM]PortNumber
This is the port number on which the management server listens for 
configuration requests and management commands.

@item [MGM]LogDestination
This parameter specifies where to send cluster logging information. 
There are three options in this regard: @code{CONSOLE}, @code{SYSLOG}, and 
@code{FILE}.

@itemize @bullet

@item
@code{CONSOLE} outputs the log to @code{stdout}:

@example
CONSOLE
@end example

@item
@code{SYSLOG} sends the log to a @code{syslog} facility, possible 
values being one of @code{auth}, @code{authpriv}, @code{cron}, 
@code{daemon}, @code{ftp}, @code{kern}, @code{lpr}, @code{mail}, 
@code{news}, @code{syslog}, @code{user}, @code{uucp}, @code{local0}, 
@code{local1}, @code{local2}, @code{local3}, @code{local4}, 
@code{local5}, @code{local6}, or @code{local7}. (@strong{Note}: Not 
every facility is necessarily supported by every operating system.)

@example
SYSLOG:facility=syslog
@end example

@item
@code{FILE} pipes the cluster log ouput to a regular file on the same 
machine. The following values can be specified:

@itemize @bullet

@item
@code{filename}: The name of the logfile.

@item
@code{maxsize}: The maximum size to which the file can grow before 
logging rolls over to a new file. When this occurs, the old logfile is 
renamed by appending @file{.x} to the filename, where @code{x} is the 
next number not yet used with this name.

@item
@code{maxfiles}: The maximum number of logfiles.

@end itemize

@example
FILE:filename=cluster.log,maxsize=1000000,maxfiles=6
@end example

It is possible to specify multiple log destinations as shown here, 
using a semicolon-delimited string:

@example
CONSOLE;SYSLOG:facility=local0;FILE:filename=/var/log/mgmd
@end example

The default value for the @code{FILE} parameter is 
@code{FILE:filename=ndb_<id>_cluster.log,maxsize=1000000,maxfiles=6}, 
where @code{<id>} is the ID of the node.

@end itemize

@item [MGM]ArbitrationRank
This parameter is used to define which nodes can act as arbitrators. 
Only MGM nodes and API nodes can be arbitrators and can take one of the 
following values:

@itemize @bullet 

@item
@code{0}: The node will never be used as an arbitrator. 

@item
@code{1}: The node has high priority; that is, it will be preferred as 
an arbitrator over low-priority nodes.  

@item
@code{2}: Indicates a low-priority node which be used as an arbtrator 
only if a node with a higher priority is not available for that 
purpose.

@end itemize

Normally, the management server should be configured as arbitrator by 
setting its @code{ArbitrationRank} to 1 (the default) and that of all 
API or server nodes to 0.

@item [MGM]ArbitrationDelay
An integer value which causes the management server's responses to 
arbitration requests to be delayed by that number of milliseconds.
By default, this value is 0; it is normally not necessary to change it.

@item [MGM]DataDir
This sets the directory where output files from the management server 
will be placed. These files include cluster log files, process output 
files, and the daemon's pid file. (For log files, this can be 
overridden by setting the @code{FILE} parameter for 
@code{[MGM]LogDestination} as discussed previously in this section.)

@end table


@node MySQL Cluster DB Definition, MySQL Cluster API Definition, MySQL Cluster MGM Definition, MySQL Cluster Config File
@subsubsection Defining MySQL Cluster Storage Nodes

The @code{[DB]} section (or its alias @code{[NDBD]}) is used to configure
the behavior of the storage nodes.  There are many parameters specified that
controls the buffer sizes, pool sizes, timeout parameters and so forth. The
only mandatory parameter is either @code{ExecuteOnComputer} or
@code{HostName} and the parameter @code{NoOfReplicas} which need to be
defined in the @code{[DB DEFAULT]} section. Most parameters should be set in
the @code{[DB DEFAULT]} section. Only parameters explicitly stated as
possible to have local values are allowed to be changed in the @code{[DB]}
section. @code{HostName}, @code{Id} and @code{ExecuteOnComputer} needs to be
defined in the local @code{[DB]} section.

The @code{Id} value (that is, the identification of the storage node) 
can now be allocated when the node is started. It is still possible to 
assign a node ID in the configuration file.

For each parameter it is possible to use k, M, or G as a suffix to indicate
units of 1024, 1024*1024, or 1024*1024*1024. For example, 100k means
102400. Parameters and values are currently case sensitive.

@table @code
@item [DB]Id
This identity is the node ID used as the address of the node in all
cluster internal messages. This is an integer between 1 and 63. Each
node in the cluster has a unique identity.

@item [DB]ExecuteOnComputer
This is referring to one of the computers defined in the computer section.

@item [DB]HostName
This parameter is similar to specifying a computer to execute on. It defines
the host name of the computer the storage node is to reside on. Either this
parameter or @code{ExecuteOnComputer} is required.

@item [DB]ServerPort
Each node in the cluster will use one port as the port other nodes use to
connect the transporters to each other. This port is used also for non-TCP
transporters in the connection setup phase. The default port will be
calculated to ensure that no nodes on the same computer receive the same
port number.

@item [DB]NoOfReplicas
This parameter can be set only in the @code{[DB DEFAULT]} section because it is a
global parameter. It defines the number of replicas for each table
stored in the cluster. This parameter also specifies the size of node
groups. A node group is a set of nodes that all store the same information.

Node groups are formed implicitly. The first node group is formed by the
storage nodes with the lowest node identities. And the next by the next
lowest node identities. As an example presume we have 4 storage nodes and
@code{NoOfReplicas} is set to 2. The four storage nodes have node IDs 2, 3,
4 and 5. Then the first node group will be formed by node 2 and node 3. The
second node group will be formed by node 4 and node 5. It is important to
configure the cluster in such a manner such that nodes in the same node
groups are not placed on the same computer. This would cause a single HW
failure to cause a cluster crash.

If no node identities are provided then the order of the storage nodes will
be the determining factor for the node group. The actual node group assigned
will be printed by the @code{SHOW} command in the management client.

There is no default value and the maximum number is 4.

@item [DB]DataDir
This parameter specifies the directory where trace files, log files, pid files
and error logs are placed.

@item [DB]FileSystemPath
This parameter specifies the directory where all files created for metadata,
REDO logs, UNDO logs and data files are placed. The default value is to use
the same directory as the @code{DataDir}. The directory must be created before
starting the @command{ndbd} process.

If you use the recommended directory hierarchy, you will use a directory
@file{/var/lib/mysql-cluster}. Under this directory a directory @file{ndb_2_fs}
will be created (if node ID was 2) which will be the file system for that
node.

@item [DB]BackupDataDir
It is possible also to specify the directory where backups will be placed.
By default, the directory @code{FileSystemPath/}@file{BACKUP} will be choosen.
@end table

@code{DataMemory} and @code{IndexMemory} are the parameters that specify
the size of memory segments used to store the actual records and their
indexes. It is important to understand how @code{DataMemory} and
@code{IndexMemory} are used to understand how to set these parameters.
For most uses, they need to be updated to reflect the usage of the
cluster.

@table @code
@item [DB]DataMemory
This parameter is one of the most important parameters because it defines the
space available to store the actual records in the database. The entire
@code{DataMemory} will be allocated in memory so it is important that the
machine contains enough memory to handle the @code{DataMemory} size.

The @code{DataMemory} is used to store two things. It stores the actual
records. Each record is currently of fixed size. So @code{VARCHAR} columns are
stored as fixed size columns. There is an overhead on each record of 16
bytes normally. Additionally each record is stored in a 32KB page with
128 byte page overhead.  There will also be a small amount of waste for
each page because records are only stored in one page.  The maximum record
size for the columns currently is 8052 bytes.

The @code{DataMemory} is also used to store ordered indexes. Ordered
indexes uses about 10 bytes per record. Each record in the table is always
represented in the ordered index.

The @code{DataMemory} consists of 32KB pages. These pages are allocated
to partitions of the tables. Each table is normally partitioned with the
same number of partitions as there are storage nodes in the cluster.  Thus
for each node there are the same number of partitions (=fragments) as the
@code{NoOfReplicas} is set to.  Once a page has been allocated to a
partition it is currently not possible to bring it back to the pool of
free pages. The method to restore pages to the pool is by deleting the
table. Performing a node recovery also will compress the partition because
all records are inserted into an empty partition from another live node.

Another important aspect is that the @code{DataMemory} also contains UNDO
information for records. For each update of a record a copy record is
allocated in the @code{DataMemory}. Also each copy record will also have an
instance in the ordered indexes of the table. Unique hash indexes are
updated only when the unique index columns are updated and in that case a new
entry in the index table is inserted and at commit the old entry is
deleted. Thus it is necessary also to allocate memory to be able to handle
the largest transactions which are performed in the cluster.

Performing large transactions has no advantage in MySQL Cluster other than
the consistency of using transactions which is the whole idea of
transactions. It is not faster and consumes large amounts of memory.

The default @code{DataMemory} size is 80MB. The minimum size is 1MB.
There is no maximum size, but in reality the
maximum size has to be adapted so that the process doesn't start swapping
when using the maximum size of the memory.

@item [DB]IndexMemory
The @code{IndexMemory} is the parameter that controls the amount of storage
used for hash indexes in MySQL Cluster. Hash indexes are always used for
primary key indexes, unique indexes, and unique constraints.  Actually
when defining a primary key and a unique index there will be two indexes
created in MySQL Cluster.  One index is a hash index which is used for all
tuple accesses and also for lock handling. It is also used to ensure unique
constraints.

The size of the hash index is 25 bytes plus the size of the primary key.
For primary keys larger than 32 bytes another 8 bytes is added for some
internal references.

Thus for a table defined as

@example
CREATE TABLE example
(
    a INT NOT NULL,
    b INT NOT NULL,
    c INT NOT NULL,
    PRIMARY KEY(a),
    UNIQUE(b)
) ENGINE=NDBCLUSTER;
@end example

We will have 12 bytes overhead (having no nullable columns saves 4 bytes of
overhead) plus 12 bytes of data per record. In addition we will have two
ordered indexes on a and b consuming about 10 bytes each per record. We
will also have a primary key hash index in the base table with roughly 29
bytes per record. The unique constraint is implemented by a separate table
with b as primary key and a as a column. This table will consume another 29
bytes of index memory per record in the table and also 12 bytes of overhead
plus 8 bytes of data in the record part.

Thus for one million records, we will need 58MB of index memory to handle
the hash indexes for the primary key and the unique constraint. For the
@code{DataMemory} part we will need 64MB of memory to handle the
records of the base table and the unique index table plus the two ordered
index tables.

The conclusion is that hash indexes takes up a fair amount of memory space
but in return they provide very fast access to the data. They are also used
in MySQL Cluster to handle uniqueness constraints.

Currently the only partitioning algorithm is hashing and the ordered
indexes are local to each node and can thus not be used to handle
uniqueness constraints in the general case.

An important point for both @code{IndexMemory} and @code{DataMemory} is
that the total database size is the the sum of all @code{DataMemory} and
@code{IndexMemory} in each node group. Each node group is used to store
replicated information, so if there are four nodes with 2 replicas there
will be two node groups and thus the total @code{DataMemory} available is
2*@code{DataMemory} in each of the nodes.

Another important point is about changes of @code{DataMemory} and
@code{IndexMemory}.  First of all, it is highly recommended to have the same
amount of @code{DataMemory} and @code{IndexMemory} in all nodes. Since data
is distributed evenly over all nodes in the cluster the size available is
no better than the smallest sized node in the cluster times the number of
node groups.

@code{DataMemory} and @code{IndexMemory} can be changed, but it is dangerous to
decrease them because that can easily lead to a node that will not be able to
restart or even a cluster not being able to restart since there is not
enough memory space for the tables needed to restore into the starting
node. Increasing them should be quite okay, but it is recommended that such
upgrades are performed in the same manner as a software upgrade where first
the configuration file is updated, then the management server is restarted
and then one storage node at a time is restarted by command.

More @code{IndexMemory} is not used due to updates but inserts are inserted
immediately and deletes are not deleted until the transaction is committed.

The default @code{IndexMemory} size is 18MB. The minimum size is 1MB.
@end table

The next three parameters are important because they affect the number of
parallel transactions and the sizes of transactions that can be handled by
the system. @code{MaxNoOfConcurrentTransactions} sets the number of
parallel transactions possible in a node and
@code{MaxNoOfConcurrentOperations} sets the number of records that can be
in update phase or locked simultaneously.

Both of these parameters and particularly
@code{MaxNoOfConcurrentOperations} are likely targets for users setting
specific values and not using the default value. The default value is set
for systems using small transactions and to ensure not using too much
memory in the default case.

@table @code
@item [DB]MaxNoOfConcurrentTransactions
For each active transaction in the cluster there needs to be also a
transaction record in one of the nodes in the cluster. The role of
transaction coordination is spread among the nodes and thus the total
number of transactions records in the cluster is the amount in one times
the number of nodes in the cluster.

Actually transaction records are allocated to MySQL servers, normally there
is at least one transaction record allocated in the cluster per connection
that uses or have used a table in the cluster. Thus one should ensure that
there is more transaction records in the cluster than there are concurrent
connections to all MySQL servers in the cluster.

This parameter has to be the same in all nodes in the cluster.

Changing this parameter is never safe and can cause a cluster crash. When a
node crashes one of the node (actually the oldest surviving node) will
build up the transaction state of all transactions ongoing in the crashed
node at the time of the crash. It is thus important that this node has as
many transaction records as the failed node.

The default value for this parameter is 4096.

@item [DB]MaxNoOfConcurrentOperations
This parameter is likely to be subject for change by users. Users
performing only short, small transactions don't need to set this parameter very
high. Applications desiring to be able to perform rather large transactions
involving many records need to set this parameter higher.

For each transaction that updates data in the cluster it is required to
have operation records. There are operation records both in the transaction
coordinator and in the nodes where the actual updates are performed.

The operation records contain state information needed to be able to find
UNDO records for rollback, lock queues, and much other state information.

To dimension the cluster to handle transactions where one million records are
updated simultaneously one should set this parameter to one million divided
by the number of nodes. Thus for a cluster with four storage nodes one
should set this parameter to 250000.

Also read queries which set locks use up operation records. Some extra
space is allocated in the local nodes to cater for cases where the
distribution is not perfect over the nodes.

When queries translate into using the unique hash index there will actually
be two operation records used per record in the transaction. The first one
represents the read in the index table and the second handles the operation
on the base table.

The default value for this parameter is 32768.

This parameter actually handles two parts that can be configured separately.
The first part specifies how many operation records are to be placed in the
transaction coordinator part. The second part specifies how many operation
records that are to be used in the local database part.

If a very big transaction is performed on a 8-node cluster then this will
need as many operation records in the transaction coordinator as there are
reads, updates, deletes involved in the transaction. The transaction will
however spread the operation records of the actual reads, updates, and
inserts over all eight nodes. Thus if it is necessary to configure the
system for one very big transaction then it is a good idea to configure
those separately. @code{MaxNoOfConcurrentOperations} will always be used
to calculate the number of operation records in the transaction coordinator
part of the node.

It is also important to have an idea of the memory requirements for those
operation records. In MySQL 4.1.5, operation records consume
about 1KB per record. This figure will shrink in future 5.x versions.

@item [DB]MaxNoOfLocalOperations
By default this parameter is calculated as 1.1 * 
@code{MaxNoOfConcurrentOperations}
which fits systems with many simultaneous, not very large transactions. If
the configuration needs to handle one very large transaction at a time and
there are many nodes then it is a good idea to configure this separately.
@end table

The next set of parameters are used for temporary storage in the midst of
executing a part of a query in the cluster. All of these records will have
been released when the query part is completed and is waiting for the
commit or rollback.

Most of the defaults for these parameters will be okay for most users. Some
high-end users might want to increase those to enable more parallelism in
the system and some low-end users might want to decrease them to save
memory.

@table @code
@item [DB]MaxNoOfConcurrentIndexOperations
For queries using a unique hash index another set of operation records are
temporarily used in the execution phase of the query. This parameter sets
the size of this pool. Thus this record is only allocated while executing a
part of a query, as soon as this part has been executed the record is
released. The state needed to handle aborts and commits is handled by the
normal operation records where the pool size is set by the parameter
@code{MaxNoOfConcurrentOperations}.

The default value of this parameter is 8192. Only in rare cases of
extremely high parallelism using unique hash indexes should this parameter
be necessary to increase. To decrease could be performed for memory savings
if the DBA is certain that such high parallelism is not occurring in the
  cluster.

@item [DB]MaxNoOfFiredTriggers
The default value of @code{MaxNoOfFiredTriggers} is 4000. Normally this
value should be sufficient for most systems. In some cases it could be
decreased if the DBA feels certain the parallelism in the cluster is not so
high.

This record is used when an operation is performed that affects a unique
hash index. Updating a column that is part of a unique hash index or
inserting/deleting a record in a table with unique hash indexes will fire
an insert or delete in the index table. This record is used to represent
this index table operation while its waiting for the original operation
that fired it to complete.  Thus it is short lived but can still need a
fair amount of records in its pool for temporary situations with many
parallel write operations on a base table containing a set of unique hash
indexes.

@item [DB]TransactionBufferMemory
This parameter is also used for keeping fired operations to update index
tables. This part keeps the key and column information for the fired
operations. It should be very rare that this parameter needs to be updated.

Also normal read and write operations use a similar buffer. This buffer is
even more short term in its usage so this is a compile time parameter set to
4000*128 bytes (500KB). The parameter is @code{ZATTRBUF_FILESIZE} in
@var{Dbtc.hpp}. A similar buffer for key info exists which contains 4000*16
bytes, 62.5KB of buffer space. The parameter in this case is
@code{ZDATABUF_FILESIZE} in @var{Dbtc.hpp}. @code{Dbtc} is the module for
handling the transaction coordination.

Similar parameters exist in the @code{Dblqh} module taking care of the reads
and updates where the data is located. In @file{Dblqh.hpp} with
@code{ZATTRINBUF_FILESIZE} set to 10000*128 bytes (1250KB) and
@code{ZDATABUF_FILE_SIZE}, set to 10000*16 bytes (roughly 156KB) of buffer
space. No known instances of that any of those compile time limits haven't
been big enough has been reported so far or discovered by any of our
extensive test suites.

The default size of the @code{TransactionBufferMemory} is 1MB.

@item [DB]MaxNoOfConcurrentScans
This parameter is used to control the amount of parallel scans that can be
performed in the cluster.  Each transaction coordinator can handle the
amount of parallel scans defined by this parameter. Each scan query is
performed by scanning all partitions in parallel. Each partition scan will
use a scan record in the node where the partition is located. The number of
those records is the size of this parameter times the number of nodes so
that the cluster should be able to sustain maximum number of scans in
parallel from all nodes in the cluster.

Scans are performed in two cases. The first case is when no hash or ordered
indexes exists to handle the query. In this case the query is executed by
performing a full table scan. The second case is when there is no hash
index to support the query but there is an ordered index. Using the ordered
index means executing a parallel range scan. Since the order is only kept
on the local partitions it is necessary to perform the index scan on all
partitions.

The default value of @code{MaxNoOfConcurrentScans} is 256. The maximum value
is 500.

This parameter will always specify the number of scans possible in the
transaction coordinator. If the number of local scan records is not provided
it is calculated as the product of @code{MaxNoOfConcurrentScans} and the number
of storage nodes in the system.

@item [DB]MaxNoOfLocalScans
Possible to specify the number of local scan records if many scans are not
fully parallelized.

@item [DB]BatchSizePerLocalScan
This parameter is used to calculate the number of lock records which needs
to be there to handle many concurrent scan operations.

The default value is 64 and this value has a strong connection to the
@code{ScanBatchSize} defined in the API nodes.

@item [DB]LongMessageBuffer
This is an internal buffer used for message passing internally in the node
and for messages between nodes in the system. It is highly unlikely that
anybody would need to change this parameter but for configurability it is
now configurable. By default it is set to 1MB.
@end table

@table @code
@item [DB]NoOfFragmentLogFiles
This is an important parameter that states the size of the REDO
log files in the node. REDO log files are organized in a ring such that it
is important that the tail and the head doesn't meet.  When the tail and
head have come to close the each other the node will start aborting all
updating transactions because there is no room for the log records.

REDO log records aren't removed until three local checkpoints have
completed since the log record was inserted. The speed of checkpoint is
controlled by a set of other parameters so these parameters are all glued
together.
@c How they interact and proposals of how to configure them is
@c provided in @ref{MySQL Cluster Complex Configuration}.

The default parameter value is 8, which means 8 sets of 4 16MB files. Thus in
total 512MB. Thus the unit is 64MB of REDO log space. In high
update scenarios this parameter needs to be set very high.  Test cases
where it has been necessary to set it to over 300 have been performed.

If the checkpointing is slow and there are so many writes to the database
that the log files are full and the log tail cannot be cut for recovery
reasons then all updating transactions will be aborted with internal error
code 410 which will be translated to @code{Out of log file space temporarily}.
This condition will prevail until a checkpoint has completed and the log tail
can be moved forward.

@c @item [DB]MaxNoOfOpenFiles
@c This parameter sets a roof to how many internal threads will be allocated
@c for open files. This parameter should never be necessary to change,
@c necessity to do so should be reported as a bug.

@c The default of this parameter is 40.

@item [DB]MaxNoOfSavedMessages
This parameter sets the maximum number of trace files that will be kept
before overwriting old trace files. Trace files are generated when the node
crashes for some reason.

The default is 25 trace files.
@end table

The next set of parameters defines the pool sizes for metadata objects. It
is necessary to define the maximum number of attributes, tables, indexes,
and trigger objects used by indexes, events and replication between
clusters.

@table @code
@item [DB]MaxNoOfAttributes
This parameter defines the number of attributes that can be defined in the
cluster.

The default value of this parameter is 1000. The minimum value is 32 and there is
no maximum. Each attribute consumes around 200 bytes of storage in each node
because metadata is fully replicated in the servers.

@item [DB]MaxNoOfTables
A table object is allocated for each table, for each unique hash index, and
for each ordered index.  This parameter sets the maximum number of table
objects in the cluster.

For each attribute that has a @code{BLOB} data type an extra table is used to
store most of the @code{BLOB} data. These tables also must be taken into account
when defining the number of tables.

The default value of this parameter is 128. The minimum is 8 and the 
maximum is 1600. Each table object consumes around 20KB in each node.

@item [DB]MaxNoOfOrderedIndexes
For each ordered index in the cluster, objects are allocated to describe what
it is indexing and its storage parts. By default each index defined will have
an ordered index also defined. Unique indexes and primary key indexes have
both an ordered index and a hash index.

The default value of this parameter is 128. Each object consumes around 10KB
of data per node.

@item [DB]MaxNoOfUniqueHashIndexes
For each unique index (not for primary keys) a special table is allocated that
maps the unique key to the primary key of the indexed table. By default there
will be an ordered index also defined for each unique index. To avoid this,
you must use the @code{USING HASH} option in the unique index definition.

The default value is 64. Each index will consume around 15KB per node.

@item [DB]MaxNoOfTriggers
For each unique hash index an internal update, insert and delete trigger is
allocated. Thus three triggers per unique hash index. Ordered indexes use
only one trigger object. Backups also use three trigger objects for each
normal table in the cluster. When replication between clusters is supported
it will also use internal triggers.

This parameter sets the maximum number of trigger objects in the cluster.

The default value of this parameter is 768.

@item [DB]MaxNoOfIndexes
This parameter was deprecated in MySQL 4.1.5. Now you should use
@code{MaxNoOfOrderedIndexes} and @code{MaxNoOfUniqueHashIndexes} instead.

This parameter is only used by unique hash indexes. There needs to be one
record in this pool for each unique hash index defined in the cluster.

The default value of this parameter is 128.
@end table

There is a set of boolean parameters affecting the behavior of storage
nodes. Boolean parameters can be specified to true by setting it to Y or 1
and to false by setting it to N or 0.

@table @code
@item [DB]LockPagesInMainMemory
For a number of operating systems such as Solaris and Linux it is possible
to lock a process into memory and avoid all swapping problems. This is an
important feature to provide real-time characteristics of the cluster.

The default is that this feature is not enabled.

@item [DB]StopOnError
This parameter states whether the process is to exit on error condition or
whether it is perform an automatic restart.

The default is that this feature is enabled.

@item [DB]Diskless
In the internal interfaces it is possible to set tables as diskless tables
meaning that the tables are not checkpointed to disk and no logging occur.
They only exist in main memory. The tables will still exist after a crash
but not the records in the table.

This feature makes the entire cluster @code{Diskless}, in this case even
the tables doesn't exist anymore after a crash. Enabling this feature can
be done by either setting it to Y or 1.

When this feature is enabled, backups will be performed but will not be
stored because there is no "disk". In future releases it is likely to make
the backup diskless a separate configurable parameter.

The default is that this feature is not enabled.

@item [DB]RestartOnErrorInsert
This feature is only accessible when building the debug version where it is
possible to insert errors in the execution of various code parts to test
failure cases.

The default is that this feature is not enabled.
@end table

There are quite a few parameters specifying timeouts and time intervals
between various actions in the storage nodes. Most of the timeouts are
specified in milliseconds with a few exceptions which will be mentioned
below.

@table @code
@item [DB]TimeBetweenWatchDogCheck
To ensure that the main thread doesn't get stuck in an eternal loop
somewhere there is a watch dog thread which checks the main thread. This
parameter states the number of milliseconds between each check. After three
checks and still being in the same state the process is stopped by the
watch dog thread.

This parameter can easily be changed and can be different in the nodes
although there seems to be little reason for such a difference.

The default timeout is 4000 milliseconds (4 seconds).

@item [DB]StartPartialTimeout
This parameter specifies the time that the cluster will wait for all
storage nodes to come up before the algorithm to start the cluster is
invocated. This time out is used to avoid starting only a partial cluster
if possible.

The default value is 30000 milliseconds (30 seconds). 0 means eternal time
out. Thus only start if all nodes are available.

@item [DB]StartPartitionedTimeout
If the cluster is ready start after waiting @code{StartPartialTimeout} but
is still in a possibly partitioned state one waits until also this timeout
has passed.

The default timeout is 60000 milliseconds (60 seconds).

@item [DB]StartFailureTimeout
If the start is not completed within the time specified by this parameter
the node start will fail. Setting this parameter to 0 means no time out is
applied on the time to start the cluster.

The default value is 60000 milliseconds (60 seconds). For storage nodes
containing large data sets this parameter needs to be increased because it
could very well take 10-15 minutes to perform a node restart of a storage
node with a few gigabytes of data.

@item [DB]HeartbeatIntervalDbDb
One of the main methods of discovering failed nodes is by heartbeats. This
parameter states how often heartbeat signals are sent and how often to
expect to receive them. After missing three heartbeat intervals in a row,
the node is declared dead. Thus the maximum time of discovering a failure
through the heartbeat mechanism is four times the heartbeat interval.

The default heartbeat interval is 1500 milliseconds (1.5 seconds). This
parameter must not be changed drastically. If one node uses 5000
milliseconds and the node watching it uses 1000 milliseconds then obviously
the node will be declared dead very quickly. So this parameter can be
changed in small steps during an online software upgrade but not in large 
steps.

@item [DB]HeartbeatIntervalDbApi
In a similar manner each storage node sends heartbeats to each of the
connected MySQL servers to ensure that they behave properly. If a MySQL
server doesn't send a heartbeat in time (same algorithm as for storage node
with three heartbeats missed causing failure) it is declared down and all
ongoing transactions will be completed and all resources will be released
and the MySQL server cannot reconnect until the completion of all
activities started by the previous MySQL instance has been completed.

The default interval is 1500 milliseconds. This interval can be different
in the storage node because each storage node independently of all other
storage nodes watches the MySQL servers connected to it.

@item [DB]TimeBetweenLocalCheckpoints
This parameter is an exception in that it doesn't state any time to wait
before starting a new local checkpoint. This parameter is used to ensure
that in a cluster where not so many updates are taking place that we don't
perform local checkpoints. In most clusters with high update rates it is
likely that a new local checkpoint is started immediately after the
previous was completed. 

The size of all write operations executed since the start of the previous
local checkpoints is added.  This parameter is specified as the logarithm
of the number of words. So the default value 20 means 4MB of write
operations, 21 would mean 8MB and so forth up until the maximum value
31 which means 8GB of write operations.

All the write operations in the cluster are added together.  Setting it to
6 or lower means that local checkpoints will execute continuosly without
any wait between them independent of the workload in the cluster.

@item [DB]TimeBetweenGlobalCheckpoints
When a transaction is committed it is committed in main memory in all nodes
where mirrors of the data existed. The log records of the transaction are
not forced to disk as part of the commit however. The reasoning here is
that having the transaction safely committed in at least two independent
computers should be meeting standards of durability.

At the same time it is also important to ensure that even the worst of
cases when the cluster completely crashes is handled properly. To ensure
this all transactions in a certain interval is put into a global
checkpoint. A global checkpoint is very similar to a grouped commit of
transactions. An entire group of transactions is sent to disk. Thus as part
of the commit the transaction was put into a global checkpoint group. Later
this groups log records are forced to disk and then the entire group of
transaction is safely committed also on all computers disk storage as well.

This parameter states the interval between global checkpoints. The default
time is 2000 milliseconds.

@item [DB]TimeBetweenInactiveTransactionAbortCheck
Time-out handling is performed by checking each timer on each transaction
every period of time in accordance with this parameter. Thus if this
parameter is set to 1000 milliseconds, then every transaction will be
checked for timeout once every second.

The default for this parameter is 1000 milliseconds (1 second). 

@item [DB]TransactionInactiveTimeout
If the transaction is currently not performing any queries but is waiting
for further user input, this parameter states the maximum time that the
  user can wait before the transaction is aborted.

The default for this parameter is no timeout. For a real-time database
that needs to control that no transaction keeps locks for a too long time
this parameter should be set to a much smaller value. The unit is
milliseconds.

@item [DB]TransactionDeadlockDetectionTimeout
When a transactioon is involved in executing a query it waits for other
nodes. If the other nodes doesn't respond it could depend on three things.
First, the node could be dead, second the operation could have entered a
lock queue and finally the node requested to perform the action could be
heavily overloaded.  This timeout parameter states how long the
transaction coordinator will wait until it aborts the transaction when
waiting for query execution of another node.

Thus this parameter is important both for node failure handling and for
deadlock detection. Setting it too high would cause a non-desirable
behavior at deadlocks and node failures.

The default time out is 1200 milliseconds (1.2 seconds).

@item [DB]NoOfDiskPagesToDiskAfterRestartTUP
When executing a local checkpoint the algorithm sends all data pages to
disk during the local checkpoint.  Simply sending them there as quickly as
possible will cause unnecessary load on both processors, networks, and
disks. Thus to control the write speed this parameter specifies how many
pages per 100 milliseconds is to be written. A page is here defined as 8KB.
The unit this parameter is specified in is thus 80KB per
second. So setting it to 20 means writing 1.6MB of data pages to disk
per second during a local checkpoint. Also writing of UNDO log records for
data pages is part of this sum. Writing of index pages (see IndexMemory to
understand what index pages are used for) and their UNDO log records is
handled by the parameter @code{NoOfDiskPagesToDiskAfterRestartACC}. This
parameter handles the limitation of writes from the @code{DataMemory}.

So this parameter specifies how quickly local checkpoints will be executed.
This parameter is important in connection with @code{NoOfFragmentLogFiles},
@code{DataMemory}, @code{IndexMemory}.
@c The interaction between those parameters and possible strategies for
@c choosing them will be shown in @ref{MySQL Cluster Complex Configuration}.

The default value is 40 (3.2MB of data pages per second). 

@item [DB]NoOfDiskPagesToDiskAfterRestartACC
This parameter has the same unit as
@code{NoOfDiskPagesToDiskAfterRestartTUP} but limits the speed of writing
index pages from @code{IndexMemory}.

The default value of this parameter is 20 (1.6MB per second).

@item [DB]NoOfDiskPagesToDiskDuringRestartTUP
This parameter specifies the same things as
@code{NoOfDiskPagesToDiskAfterRestartTUP} and
@code{NoOfDiskPagesToDiskAfterRestartACC}, only it does it for local
checkpoints executed in the node as part of a local checkpoint when the
node is restarting. As part of all node restarts a local checkpoint is
always performed. Since during a node restart it is possible to use a
higher speed of writing to disk because fewer activities are performed in the
node due to the restart phase.

This parameter handles the @code{DataMemory} part.

The default value is 40 (3.2MB per second).

@item [DB]NoOfDiskPagesToDiskDuringRestartACC
During Restart for @code{IndexMemory} part of local checkpoint.

The default value is 20 (1.6MB per second).

@item [DB]ArbitrationTimeout
This parameter specifies the time that the storage node will wait for a
response from the arbitrator when sending an arbitration message in the
case of a split network.

The default value is 1000 milliseconds (1 second).
@end table

A number of new configuration parameters were introduced in MySQL 4.1.5.
These correspond to values that
previously were compile time parameters. The main reason for this is to
enable the advanced user to have more control of the size of the process
and adjust various buffer sizes according to his needs.

All of these buffers are used as front-ends to the file system when
writing log records of various kinds to disk. If the node runs with
Diskless then these parameters can most definitely be set to their
minimum values because all disk writes are faked as okay by the file system
abstraction layer in the @code{NDB} storage engine.

@table @code
@item [DB]UndoIndexBuffer
This buffer is used during local checkpoints. The @code{NDB} storage engine
uses a recovery scheme based on a consistent checkpoint together with an
operational REDO log. In order to produce a consistent checkpoint without
blocking the entire system for writes, UNDO logging is done while performing
the local checkpoint. The UNDO logging is only activated on one fragment of
one table at a time. This optimization is possible because tables are
entirely stored in main memory.

This buffer is used for the updates on the primary key hash index. Inserts
and deletes rearrange the hash index and the @code{NDB} storage engine writes
UNDO log records that map all physical changes to an index page such that
they can be undone at a system restart. It also logs all active insert
operations at the start of a local checkpoint for the fragment.

Reads and updates only set lock bits and update a header in the hash index
entry. These changes are handled by the page write algorithm to ensure that
these operations need no UNDO logging.

This buffer is 2MB by default. The minimum value is 1MB. For most
applications this is good enough. Applications doing extremely heavy inserts
and deletes together with large transactions using large primary keys
might need to extend this buffer.

If this buffer is too small, the @code{NDB} storage engine issues the internal
error code 677 which will be translated into "Index UNDO buffers overloaded".

@item [DB]UndoDataBuffer
This buffer has exactly the same role as the @code{UndoIndexBuffer} but is
used for the data part. This buffer is used during local checkpoint of a
fragment and inserts, deletes, and updates use the buffer.

Since these UNDO log entries tend to be bigger and more things are logged,
the buffer is also bigger by default. It is set to 16MB by default.
For some applications this might be too conservative and they might want
to decrease this size, the minimum size is 1MB. It should be rare that
applications need to increase this buffer size. If there is a need for this
it is a good idea to check if the disks can actually handle the load that
the update activity in the database causes. If they cannot then no size of
this buffer will be big enough.

If this buffer is too small and gets congested, the @code{NDB} storage engine 
issues the internal error code 891 which will be translated to
"Data UNDO buffers overloaded".

@item [DB]RedoBuffer
All update activities also need to be logged. This enables a replay of these
updates at system restart. The recovery algorithm uses a consistent
checkpoint produced by a "fuzzy" checkpoint of the data together with UNDO
logging of the pages. Then it applies the REDO log to play back all changes
up until the time that will be restored in the system restart.

This buffer is 8MB by default. The minimum value is 1MB.

If this buffer is too small, the @code{NDB} storage engine issues the internal
error code 1221 which will be translated into "REDO log buffers overloaded".
@end table

For cluster management, it is important to be able to control the
amount of log messages sent to stdout for various event types. The possible
events will be listed in this manual soon.  There are 16 levels possible
from level 0 to level 15. Setting event reporting to level 15 means
receiving all event reports of that category and setting it to 0 means
getting no event reports in that category.

The reason why most defaults are set to 0 and thus not causing any output
to stdout is that the same message is sent to the cluster log in the
management server. Only the startup message is by default generated to
stdout.

A similar set of levels can be set in management client to define what
levels to record in the cluster log.

@table @code
@item [DB]LogLevelStartup
Events generated during startup of the process.

The default level is 1.

@item [DB]LogLevelShutdown
Events generated as part of graceful shutdown of a node.

The default level is 0.

@item [DB]LogLevelStatistic
Statistical events such as how many primary key reads, updates, inserts and
many other statistical information of buffer usage, and so forth.

The default level is 0.

@item [DB]LogLevelCheckpoint
Events generated by local and global checkpoints.

The default level is 0.

@item [DB]LogLevelNodeRestart
Events generated during node restart.

The default level is 0.

@item [DB]LogLevelConnection
Events generated by connections between nodes in the cluster.

The default level is 0.

@item [DB]LogLevelError
Events generated by errors and warnings in the cluster. These are errors
not causing a node failure but still considered worth reporting.

The default level is 0.

@item [DB]LogLevelInfo
Events generated for information about state of cluster and so forth.

The default level is 0.
@end table

There is a set of parameters defining memory buffers that are set aside for
online backup execution.

@table @code
@item [DB]BackupDataBufferSize
When executing a backup there are two buffers used for sending data to the
disk. This buffer is used to fill in data recorded by scanning the tables
in the node. When filling this to a certain level the pages are sent to
disk. This level is specified by the @code{BackupWriteSize} parameter.
When sending data to the disk, the backup can continue filling this buffer
until it runs out of buffer space. When running out of buffer space, it will
simply stop the scan and wait until some disk writes return and thus free
up memory buffers to use for further scanning.

The default value is 2MB.

@item [DB]BackupLogBufferSize
This parameter has a similar role but instead used for writing a log of all
writes to the tables during execution of the backup. The same principles
apply for writing those pages as for @code{BackupDataBufferSize} except
that when this part runs out of buffer space, it causes the backup to
fail due to lack of backup buffers. Thus the size of this buffer must be
big enough to handle the load caused by write activities during the backup
execution.

The default parameter should be big enough. Actually it is more likely that
a backup failure is caused by a disk not able to write as quickly as it
should. If the disk subsystem is not dimensioned for the write load caused
by the applications this will create a cluster which will have great
difficulties to perform the desired actions.

It is important to dimension the nodes in such a manner that the processors
becomes the bottleneck rather than the disks or the network connections.

The default value is 2MB.

@item [DB]BackupMemory
This parameter is simply the sum of the two previous, the
@code{BackupDataBufferSize} and @code{BackupLogBufferSize}.

The default value is 4MB.

@item [DB]BackupWriteSize
This parameter specifies the size of the write messages to disk for the log
and data buffer used for backups.

The default value is 32KB.
@end table


@node MySQL Cluster API Definition, MySQL Cluster TCP Definition, MySQL Cluster DB Definition, MySQL Cluster Config File
@subsubsection Defining the MySQL Servers for a MySQL Cluster

The @code{[API]} section (with its alias @code{[MYSQLD]}) defines the
behavior of the MySQL server. No parameter is mandatory. If no computer or
host name is provided, then any host can use this API node.

@table @code
@item [API]Id
This identity is the node ID used as the address of the node in all cluster
internal messages. This is an integer between 1 and 63. Each node in the
cluster must have a unique identity.

@item [API]ExecuteOnComputer
This is referring to one of the computers defined in the computer section.

@item [API]ArbitrationRank
This parameter is used to define which nodes can act as an arbitrator. MGM
nodes and API nodes can be arbitrators. 0 means it isn't used as
arbitrator, 1 high priority and 2 low priority. A normal configuration uses
the management server as arbitrator setting the ArbitrationRank to 1 (which
is the default) and setting all APIs to 0.

@item [API]ArbitrationDelay
If setting this to anything else than 0 it means that the management server
will delay responses to the arbitration requests. Default is no delay and
this should not be necessary to change.
@item [API]BatchByteSize
For queries that get translated into full table scans or range scans on
indexes, it is important for best performance to fetch records in properly
sized batches. It is possible to set the proper size both in terms of
number of records and in terms of bytes. Real batch size will be limited
by both parameters.

Performance of queries can vary more than 40% due to how this parameter is
set. In future releases, the MySQL Server will make educated guesses on
what to set these parameters to, based on the query type.

This parameter is measured in bytes and is by default equal to 32KB.
@item [API]BatchSize
This parameter is measured in number of records and is by default set to
64. The maximum size is 992.
@item [API]MaxScanBatchSize
The batch size is the size of each batch sent from each storage node. Most
scans are performed in parallel so to protect the MySQL Server from getting
too much data from many nodes in parallel, this parameter sets a limit to
the total batch size over all nodes.

The default value of this parameter is set to 256KB. Its maximum size
is 16MB.
@end table


@node MySQL Cluster TCP Definition, MySQL Cluster SHM Definition, MySQL Cluster API Definition, MySQL Cluster Config File
@subsubsection MySQL Cluster TCP/IP Connections

TCP/IP is the default transport mechanism for establishing connections in
MySQL Cluster. It
is actually not necessary to define any connection because there will be a
one connection setup between each of the storage nodes, between each
storage node, and all MySQL server nodes and between each storage node and
the management server.

It is only necessary to define a connection if it is necessary to change
the default values of the connection.  In that case it is necessary to
define at least @code{NodeId1}, @code{NodeId2} and the parameters to
change.

It is also possible to change the default values by setting the parameters
in the @code{[TCP DEFAULT]} section.

@table @code
@item [TCP]NodeId1
@item [TCP]NodeId2
To identify a connection between two nodes it is necessary to provide the
node identity for both of them in @code{NodeId1} and @code{NodeId2}.

@item [TCP]SendBufferMemory
TCP transporters use a buffer all messages before performing the send call
to the operating system. When this buffer reaches 64KB it sends the
buffer, the buffer is also sent when a round of messages have been
executed. To handle temporary overload situations it is also possible to
define a bigger send buffer.  The default size of the send buffer is 256KB.

@item [TCP]SendSignalId
To be able to retrace a distributed message diagram it is necessary to
identify each message with an identity. By setting this parameter to Y
these message identities are also transported over the network.  This
feature is not enabled by default.

@item [TCP]Checksum
This parameter is also a Y/N parameter which is not enabled by default.
When enabled all messages are checksummed before put into the send buffer.
This feature enables control that messages are not corrupted while waiting
in the send buffer. It is also a double check that the transport mechanism
haven't corrupted the data.

@item [TCP]PortNumber
This is the port number to use for listening to connections from other
nodes. This port number should be specified in the @code{[TCP DEFAULT]} section
normally.

This parameter should no longer be used. Use the parameter ServerPort on
storage nodes instead.

@item [TCP]ReceiveBufferMemory
This parameter specifies the size of the buffer used when receiving data
from the TCP/IP socket. There is seldom any need to change this parameter
from its default value of 64KB. One possible reason could be to save memory.
@end table


@node MySQL Cluster SHM Definition, MySQL Cluster SCI Definition, MySQL Cluster TCP Definition, MySQL Cluster Config File
@subsubsection MySQL Cluster Shared-Memory Connections

Shared memory segments are currently supported only for special builds of
MySQL Cluster using the @command{configure} parameter @code{--with-ndb-shm}. Its
implementation will most likely change. When defining shared memory as the
connection method it is necessary to define at least @code{NodeId1},
@code{NodeId2} and @code{ShmKey}. All other parameters have default values
that will work out fine in most cases.

@table @code
@item [SHM]NodeId1
@item [SHM]NodeId2
To identify a connection between two nodes it is necessary to provide the
node identity for both of them in @code{NodeId1} and @code{NodeId2}.

@item [SHM]ShmKey
When setting up shared memory segments an identifier is used to uniquely
identify the shared memory segment to use for the communication. This is an
integer which does not have a default value.

@item [SHM]ShmSize
Each connection has a shared memory segment where messages between the
nodes are put by the sender and read by the reader. This segment has a size
defined by this parameter. Default value is 1MB.

@item [SHM]SendSignalId
To be able to retrace a distributed message diagram it is necessary to
identify each message with an identity. By setting this parameter to Y
these message identities are also transported over the network.  This
feature is not enabled by default.

@item [SHM]Checksum
This parameter is also a Y/N parameter which is not enabled by default.
When enabled all messages are checksummed before put into the send buffer.
This feature enables control that messages are not corrupted while waiting
in the send buffer. It is also a double check that the transport mechanism
haven't corrupted the data.
@end table

@node MySQL Cluster SCI Definition,  , MySQL Cluster SHM Definition, MySQL Cluster Config File
@subsubsection MySQL Cluster SCI Transport Connections

SCI Transporters as connection between nodes in the MySQL Cluster is only
supported for special builds of MySQL Cluster using the @command{configure}
parameter @code{--with-ndb-sci=/your/path/to/SCI}. The path should point
to a directory that contains at least a lib and a include directory where
SISCI libraries and header files are provided.

It is strongly recommended to only use SCI Transporters for communication
between ndbd processes. Also using SCI Transporters will mean that the
ndbd process will never sleep so use SCI Transporters only for machines
with at least 2 CPU's which are dedicated for use by ndbd process(es). There
should be at least 1 CPU per ndbd process in this case and in addition at 
least one more is needed to also handle OS activities.

@table @code
@item [SCI]NodeId1
@item [SCI]NodeId2
To identify a connection between two nodes it is necessary to provide the
node identity for both of them in @code{NodeId1} and @code{NodeId2}.

@item [SCI]Host1SciId0
This identifies the SCI node id on the first node identified by NodeId1.

@item [SCI]Host1SciId1
It is possible to set-up SCI Transporters for fail-over between two SCI
cards which then should use separate networks between the nodes. This
identifies the node id and the second SCI card to be used on the first
node.

@item [SCI]Host2SciId0
This identifies the SCI node id on the second node identified by NodeId2.

@item [SCI]Host2SciId1
It is possible to set-up SCI Transporters for fail-over between two SCI
cards which then should use separate networks between the nodes. This
identifies the node id and the second SCI card to be used on the second
node.

@item [SCI]SharedBufferSize
Each SCI transporter has a shared memory segment between the two nodes. With
this segment set to the default 1 MB most applications should be ok. Smaller
sizes such as 256 kB has problems when performing many parallel inserts.
If the buffer is too small it can cause crashes of the ndbd process.

@item [SCI]SendLimit
A small buffer in front of the SCI media buffers up messages before sending
them over the SCI network. By default this is set to 8kB. Most benchmark
measurements shows that tops are reached at 64 kB but 16kB reaches within a
few percent of the performance and for all MySQL Cluster benchmarks it was
no measurable difference in increasing it beyond 8kB.

@item [SCI]SendSignalId
To be able to retrace a distributed message diagram it is necessary to
identify each message with an identity. By setting this parameter to Y
these message identities are also transported over the network.  This
feature is not enabled by default.

@item [SCI]Checksum
This parameter is also a Y/N parameter which is not enabled by default.
When enabled all messages are checksummed before put into the send buffer.
This feature enables control that messages are not corrupted while waiting
in the send buffer. It is also a double check that the transport mechanism
haven't corrupted the data.
@end table

@c @node MySQL Cluster Complex Configuration,  , MySQL Cluster SHM Definition, MySQL Cluster Config File
@c @subsubsection Configuring Pecovery Parts in a MySQL Cluster


@node MySQL Cluster Process Management, MySQL Cluster Management, MySQL Cluster Configuration, NDBCluster
@section Process Management in MySQL Cluster

There are four processes that are important to know about when using MySQL
Cluster. We will cover how to work with those processes, which options to
use when starting and so forth.

@menu
* mysqld process::              MySQL Server Process Usage for MySQL Cluster
* ndbd process::                @command{ndbd}, the Storage Engine Node Process
* ndb_mgmd process::            @command{ndb_mgmd}, the Management Server Process
* ndb_mgm process::             @command{ndb_mgm}, the Management Client Process
* MySQL Cluster Command Options::  Command Options for MySQL Cluster Processes
@end menu


@node mysqld process, ndbd process, MySQL Cluster Process Management, MySQL Cluster Process Management
@subsection MySQL Server Process Usage for MySQL Cluster

@command{mysqld} is the traditional MySQL server process. To be used with
MySQL Cluster it needs to be built with support for the NDB Cluster storage
engine. If the @command{mysqld} binary has been built in such a manner, the
NDB Cluster storage engine is still disabled by default.

To enable the NDB Cluster storage engine there are two ways. Either use
@code{--ndbcluster} as a startup option when starting @command{mysqld} or
insert a line with @code{ndbcluster} in the @code{[mysqld]} section of your
@file{my.cnf} file.
An easy way to verify that your server runs with support for the
@code{NDB Cluster} storage engine is to issue the command
@code{SHOW ENGINES} from a @command{mysql} client.
You should see @code{YES} for the row listing @code{NDBCLUSTER}.
If you see @code{NO}, you are not running a @command{mysqld} that is compiled
with @code{NDB Cluster} support enabled. If you see @code{DISABLED}, then you
need to enable it in the @file{my.cnf} configuration file.

The MySQL server needs to know how to get the configuration of the cluster.
To access this configuration, it needs to know three things:

@itemize @bullet
@item
Its own node ID in the cluster.
@item
The hostname (or IP address) where the management server resides.
@item
The port on which it can connect to the management server.
@end itemize

The node ID can be skipped from MySQL 4.1.5 on, because a node ID can be
dynamically allocated.

The @code{mysqld} parameter @code{ndb-connectstring} is used to specify the
connectstring either when starting @code{mysqld} or in @file{my.cnf}.
See also @ref{MySQL Cluster Connectstring} for more info on connectstrings.

@example
shell> mysqld --ndb-connectstring=ndb_mgmd.mysql.com:1186
@end example

@code{ndb_mgmd.mysql.com} is the host where the management server resides,
and it is listening to port 1186.

With this setup the MySQL server will be a full citizen of MySQL Cluster
and will be fully aware of all storage nodes in the cluster and their
status. It will setup connection to all storage nodes and will be
able to use any storage node as a transaction coordinator and to
access their data for reading and updating.


@node ndbd process, ndb_mgmd process, mysqld process, MySQL Cluster Process Management
@subsection @command{ndbd}, the Storage Engine Node Process

@command{ndbd} is the process that is used to handle all the data in the
tables using the NDB Cluster storage engine. This is the process that
contains all the logic of distributed transaction handling, node recovery,
checkpointing to disk, online backup, and lots of other functionality.

In a cluster there is a set of @command{ndbd} processes cooperating in
handling the data. These processes can execute on the same computer or on
different computers, in a completely configurable manner.

Before MySQL 4.1.5, @command{ndbd} process should start from a separate
directory. The reason for this was that @command{ndbd} generates a set of log
files in its starting directory.

In MySQL 4.1.5, this was changed such that the files are placed in the
directory specified by @code{DataDir} in the configuration file. Thus
@command{ndbd} can be started from anywhere.

These log files are (the 2 is the node ID):

@itemize @bullet
@item
@var{ndb_2_error.log} (was @file{error.log} in version 4.1.3) is a file that
contains information of all the crashes which the @command{ndbd} process has
encountered and a smaller error string and reference to a trace file for
this crash. An entry could like this:

@example
Date/Time: Saturday 31 January 2004 - 00:20:01
Type of error: error
Message: Internal program error (failed ndbrequire)
Fault ID: 2341
Problem data: DbtupFixAlloc.cpp
Object of reference: DBTUP (Line: 173)
ProgramName: NDB Kernel
ProcessID: 14909
TraceFile: ndb_2_trace.log.2
***EOM***
@end example

@item
@file{ndb_2_trace.log.1} (was @file{NDB_TraceFile_1.trace} in version 4.1.3) is a
trace file describing exactly what
happened before the error occurred. This information is useful for the
MySQL Cluster team when analysing any bugs occurring in MySQL Cluster. The
information in this file will be described in the section @code{MySQL
Cluster Troubleshooting}. There can be a configurable number of those trace
files in the directory before old files are overwritten. 1 in this context
is simply the number of the trace file.

@item
@file{ndb_2_trace.log.next} (was @file{NextTraceFileNo.log} in version
4.1.3) is the file that keeps track of what the next trace file number
is to be.

@item
@file{ndb_2_out.log} is the file which
contains any data printed by the @command{ndbd} process. 2 in this context
is the node ID. (this file only applies if @command{ndbd} is started in dameon mode
which is default from 4.1.5, was @file{node2.out} in version 4.1.3)

@item
@file{ndb_2.pid} is a file containing
the process id of the ndbd when started as a daemon (default from 4.1.5 and
named @file{node2.pid} in version 4.1.3). It also functions as a lock file to
avoid the starting of nodes with the same id.

@item
@file{ndb_2_signal.log} (was @file{Signal.log} in version 4.1.3) is a file
which is only used in debug versions of @command{ndbd} where it is possible to
trace all incoming, outgoing and internal messages with their data in the
@command{ndbd} process.

@end itemize

It is recommended to not use a directory mounted through NFS because in some
environments that can cause problems with the lock on the pid-file remaining
even after the process has stopped.

Also when starting the @command{ndbd} process it may be necessary to specify
the hostname of the management server and the port it is listening to,
optionally one may specify node ID the process is to use, 
see @ref{MySQL Cluster Connectstring}.

@example
shell> ndbd --connect-string="nodeid=2;host=ndb_mgmd.mysql.com:1186"
@end example

When @command{ndbd} starts it will actually start two processes. The starting
process is called the "angel" and its only job is to discover when the
execution process has completed, and then restart the @command{ndbd} process if
configured to do so.  Thus if one attempts to kill @command{ndbd} through the
@command{kill} command in Unix, it is necessary to kill both processes.  A
more proper way to handle the stopping of @command{ndbd} processes is to use
the management client and stop the process from there.

The execution process uses one thread for all activities in reading,
writing, and scanning data and all other activities. This thread is designed
with asynchronous programming so it can easily handle thousands of
concurrent activites. In addition there is a watch-dog thread supervising
the execution thread to ensure it doesn't stop in an eternal loop or other
problem. There is a pool of threads handling file I/O. Each thread can
handle one open file. In addition threads can be used for connection
activities of the transporters in the @command{ndbd} process. Thus in a system
that performs a large number of activities including update activities the
@command{ndbd} process will consume up to about 2 CPUs if allowed to. Thus in
a large SMP box with many CPUs it is recommended to use several
@command{ndbd} processes which are configured to be part of different node
groups.

@node ndb_mgmd process, ndb_mgm process, ndbd process, MySQL Cluster Process Management
@subsection @command{ndb_mgmd}, the Management Server Process

The management server is the process that reads the configuration file of
the cluster and distributes this information to all nodes in the cluster
requesting it. It also maintains the log of cluster activities.
Management clients can connect to the management server and use commands to
check status of the cluster in various aspects.

As of MySQL 4.1.5, it is no longer necessary to specify a connectstring 
when starting the management server. However, if you are using several 
management servers, a connectstring should be provided and each node in 
the cluster should specify its nodeid explicitly.

The following files are created or used by @command{ndb_mgmd} in its starting
directory of @command{ndb_mgmd}. From MySQL 4.1.5, the log and PID files will
be placed in the @code{DataDir} specified in the configuration file:

@itemize @bullet
@item
@file{config.ini} is the configuration file of the cluster. This is created
by the user and read by the management server. How to write this file is
described in the section @code{MySQL Cluster Configuration}.

@item
@file{ndb_1_cluster.log} (was @file{cluster.log} in version 4.1.3) is the
file where events in the cluster are reported.
Examples of events are checkpoints started and completed, node failures and
nodes starting, levels of memory usage passed and so forth. The events
reported are described in the section @ref{MySQL Cluster Management}.

@item
@file{ndb_1_out.log} (was @file{node1.out} in version 4.1.3) is the file used
for stdout and stderr when executing the
management server as a daemon process. 1 in this context is the node ID.

@item
@file{ndb_1.pid} (was @file{node1.pid} in version 4.1.3) is the PID file used
when executing the management server as a daemon process. 1 in this context
is the node ID.

@item
@file{ndb_1_cluster.log.1} (was @file{cluster.log.1} in version 4.1.3) when
the cluster log becomes bigger than one million
bytes then the file is renamed to this name where 1 is the number
of the cluster log file, so if 1, 2, and 3 already exists the next will be
having the number 4 instead.
@end itemize


@node ndb_mgm process, MySQL Cluster Command Options, ndb_mgmd process, MySQL Cluster Process Management
@subsection @command{ndb_mgm}, the Management Client Process

The final important process to know about is the management client. This
process is not needed to run the cluster. Its value lies in its ability to
check status of the cluster, start backups, and perform other management
activities.  It does so by providing access to a set of commands.

Actually the management client is using a C API that is used to access the
management server so for advanced users it is also possible to program
dedicated management processes which can do similar things as the
management client can do.

When starting the management client, it is necessary to state the hostname
and port of the management server as in the example below. The default is
localhost as host and port number 1186 (was 2200 prior to version 4.1.8).

@example
shell> ndb_mgm localhost 1186
@end example

@node MySQL Cluster Command Options,  , ndb_mgm process, MySQL Cluster Process Management
@subsection Command Options for MySQL Cluster Processes

@menu
* new mysqld command options::  MySQL Cluster-Related Command Options for @command{mysqld}
* ndbd command options::        Command Options for @command{ndbd}
* ndb_mgmd command options::    Command Options for @command{ndb_mgmd}
* ndb_mgm command options::     Command Options for @command{ndb_mgm}
@end menu


All MySQL Cluster executables (except @command{mysqld}) takes the 
following options as of 4.1.8. If you're running an earlier version 
please read carefully, as we have made changes in some of these 
switches in order to make them consistent between the different 
executables and with @command{mysqld}. (For example: @code{-V} was 
@code{-v} in earlier versions.) Note also that you can use the 
@code{-?} option to see what is supported in your version.

@table @code

@item -?, --usage, --help
Prints a short description of the available command options.

@item -V, --version
Prints the version number of the @command{ndbd} process. The version number is
the MySQL Cluster version number. It is important because at
startup the MySQL Cluster processes verifies that the versions of the
processes in the cluster can co-exist in the cluster. It is also important
for online software upgrade of MySQL Cluster (see section
@code{Software Upgrade of MySQL Cluster}).

@item -c @var{connect_string} (not @command{ndb_mgmd}), --connect-string @var{connect_string}
Set the connect string to the management server as a command option.
(for backwards compatability reasons the @command{ndb_mgmd} does not take 
the -c option until 5.0, as it currently specifies the config file). 
Available with @command{ndb_mgm} from 4.1.8.

@example
shell> ndbd --connect-string="nodeid=2;host=ndb_mgmd.mysql.com:1186"
@end example

@item --debug[=@var{options}]
This can only be used for versions compiled with debug information. It is
used to enable printouts from debug calls in the same manner as for the
@command{mysqld} process.

@end table


@node new mysqld command options, ndbd command options, MySQL Cluster Command Options, MySQL Cluster Command Options
@subsubsection MySQL Cluster-Related Command Options for @command{mysqld}

@table @code
@item --ndbcluster
If the binary includes support for the @code{NDB Cluster} storage engine the
default disabling of support for the @code{NDB} storage engine can be
overruled by using this option. Using the @code{NDB Cluster} storage engine
is necessary for using MySQL Cluster.

@item --skip-ndbcluster
Disable the @code{NDB Cluster} storage engine. This is disabled by default
for binaries where it is included. So this option only applies if the
server was configured to use the @code{NDB Cluster} storage engine.

@item --ndb-connectstring=@var{connect_string}
When using the @code{NDB} storage engine, it is possible to point out the
management server that distributes the cluster configuration by setting the
connect string option.
@end table

@node ndbd command options, ndb_mgmd command options, new mysqld command options, MySQL Cluster Command Options
@subsubsection Command Options for @command{ndbd}

For common options see @ref{MySQL Cluster Command Options}.

@table @code

@item -d, --daemon
Instructs @command{ndbd} to execute as a daemon process. From MySQL 4.1.5 on, this
is the default behavior.

@item --nodaemon
Instructs @command{ndbd} not to start as a daemon process. Useful when
@command{ndbd} is debugged and one wants printouts on the screen.

@item --initial
Instructs @command{ndbd} to perform an initial start. An initial start will
erase any files created by earlier @command{ndbd} instances for recovery. It
will also recreate recovery log files which on some operating systems can
take a substantial amount of time.

An initial start is only to be used at the very first start of the
@command{ndbd} process. It removes all files from the file system and
creates all REDO log files. When performing a software upgrade which has
changed the file contents on any files it is also necessary to use this
option when restarting the node with a new software version of
@command{ndbd}. Finally it could also be used as a final resort if for some
reason the node restart or system restart doesn't work. In this case be
aware that destroying the contents of the file system means that this node
can no longer be used to restore data.

This option does not affect any backup files created.

The previous possibility to use @code{-i} for this option was removed to
ensure that this option is not used by mistake.

@item --nostart
Instructs @command{ndbd} not to automatically start. @command{ndbd} will connect
to the management server and get the configuration and initialise
communication objects. It will not start the execution engine until
requested to do so by the management server. The management server can
request by command issued by the management client.

@end table

@c TODO: That section doesn't seem to exist?

@node ndb_mgmd command options, ndb_mgm command options, ndbd command options, MySQL Cluster Command Options
@subsubsection Command Options for @command{ndb_mgmd}

For common options see @ref{MySQL Cluster Command Options}.

@table @code

@item -f @var{filename} (from 4.1.8), --config-file=@var{filename}, -c @var{filename} (obsolete from 5.0)
Instructs the management server which file to use as configuration file.
This option must be specified. The file name defaults to @code{config.ini}.

@item -d, --daemon
Instructs @command{ndb_mgmd} to start as a daemon process. This is the
default behavior.

@item -nodaemon
Instructs the management server not to start as a daemon process.

@end table


@node ndb_mgm command options,  , ndb_mgmd command options, MySQL Cluster Command Options
@subsubsection Command Options for @command{ndb_mgm}

For common options see @ref{MySQL Cluster Command Options}.

@table @code

@item [@var{host_name} [@var{port_num}]]
To start the management client it is necessary to specify where the
management server resides. This means specifying the hostname and the port.
The default hostname is @code{localhost} and the default port is 1186 
(was 2200 prior to version 4.1.8).

@item --try-reconnect=@var{number}
If the connection to the management server is broken it is possible to
perform only a specified amount of retries before reporting a fault code to
the user. The default is that it keeps retrying every 5 seconds until it
succeeds.

@end table


@node MySQL Cluster Management, MySQL Cluster Interconnects, MySQL Cluster Process Management, NDBCluster
@section Management of MySQL Cluster

Managing a MySQL Cluster involves a number of activities.
The first activity is to configure and startup MySQL Cluster.
This is covered by the sections @ref{MySQL Cluster Configuration}
and @ref{MySQL Cluster Process Management}.
This section covers how to manage a running MySQL Cluster.

There are essentially two ways of actively managing a running MySQL Cluster.
The first is by commands entered into the management client where status of
cluster can be checked, log levels changed, backups started and stopped and
nodes can be stopped and started. The second method is to study the output
in the cluster log. The cluster log is directed towards the
@file{ndb_2_cluster.log} in the @code{DataDir} directory of the management
server.  The cluster log contains event reports generated from the
@command{ndbd} processes in the cluster. It is also possible to send the
cluster log entries to a Unix system log.


@menu
* mgm client commands::         Commands in the Management Client
* MySQL Cluster Event Reports::  Event Reports Generated in MySQL Cluster
* MySQL Cluster Single User Mode::  Single User Mode
* MySQL Cluster Backup::        On-line Backup of MySQL Cluster
@end menu

@node mgm client commands, MySQL Cluster Event Reports, MySQL Cluster Management, MySQL Cluster Management
@subsection Commands in the Management Client

In addition to the central configuration file, the cluster
may also be controlled through a command line interface. The command
line interface is available through a separate management client process.
This is the main administrative interface to a running cluster.

The management client has the following basic commands.
Below, @code{<id>} denotes either a database node id (e.g. 21) or the
keyword @code{ALL} that indicates that the command should be applied
to all database nodes in the cluster.

@table @asis
@item @code{HELP}
Prints information on all available commands.
@item @code{SHOW}
Prints information on the status of the cluster.
@item @code{<id> START}
Start a database node identified with @code{<id>} or all database nodes.
@item @code{<id> STOP}
Stop a database node identified with @code{<id>} or all database nodes.
@item @code{<id> RESTART [-N] [-I]}
Restart a database node identified with @code{<id>} or all database nodes.
@item @code{<id> STATUS}
Displays status information for database node identified with @code{<id>}
(or @code{ALL} database nodes).
@item @code{ENTER SINGLE USER MODE <id>}
Enters single user mode where only the API with node @code{<id>} is
allowed to access the database system.
@item @code{EXIT SINGLE USER MODE}
Exists single user mode allowing all APIs to access the database system.
@item @code{QUIT}
Terminates the management client.
@item @code{SHUTDOWN}
Shuts down all cluster nodes (except mysql servers) and exits.
@end table

Commands for the event logs are given in the next section and commands
for backup and restore are given in a separate section on these topics.


@node MySQL Cluster Event Reports, MySQL Cluster Single User Mode, mgm client commands, MySQL Cluster Management
@subsection Event Reports Generated in MySQL Cluster

MySQL Cluster has two event logs, the cluster log and the node log.

@itemize @bullet
@item
The cluster log is a log of the whole cluster and this log can have
multiple destinations (file, management server console window or
syslog).
@item
The node log is a log that is local to each database node and is
written to the console window of the database node. The two logs can
be set to log different subsets of the list of events.
@end itemize

Note: The cluster log is the recommended log.  The node log is only
intended to be used during application development or for debugging
application code.

Each reportable event has the following properties:
@itemize @bullet
@item
Category (STARTUP, SHUTDOWN, STATISTICS, CHECKPOINT, NODERESTART,
CONNECTION, ERROR, INFO)
@item
Priority (1-15 where 1 - Most important, 15 - Least important)
@item
Severity (ALERT, CRITICAL, ERROR, WARNING, INFO, DEBUG)
@end itemize

The two logs (the cluster log and the node log) can be filtered on
these properties.


@menu
* MySQL Cluster Logging Management Commands::  Logging Management Commands
* MySQL Cluster Log Events::    Log Events
@end menu

@node MySQL Cluster Logging Management Commands, MySQL Cluster Log Events, MySQL Cluster Event Reports, MySQL Cluster Event Reports
@subsubsection Logging Management Commands

The following management commands are related to the cluster log:

@table @asis
@item @code{CLUSTERLOG ON}
Turn cluster log on.
@item @code{CLUSTERLOG OFF}
Turn cluster log off.
@item @code{CLUSTERLOG INFO}
Information about cluster log settings.
@item @code{<id> CLUSTERLOG <category>=<threshold>}
Log category events with priority less than or equal to threshold in
the cluster log.
@item @code{CLUSTERLOG FILTER <severity>}
Toggles cluster logging of the specified severity type on/off.
@end table

The following table describes the default setting (for all database
nodes) of the cluster log category threshold.  If an event has a
priority with a value lower than or equal to the priority threshold,
then it is reported in the cluster log.

Note that the events are reported per database node and that the
thresholds can be set differently on different nodes.

@multitable @columnfractions .30 .70
@item @strong{Category} @tab @strong{Default threshold (All database nodes)}
@item STARTUP           @tab  7
@item SHUTDOWN          @tab  7
@item STATISTICS        @tab  7
@item CHECKPOINT        @tab  7
@item NODERESTART       @tab  7
@item CONNECTION        @tab  7
@item ERROR             @tab 15
@item INFO              @tab  7
@end multitable

The threshold is used to filter events within each category.
For example: a @code{STARTUP} event with a priority of 3 is never sent
unless the threshold for @code{STARTUP} is changed to 3 or lower.
Only events with priority 3 or lower are sent if the threshold is 3.
The event severities are (corresponds to UNIX syslog levels):

@multitable @columnfractions .5 .10 .50
@item 1 @tab ALERT    @tab A condition that should be corrected immediately, such as a corrupted system database
@item 2 @tab CRITICAL @tab Critical conditions, such as device errors or out of resources
@item 3 @tab ERROR    @tab Conditions that should be corrected, such as configuration errors
@item 4 @tab WARNING  @tab Conditions that are not error conditions but might require handling 
@item 5 @tab INFO     @tab Informational messages
@item 6 @tab DEBUG    @tab Messages used during development of NDB Cluster
@end multitable

Syslog's @code{LOG_EMERG} and @code{LOG_NOTICE} are not used/mapped.

The event severities can be turned on or off.  If the severity is on
then all events with priority less than or equal to the category
thresholds are logged. If the severity is off then no events belonging
to the severity are logged.


The following commands are related to the node log:

@itemize @asis
@item @code{<id> LOGLEVEL <levelnumber>}
Set logging level for database process with @code{id} to the value
of @code{<levelnumber>}.
@end itemize


@node MySQL Cluster Log Events,  , MySQL Cluster Logging Management Commands, MySQL Cluster Event Reports
@subsubsection Log Events

All reportable events are listed below.

@multitable @columnfractions .25 .15 .10 .10 .40
@item @strong{Event} @tab @strong{Category} @tab @strong{Priority} @tab @strong{Severity} @tab @strong{Description}

@item DB nodes connected     @tab CONNECTION @tab  8 @tab INFO  @tab
@item DB nodes disconnected  @tab CONNECTION @tab  8 @tab INFO  @tab
@item Communication closed   @tab CONNECTION @tab  8 @tab INFO  @tab API & DB nodes connection closed 
@item Communication opened   @tab CONNECTION @tab  8 @tab INFO  @tab API & DB nodes connection opened

@item Global checkpoint started           @tab CHECKPOINT @tab  9 @tab INFO  @tab Start of a GCP, i.e., REDO log is written to disk
@item Global checkpoint completed         @tab CHECKPOINT @tab 10 @tab INFO  @tab GCP finished
@item Local checkpoint started            @tab CHECKPOINT @tab  7 @tab INFO  @tab Start of local check pointing, i.e., data is written to disk. LCP Id and GCI Ids (keep and oldest restorable)
@item Local checkpoint completed          @tab CHECKPOINT @tab  8 @tab INFO  @tab LCP finished
@item LCP stopped in calc keep GCI        @tab CHECKPOINT @tab  0 @tab ALERT @tab LCP stopped!
@item Local checkpoint fragment completed @tab CHECKPOINT @tab 11 @tab INFO  @tab A LCP on a fragment has been completed
@item Report undo log blocked             @tab CHECKPOINT @tab  7 @tab INFO  @tab Reports undo logging blocked due buffer near to overflow

@item DB node start phases initiated                        @tab STARTUP @tab  1 @tab INFO @tab NDB Cluster starting
@item DB node all start phases completed                    @tab STARTUP @tab  1 @tab INFO @tab NDB Cluster started
@item Internal start signal received STTORRY                @tab STARTUP @tab 15 @tab INFO @tab Internal start signal to blocks received after restart finished
@item DB node start phase X completed                       @tab STARTUP @tab  4 @tab INFO @tab A start phase has completed
@item Node has been successfully included into the cluster  @tab STARTUP @tab  3 @tab INFO @tab President node, own node and dynamic id is shown
@item Node has been refused to be included into the cluster @tab STARTUP @tab  8 @tab INFO @tab 
@item DB node neighbours                                    @tab STARTUP @tab  8 @tab INFO @tab Show left and right DB nodes neighbours
@item DB node shutdown initiated                            @tab STARTUP @tab  1 @tab INFO @tab 
@item DB node shutdown aborted                              @tab STARTUP @tab  1 @tab INFO @tab 
@item New REDO log started                                  @tab STARTUP @tab 10 @tab INFO @tab GCI keep X, newest restorable GCI Y
@item New log started                                       @tab STARTUP @tab 10 @tab INFO @tab Log part X, start MB Y, stop MB Z
@item Undo records executed                                 @tab STARTUP @tab 15 @tab INFO @tab 

@item Completed copying of dictionary information           @tab NODERESTART @tab  8 @tab INFO  @tab 
@item Completed copying distribution information            @tab NODERESTART @tab  8 @tab INFO  @tab 
@item Starting to copy fragments                            @tab NODERESTART @tab  8 @tab INFO  @tab 
@item Completed copying a fragment                          @tab NODERESTART @tab 10 @tab INFO  @tab 
@item Completed copying all fragments                       @tab NODERESTART @tab  8 @tab INFO  @tab 
@item Node failure phase completed                          @tab NODERESTART @tab  8 @tab ALERT @tab Reports node failure phases 
@item Node has failed,  node state was X                    @tab NODERESTART @tab  8 @tab ALERT @tab Reports that a node has failed 

@item Report whether an arbitrator is found or not          @tab NODERESTART @tab  6 @tab INFO  @tab 7 different cases
@c FIX fudged list, as texinfo does not support an enumerate inside a multitable
@item @tab @tab @tab @tab - President restarts arbitration thread [state=X]
@item @tab @tab @tab @tab - Prepare arbitrator node X [ticket=Y]
@item @tab @tab @tab @tab - Receive arbitrator node X [ticket=Y]
@item @tab @tab @tab @tab - Started arbitrator node X [ticket=Y]
@item @tab @tab @tab @tab - Lost arbitrator node X - process failure [state=Y]
@item @tab @tab @tab @tab - Lost arbitrator node X - process exit [state=Y]
@item @tab @tab @tab @tab - Lost arbitrator node X <error msg>[state=Y]

@item Report arbitrator results                             @tab NODERESTART @tab  2 @tab ALERT @tab 8 different results
@c FIX fudged list, as texinfo does not support an enumerate inside a multitable
@item @tab @tab @tab @tab - Arbitration check lost - less than 1/2 nodes left
@item @tab @tab @tab @tab - Arbitration check won - node group majority
@item @tab @tab @tab @tab - Arbitration check lost - missing node group
@item @tab @tab @tab @tab - Network partitioning - arbitration required
@item @tab @tab @tab @tab - Arbitration won - positive reply from node X
@item @tab @tab @tab @tab - Arbitration lost - negative reply from node X
@item @tab @tab @tab @tab - Network partitioning - no arbitrator available
@item @tab @tab @tab @tab - Network partitioning - no arbitrator configured

@item GCP take over started                                 @tab NODERESTART @tab  7 @tab INFO @tab 
@item GCP take over completed                               @tab NODERESTART @tab  7 @tab INFO @tab 
@item LCP take over started                                 @tab NODERESTART @tab  7 @tab INFO @tab 
@item LCP take completed (state = X)                        @tab NODERESTART @tab  7 @tab INFO @tab 

@item Report transaction statistics     @tab STATISTICS  @tab  8 @tab INFO @tab # of: transactions, commits, reads, simple reads, writes, concurrent operations, attribute info, aborts
@item Report operations                 @tab STATISTICS  @tab  8 @tab INFO @tab # of operations
@item Report table create               @tab STATISTICS  @tab  7 @tab INFO @tab 
@item Report job scheduling statistics  @tab STATISTICS  @tab  9 @tab INFO @tab Mean Internal job scheduling statistics
@item Sent # of bytes                   @tab STATISTICS  @tab  9 @tab INFO @tab Mean # of bytes sent to node X
@item Received # of bytes               @tab STATISTICS  @tab  9 @tab INFO @tab Mean # of bytes received from node X
@item Memory usage                      @tab STATISTICS  @tab  5 @tab INFO @tab Data and Index memory usage (80%, 90% and 100%)

@item Transporter errors            @tab ERROR  @tab  2 @tab ERROR   @tab 
@item Transporter warnings          @tab ERROR  @tab  8 @tab WARNING @tab 
@item Missed heartbeats             @tab ERROR  @tab  8 @tab WARNING @tab Node X missed heartbeat # Y
@item Dead due to missed heartbeat  @tab ERROR  @tab  8 @tab ALERT   @tab Node X declared dead due to missed heartbeat
@item General warning events        @tab ERROR  @tab  2 @tab WARNING @tab 

@item Sent heartbeat      @tab INFO @tab 12 @tab INFO @tab Heartbeat sent to node X
@item Create log bytes    @tab INFO @tab 11 @tab INFO @tab Log part, log file, MB
@item General info events @tab INFO @tab  2 @tab INFO @tab 
@end multitable

An event report has the following format in the logs:
@example
<date & time in GMT> [<any string>] <event severity> -- <log message>

09:19:30 2003-04-24 [NDB] INFO -- Node 4 Start phase 4 completed
@end example


@node MySQL Cluster Single User Mode, MySQL Cluster Backup, MySQL Cluster Event Reports, MySQL Cluster Management
@subsection Single User Mode

Single user mode allows the database administrator to restrict access
to the database system to only one application (API node).  When
entering single user mode all connections to all APIs will be
gracefully closed and no transactions are allowed to be started.
All running transactions are aborted.

When the cluster has entered single user mode (use the all status
command to see when the state has entered the single user mode), only
the allowed API node is granted access to the database.

Example:
@example
ENTER SINGLE USER MODE 5
@end example

After executing this command and after cluster has entered the single
user mode, the API node with node id 5 becomes the single user of the
cluster.

The node specified in the command above must be a MySQL Server node.
Any attempt to specify any other type of node will be rejected.

Note: if the node with id 5 is running when executing
@code{ENTER SINGLE USER MODE 5}, all transactions running on node 5
will be aborted, the connection is closed, and the server must be
restarted.

The command @code{EXIT SINGLE USER MODE} alters the state of the
cluster DB nodes from ``single user mode'' to ``started''.
MySQL Servers waiting for a connection, i.e. for the cluster to become
ready, are now allowed to connect.  The MySQL Server denoted as the
single user continues to run, if it is connected, during and after the
state transition. 

Example:
@example
EXIT SINGLE USER MODE
@end example

Best practice in case of node failures when running in single user
mode is to:

@enumerate
@item Finish all single user mode transactions
@item Issue the command exit single user mode
@item Restart database nodes
@end enumerate

Or restart database nodes prior to entering single user mode.


@node MySQL Cluster Backup,  , MySQL Cluster Single User Mode, MySQL Cluster Management
@subsection On-line Backup of MySQL Cluster

This section describes how to create a backup and later restore the
backup to a database.


@menu
* MySQL Cluster Backup Concepts::  Cluster Backup Concepts
* MySQL Cluster Backup Using Management Server::  Using The Management Server to Create a Backup
* MySQL Cluster Restore::       How to Restore a Cluster Backup
* MySQL Cluster Backup Configuration::  Configuration for Cluster Backup
* MySQL Cluster Backup Troubleshooting::  Backup Troubleshooting
@end menu

@node MySQL Cluster Backup Concepts, MySQL Cluster Backup Using Management Server, MySQL Cluster Backup, MySQL Cluster Backup
@subsubsection Cluster Backup Concepts

A backup is a snapshot of the database at a given time.
The backup contains three main parts:

@enumerate
@item Meta data (what tables exists etc)
@item Table records (data in tables)
@item A log of committed transactions
@end enumerate

Each of these parts is saved on all nodes participating in a backup. 

During backup each node saves these three parts to disk into three files:

@table @asis
@item @file{BACKUP-<BackupId>.<NodeId>.ctl}
The control file which contain control information and meta data.
@item @file{BACKUP-<BackupId>-0.<NodeId>.data}
The data file that contain the table records.
@item @file{BACKUP-<BackupId>.<NodeId>.log}
The log file that contain the committed transactions.
@end table

Above <BackupId> is an identifier for the backup and <NodeId> is the
node id of the node creating the file.

@table @asis
@item @strong{Meta data}
The meta data consists of table definitions. All nodes have the exact
same table definitions saved on disk.
@item @strong{Table records}
The table records are saved per fragment. Each fragment contains a
header that describes which table the records belong to.  After the
list of records there is a footer that contains a checksum for the
records. Different nodes save different fragments during the backup.
@item @strong{Committed log}
The committed log contains committed transaction made during the
backup.  Only transactions on tables stored in the backup are stored
in the log.  The different nodes in the backup saves different log
records as they host different database fragments.
@end table


@node MySQL Cluster Backup Using Management Server, MySQL Cluster Restore, MySQL Cluster Backup Concepts, MySQL Cluster Backup
@subsubsection Using The Management Server to Create a Backup

Before starting make sure that the cluster is properly configured for
backups.

@enumerate
@item
Start management server.
@item
Execute the command @code{START BACKUP}.
@item
The management server will reply with a message
``Start of backup ordered''.
This means that the management server has submitted the request to the
cluster, but has not yet received any response.
@item
The management server will reply ``Backup <BackupId> started'' where
<BackupId> is the unique identifier for this particular backup.
This will also be saved in the cluster log (if not configured otherwise).
This means that the cluster has received and processed the backup
request. It does not mean that the backup has completed.
@item
The management server will when the backup is finished reply
``Backup <BackupId> completed''.
@end enumerate

Using the management server to abort a backup:

@enumerate
@item
Start management server.
@item
Execute the command @code{ABORT BACKUP <BACKUPID>}.
The number <BackupId> is the identifier of the backup that is included
in the response of the management server when the backup is started,
i.e. in the message ``Backup <BackupId> started''.
The identifier is also saved in the cluster log (cluster.log).
@item
The management server will reply ``Abort of backup <BackupId> ordered''
This means that it has submitted the request to the cluster, but has
not received any response.
@item
The management server will reply ``Backup <BackupId> has been aborted
reason XYZ''. This means that the cluster has aborted the backup and
removed everything belonging to it, including the files in the file
system.
@end enumerate

Note that if there is not any backup with id <BackupId> running when
it is aborted, the management server will not reply anything.  However
there will be a line in the cluster.log mentioning that an ``invalid''
abort command has been filed.


@node MySQL Cluster Restore, MySQL Cluster Backup Configuration, MySQL Cluster Backup Using Management Server, MySQL Cluster Backup
@subsubsection How to Restore a Cluster Backup

The restore program is implemented as seperate command line utility.
It reads the files created from the backup and inserts the stored
information into the database. The restore program has to be executed
once for each set of backup files, i.e. as many times as there were
database nodes running when the backup we created.

The first time you run the restore program you also need to restore
the meta data, i.e. create tables. The restore program acts as an
API to the cluster and therefore needs a free connection to connect
to. This can be verified with the @command{ndb_mgm} command SHOW. 
The switch @code{-c <connectstring>} may 
be used to locate the MGM node (see @ref{MySQL Cluster Connectstring} for
info on connectstrings).  
The backup files must be present in 
the directory given as an argument to the restore program.  The backup 
can be restored to a database with a different configuration than it was
created from.  For example, consider if a backup (with id 12) created
in a cluster with two database nodes (with node id 2 and node id 3)
that should be restored to a cluster with four nodes.  The restore
program then has to be executed two times (one for each database node
in the cluster where the backup was taken) as described in the box
below.

Note: for rapid restore, the data may be restored in parallell
(provided that there are enough free API connections available). Note
however that the data files must always be applied before the logs.

Note: the cluster should have an empty database when starting to
restore a backup. 


@node MySQL Cluster Backup Configuration, MySQL Cluster Backup Troubleshooting, MySQL Cluster Restore, MySQL Cluster Backup
@subsubsection Configuration for Cluster Backup

There are four configuration parameters for backup:

@table @asis
@item @strong{BackupDataBufferSize}
Amount of memory (out of the total memory) used to buffer data before
it is written to disk.
@item @strong{BackupLogBufferSize}
Amount of memory (out of the total memory) used to buffer log records
before these are written to disk.
@item @strong{BackupMemory}
Total memory allocated in a database node for backups.  This should be
the sum of the memory allocated for the two buffers.
@item @strong{BackupWriteSize}
Size of blocks written to disk.  This applies for both the data buffer
and the log buffer.
@end table


@node MySQL Cluster Backup Troubleshooting,  , MySQL Cluster Backup Configuration, MySQL Cluster Backup
@subsubsection Backup Troubleshooting

If an error code is returned when issuing a backup request, then check
that there is enough memory allocated for the backup (i.e. the
configuration parameters).  Also check that there is enough space on
the hard drive partition of the backup target.


@node MySQL Cluster Interconnects, MySQL Cluster Limitations in 4.1, MySQL Cluster Management, NDBCluster
@section Using High-Speed Interconnects with MySQL Cluster

@menu
* SCI Sockets::                 Configuring MySQL Cluster to use SCI Sockets
* Performance figures::         Low-level benchmarks to understand impact of cluster interconnects
@end menu

Already before design of NDB Cluster started in 1996 it was evident that one
of the major problems of building parallel databases is the communication
between the nodes in the network. Thus from the very beginning NDB Cluster
was designed with a transporter concept to allow for different transporters.

At the moment the code base includes 4 different transporters where 3 of them
are currently working. Most users today uses TCP/IP over Ethernet since this
exists in all machines. This is also by far the most well-tested transporter
in MySQL Cluster.

Within MySQL we are working hard to ensure that communication with the ndbd
process is made in as large chunks as possible since this will benefit all
communication medias since all means of transportation benefits from sending
large messages over small messages.

For users which desire top performance it is however also possible to use
cluster interconnects to increase performance even further. There are two
ways to achieve this, either a transporter can be designed to handle this
case, or one can use socket implementations that bypass the TCP/IP stack to
a small or large extent.

We have made some experiments with both those variants using SCI technology
developed by Dolphin (www.dolphinics.no).

@node SCI Sockets, Performance figures, MySQL Cluster Interconnects, MySQL Cluster Interconnects
@subsection Configuring MySQL Cluster to use SCI Sockets

In this section we will show how one can use a cluster configured for normal
TCP/IP communication to instead use SCI Sockets. Prerequisites for doing this
is that the machines to communicate needs to be equipped with SCI cards. This
documentation is based on the SCI Socket version 2.3.0 as of 1 october 2004.

To use SCI Sockets one can use any version of MySQL Cluster. The tests were
performed on an early 4.1.6 version. No special builds are needed since
it uses normal socket calls which is the normal configuration set-up for
MySQL Cluster. SCI Sockets are only supported on Linux 2.4 and 2.6 kernels at the
moment. SCI Transporters works on more OS's although only Linux 2.4 have been
verified.

There are essentially four things needed to enable SCI Sockets. First it is
necessary to build the SCI Socket libraries. Second the SCI Socket kernel
libraries need to be installed. Third one or two configuration files needs to
be installed.
At last the the SCI Socket kernel library needs to be enabled either for the
entire machine or for the shell where the MySQL Cluster processes are started
from. This process needs to be repeated for each machine in cluster which will
use SCI Sockets to communicate.

Two packages need to be retrieved to get SCI Sockets working. The first package
builds the libraries which SCI Sockets are built upon and the second is the
actual SCI Socket libraries. Currently the distribution is only in source
code format.

The latest versions of these packages is currently found at. Check
@example
http://www.dolphinics.no/support/downloads.html
@end example

for latest versions.

@example
http://www.dolphinics.no/ftp/source/DIS_GPL_2_5_0_SEP_10_2004.tar.gz
http://www.dolphinics.no/ftp/source/SCI_SOCKET_2_3_0_OKT_01_2004.tar.gz
@end example

The next step is to unpack those directories, SCI Sockets is unpacked below
the DIS code. Then the code base is compiled. The example below shows the
commands used in Linux/x86 to perform this.

@example
shell> tar xzf DIS_GPL_2_5_0_SEP_10_2004.tar.gz
shell> cd DIS_GPL_2_5_0_SEP_10_2004/src/
shell> tar xzf ../../SCI_SOCKET_2_3_0_OKT_01_2004.tar.gz
shell> cd ../adm/bin/Linux_pkgs
shell> ./make_PSB_66_release
@end example

If the build is made on an Opteron box and is to use the 64 bit extensions
then use make_PSB_66_X86_64_release instead, if the build is made on an
Itanium box then use make_PSB_66_IA64_release instead. The X86-64 variant
should work for Intel EM64T architectures but no known tests of this exists
yet.

After building the code base it has been put into a zipped tar filed DIS
and OS and date. It is now time to install the package in the proper place.
In this example we will place the installation in /opt/DIS. These actions
will most likely require you to log in as root-user.

@example
shell> cp DIS_Linux_2.4.20-8_181004.tar.gz /opt/
shell> cd /opt
shell> tar xzf DIS_Linux_2.4.20-8_181004.tar.gz
shell> mv DIS_Linux_2.4.20-8_181004 DIS
@end example

Now that all the libraries and binaries are in their proper place we need to
ensure that SCI cards gets proper node identities within the SCI address space.
Since SCI is a networking gear it is necessary to decide on the network structure
at first.

There are three types of network structures, the first is a simple
one-dimensional ring, the second uses SCI switch(es) with one ring per switch
port and finally there are 2D/3D torus. Each has its standard of providing
node ids.

A simple ring uses simply node ids displaced by 4.
@example
4, 8, 12, ....
@end example

The next possibility uses switch(es). The SCI switch has 8 ports. On each port
it is possible to place a ring. It is here necessary to ensure that the
rings on the switch uses different node id spaces. So the first port uses
node ids below 64 and the next 64 node ids are allocated for the next port and
so forth.
@example
4,8, 12, ... , 60  Ring on first port
68, 72, .... , 124 Ring on second port
132, 136, ..., 188 Ring on third port
..
452, 456, ..., 508 Ring on the eight port
@end example

2D/3D torus network structures takes into account where each node is in each
dimension, increment by 4 for each node in the first dimension, by 64 in the
second dimension and by 1024 in the third dimension. Please look in the Dolphin
for more thorough documentation on this.

In our testing we have used switches. Most of the really big cluster
installations uses 2D/3D torus. The extra feature which switches provide
is that with dual SCI cards and dual switches we can easily build a
redundant network where failover times on the SCI network is around 100
microseconds. This feature is supported by the SCI transporter and is
currently also developed for the SCI Socket implementation.

Failover for 2D/3D torus is also possible but requires sending out new
routing indexes to all nodes. Even this will complete in around 100
milliseconds and should be ok for most high-availability cases.

By placing the NDB nodes in proper places in the switched architecture it is
possible to use 2 switches to build a structure where 16 computers can be
interconnected and no single failure can hamper more than one computer.
With 32 computers and 2 switches it is possible to configure the cluster in
such a manner that no single failure can hamper more than two nodes and
in this case it is also known which pair will be hit. Thus by placing those
two in separate NDB node groups it is possible to build a safe MySQL Cluster
installation. We won't go into details in how this is done, since it is
likely to be only of interest for users wanting to go real deep into this.

To set the node id of an SCI card use the following command still being
in the @code{/opt/DIS/sbin} directory. -c 1 refers to the number of the SCI
card, where 1 is this number if only 1 card is in the machine. In this case
use adapter 0 always (set by -a 0). 68 is the node id set in this example.
@example
shell> ./sciconfig -c 1 -a 0 -n 68
@end example

In case you have several SCI cards in your machine the only safe to discover
which card has which slot is by issuing the following command
@example
shell> ./sciconfig -c 1 -gsn
@end example

This will give the serial number which can be found at the back of the SCI
card and on the card itself. Do this then for -c 2 and onwards as many cards
there are in the machine. This will identify which cards uses which id. Then
set node ids for all cards.

Now we have installed the necessary libraries and binaries. We have also set the
SCI node ids. The next step is to set the mapping from hostnames (or IP addresses)
to SCI node ids.

The configuration file for SCI Sockets is to be placed in the file
@code{/etc/sci/scisock.conf}. This file contains a mapping from hostnames
(or IP addresses) to SCI node ids. The SCI node id will map the hostname
to communicate through the proper SCI card. Below is a very simple such
configuration file.
@example
#host           #nodeId 
alpha           8
beta            12
192.168.10.20   16
@end example

It is also possible to limit this configuration to only apply for a subset of
the ports of these hostnames. To do this another configuration is used which
is placed in @code{/etc/sci/scisock_opt.conf}.

@example
#-key                        -type        -values
EnablePortsByDefault		          yes
EnablePort                  tcp           2200
DisablePort                 tcp           2201
EnablePortRange             tcp           2202 2219 
DisablePortRange            tcp           2220 2231 
@end example

Now we ready to install the drivers. We need to first install the low-level drivers
and then the SCI Socket driver.

@example
shell> cd DIS/sbin/
shell> ./drv-install add PSB66
shell> ./scisocket-install add
@end example

If desirable one can now check the installation by invoking a script which checks
that all nodes in the SCI Socket config files are accessible.

@example
shell> cd /opt/DIS/sbin/
shell> ./status.sh
@end example

If you discover an error and need to change the SCI Socket config files then it is
necessary to use a program ksocketconfig to change the configuration.

@example
shell> cd /opt/DIS/util
shell> ./ksocketconfig -f
@end example

To check that SCI Sockets are actually used you can use a test program
@code{latency_bench} which needs to have a server component and clients can
connect to the server to test the latency, whether SCI is enabled is very clear
from the latency you get. Before you use those programs you also need to set
the LD_PRELOAD variable in the same manner as shown below.

To set up a server use the command
@example
shell> cd /opt/DIS/bin/socket
shell> ./latency_bench -server
@end example

To run a client use the following command
@example
shell> cd /opt/DIS/bin/socket
shell> ./latency_bench -client hostname_of_server
@end example

Now the SCI Socket configuration is completed. MySQL Cluster is now
ready to use both SCI Sockets and the SCI transporter documented in
@ref{MySQL Cluster SCI Definition}.

The next step is to start-up MySQL Cluster. To enable usage of SCI Sockets
it is necessary to set the environment variable LD_PRELOAD before starting
the ndbd, mysqld and ndb_mgmd processes to use SCI Sockets. The LD_PRELOAD
variable should point to the kernel library for SCI Sockets.

So as an example to start up ndbd in a bash-shell use the following
commands.

@example
bash-shell> export LD_PRELOAD=/opt/DIS/lib/libkscisock.so
bash-shell> ndbd
@end example

From a tcsh environment the same thing would be accomplished with
the following commands.

@example
tcsh-shell> setenv LD_PRELOAD=/opt/DIS/lib/libkscisock.so
tcsh-shell> ndbd
@end example

Noteworthy here is that MySQL Cluster can only use the kernel variant of
SCI Sockets.

@node Performance figures,  , SCI Sockets, MySQL Cluster Interconnects
@subsection Low-level benchmarks to understand impact of cluster interconnects

The ndbd process has a number of simple constructs which are used to access
the data in MySQL Cluster. We made a very simple benchmark to check the
performance of each such statement and the effect various interconnects have
on their performance.

There are four access methods:
@table @code
@item Primary key access
This is a simple access of one record through its primary key. In the simplest
case only one record is accessed at a time. This means that the full cost of
setting up a number of TCP/IP message and a number of costs for context
switching is taken by this single request. In a batched case where e.g. 32
primary key accesses are sent in one batch then those 32 accesses will share
the set-up cost of TCP/IP messages and context switches (if the TCP/IP are
for different destinations then naturally a number of TCP/IP messages needs
to be set up.

@item Unique key access
Unique key accesses are very similar to primary key accesses except that they
are executed as a read of an index table followed by a primary key access on
the table. However only one request is sent from the MySQL Server, the read
of the index table is handled by the ndbd process. Thus again these requests
benefit from being accessed in batches.

@item Full table scan
When no indexes exist for the lookup on a table, then a full scan of a table
is performed. This is one request to the ndbd process which divides the
table scan into a set of parallel scans on all ndbd processes in the cluster.
In future versions the MySQL server will be able to push down some filtering
in those scans.
When no indexes exist for the lookup on a table, then a full scan of a table
is performed. This is one request to the ndbd process which divides the
table scan into a set of parallel scans on all ndbd processes in the cluster.
In future versions the MySQL server will be able to push down some filtering
in those scans.

@item Range scan using ordered index
When an ordered index is used it will perform a scan in the same manner as the
full table scan except that it will only scan those records which are in the
range used by the query set-up by the MySQL server. In future versions a
special optimisation will ensure that when all index attributes that are
bound includes all attributes in the partitioning key then only one partition
will be scanned instead of all in parallel.
@end table

To check the base performance of these access methods we developed a set of
benchmarks. One such benchmark, testReadPerf issues, simple primary and unique
key access, batched primary and unique key accesses. The benchmark also
measures the set-up cost of range scans by issuing scans returning a single
record and finally there is a variant which uses a range scan to fetch a
batch of records.

In this manner we can test the cost of issuing single key access and single
record scan accesses and measure the impact of the communication media
implementation of these base access methods.

We executed those base benchmark both using a normal transporter using TCP/IP
sockets and a similar set-up using SCI sockets. The figures reported below
is for small accesses of 20 records per of data per access. The difference
between serial and batched goes down by a factor of 3-4 when using 2 kB
records instead. SCI Sockets were not tested with 2 kB record2 kB records. Tests
were performed on a 2-node cluster with 2 dual CPU machines equipped with
AMD MP1900+ processors.

@example
Access type:         TCP/IP sockets           SCI Socket
Serial pk access:    400 microseconds         160 microseconds
Batched pk access:    28 microseconds          22 microseconds
Serial uk access:    500 microseconds         250 microseconds
Batched uk access:    70 microseconds          36 microseconds
Indexed eq-bound:   1250 microseconds         750 microseconds
Index range:          24 microseconds          12 microseconds
@end example

We did also another set of tests to check the performance of SCI Sockets
compared to using the SCI transporter and all compared to the TCP/IP
transporter. All these tests used primary key accesses either serially,
multi-threaded and multi-threaded and batched simultaneously.

More or less all of these tests showed that SCI sockets were about
100% faster compared to TCP/IP. The SCI transporter was faster in most cases
compared to SCI sockets. One notable case however with many threads in the
test program showed that the SCI transporter behaved really bad if used in the
mysqld process.

Thus our conclusion overall is that for most benchmarks SCI sockets improves
performance with around 100% compared to TCP/IP except in rare cases when
communication performance is not an issue such as when scan filters make up
most of processing time or when very large batches of primary key accesses are
achieved. In that case the CPU processing in the ndbd processes becomes a fairly
large part of the cost.

Using the SCI transporter instead of SCI Sockets is only of interest in
communicating between ndbd processes. Using the SCI transporter is also only
of interest if a CPU can be dedicated for the ndbd process since the SCI
transporter ensures that the ndbd will never go to sleep. It is also
important to ensure that the ndbd process priority is set in such a way that
the process doesn't lose in priority due to running for a long time (as
can be done by locking processes to CPU's in Linux 2.6). If this is a
possible configuration then ndbd process will benefit by 10-70% compared to
using SCI sockets (the larger figures when performing updates and probably
also on parallel scan activities).

There are several other implementations of optimised socket variants for
clusters reported in various papers. These include optimised socket
variants for Myrinet, Gigabit Ethernet, Infiniband and the VIA interface.
We have only tested MySQL Cluster so far with SCI sockets and we also
include documentation above on how to set-up SCI sockets using ordinary
TCP/IP configuration for MySQL Cluster.

@node MySQL Cluster Limitations in 4.1,  , MySQL Cluster Interconnects, NDBCluster
@section MySQL Cluster Limitations in 4.1

Below is a list of known limitations with release 4.1 when comparing to the storage 
engines MyISAM and InnoDB. Currently there are no plans to
address these in coming releases of 4.1 (but well in 5.0 or later releases).
At @uref{http://bugs.mysql.com}, category cluster,
you fill find known bugs which are intended to be fixed in upcoming releases of 4.1 (if marked 4.1). 
This list is intended to be complete with respect to the above, 
please report discrepancies at @uref{http://bugs.mysql.com}, 
category cluster. If this discrepancy will not be fixed in 4.1 it will be added to this list.

@table @asis
@item Non compliance in syntax (resulting in error when running an existing application)
@itemize @asis
@item Not all charsets and collations supported, see @ref{MySQL Cluster news-4.1.6} for a list of
      the ones supported.
@item No prefix indexes (can only index complete fields)
@item No text indexes
@item No geometry type support
@end itemize

@item Non compliance in limits/behavior (may result in error when running an existing application)
@itemize @asis
@item No partial rollback of transactions on error. As a result, e.g. duplicate key error, will result
      in a rollback of the whole transaction.
@item A number of hard limits exist which are configurable, but available main memory in the 
      cluster sets limits. See complete list of configuration parameters 
      @ref{MySQL Cluster Config File}. Most configuration parameters can be upgraded on-line.
      @itemize @asis
      @item Database memory size and index memory size, @code{DataMemory} and @code{IndexMemory}
            repectively.
      @item How large transactions can be performed is set with config parameter 
            @code{MaxNoOfConcurrentOperations}
            (bulk load, truncate table and alter table are handled specially by running 
             several transactions, and thus does not have this limitation)
      @item Different limits related to tables and indexes, e.g. max number of ordered indexes,
             @code{MaxNoOfOrderedIndexes} etc.
      @end itemize
@item Database names, table names and attribute names cannot be as long in
      ndb tables as in other table handlers. Attibute names will be truncated to 31 characters,
      and if they are not unique after truncation gives an error. Database name and table name
      can be max a total of 122 characters together.
@item Max number of meta data objects is limited to 1600 (includes tables, system tables, indexes and BLOBs)
@item Max number of attributes per table limited to 128
@item Max row size of 8k (not including BLOBs)
@item Max number of attributes in a key is 32
@end itemize

@item Not supported features (no error, but not supported/enforced)
@itemize @asis
@item Foreign key construct is ignored (same behavior as MyISAM)
@item Savepoint and rollback to savepoint ignored (same behavior as MyISAM)
@end itemize

@item Performance and limitations related
@itemize @asis
@item Query cache disabled since it is not invalidated if update occurs on other MySQL server
@item Query performance issues due to sequential access to storage engine 
      and relatively more expensive to do many range scans.
@item Records in range statistic not supported, giving non-optimal
      query plans in some cases. Use constructs @code{USE INDEX} or @code{FORCE INDEX}
      to work around non optimal query plans.
@item Unique hash index (constructed with @code{USING HASH}) cannot be used for accessing table 
      if NULL is given as part of the key.
@end itemize

@item Missing features
@itemize @asis
@item Only support for READ_COMMITTED isolation level
      (InnoDB supports READ_COMMITTED, REPEATABLE_READ and SERIALIZABLE)
@item No disk durable commit (are replicated, but no guarantee that logs are
      flushed to disk at commit)
@end itemize

@item Problems related to multiple MySQL servers (not related to MyISAM or InnoDB)
@itemize @asis
@item Alter table not fully blocking when running multiple MySQL servers (no distributed table lock)
@item MySQL Replication will not work right off if updates are done on several MySQL servers.
      If a partitioning scheme of the database is done at the application level, and no transactions
      takes place across these partitions, it will work.
@end itemize

@item Cluster only related (not related to MyISAM or InnoDB)
@itemize @asis
@item All machines in the cluster must use the same architecture; that 
      is, all machines hosting nodes must be either big-endian or 
      little-endian, and you cannot use a mixture of both. For example, 
      you cannot have a management node running on a PPC which directs 
      a server node that is running on an x86 machine. This restriction 
      does not apply to machines simply running @command{mysql} clients 
      that may be accessing the cluster.
@item No on-line schema changes (no on-line alter table,
      Ndb on-line create index not accessible)
@item No on-line add/drop node
@item When using multiple management servers one must give nodes an id explicitly in the
      connect strings since the automatic allocation of node id's does not work across 
      several management servers.
@item When using multiple management servers one must take extreme care to have the same
      configuration in all management servers.  No checks for this are performed.
@item Max number of storage nodes 48
@item Total max number of nodes 63 (MySQL Servers, storage nodes and management servers)
@end itemize

@end table


@c @node MySQL Cluster Tables
@c @section Creating NDBCluster Tables


@c @node MySQL Cluster Trans Model
@c @section The Transaction Model for MySQL Cluster


@c @node MySQL Cluster Structures
@c @section Record and Index Structures in MySQL Cluster


@c @node MySQL Cluster Fixed
@c @subsection Fixed Record Structure

@c @node MySQL Cluster Variable
@c @subsection Variable Sized Record Parts


@c @node MySQL Cluster BLOB
@c @subsection @code{BLOB} Handling in MySQL Cluster


@c @node MySQL Cluster Hash Index
@c @subsection Hash Index Structure


@c @node MySQL Cluster Ordered Index
@c @subsection Structure of the Ordered Index


@c @node MySQL Cluster Access
@c @section Table Access Methods in MySQL Cluster


@c @node MySQL Cluster PK
@c @subsection Primary Key Access


@c @node MySQL Cluster UK
@c @subsection Unique Hash Index Access


@c @node MySQL Cluster Scan
@c @subsection Full Table Scan


@c @node MySQL Cluster Range
@c @subsection Range Scan


@c @node MySQL Cluster Performance
@c @section Performance Tuning of MySQL Cluster


@c @node MySQL Cluster Software Upgrade
@c @section Software Upgrade of MySQL Cluster


@c @node MySQL Cluster Error
@c @section Error Handling in MySQL Cluster


@c @node MySQL Cluster Restrictions
@c @section Restrictions on NDBCluster Tables


@c @node MySQL Cluster Troubleshooting
@c @section Troubleshooting MySQL Cluster 

@c @node MySQL Cluster TODO
@c @section TODO list for MySQL Cluster


@node MaxDB, Spatial extensions in MySQL, NDBCluster, Top
@chapter Introduction to MaxDB

@c Author: Stefan Hinz
@c Technical Editor / Approved by: Patrik Backman

MaxDB is an enterprise-level database. MaxDB is the new name of a database management system formerly called SAP DB.

@menu
* MaxDB History::               History of MaxDB
* MaxDB Licensing::             Licensing and Support
* MaxDB Links::                 MaxDB-Related Links
* MaxDB Basics::                Basic Concepts of MaxDB
* MaxDB-MySQL Differences::     Feature Differences Between MaxDB and MySQL
* MaxDB-MySQL Interoperability::  Interoperability Features Between MaxDB and MySQL
* MaxDB Reserved Words::        Reserved Words in MaxDB
@end menu


@node MaxDB History, MaxDB Licensing, MaxDB, MaxDB
@section History of MaxDB

The  history of SAP DB goes back to the early 1980s when it was developed as
a commercial product (Adabas). The database has changed names several times
since then. When SAP AG, a company based in Walldorf, Germany, took over the
development of that database system, it was called SAP DB.

SAP developed that database system to serve as a storage system
for all heavy-duty SAP applications, namely R/3. SAP DB was meant
to provide an alternative to third-party database systems such as
Oracle, Microsoft SQL Server, and DB2 by IBM. In October 2000, SAP
AG released SAP DB under the GNU GPL license (@pxref{GPL license}), 
thus making it Open Source software. In October 2003, more than 2,000 
customers of SAP AG were using SAP DB as their main database system, 
and more than another 2,000 customers were using it as a separate 
database system besides their main database, as part of the 
APO/LiveCache solution.

In May 2003, a technology partnership was formed between MySQL AB
and SAP AG. That partnership entitles MySQL AB to further develop SAP
DB, rename it, and sell commercial licenses of the renamed SAP DB
to customers who do not want to be bound to the restrictions imposed
on them when using that database system under the GNU GPL (@pxref{GPL
license}). In August 2003, SAP DB was renamed MaxDB by MySQL AB.

@node MaxDB Licensing, MaxDB Links, MaxDB History, MaxDB
@section Licensing and Support

MaxDB can be used under the same licenses available for the other
products distributed by MySQL AB. Thus, MaxDB will be available under 
the GNU General Public License, and a commercial license. For more information
on licensing, see @uref{http://www.mysql.com/company/legal/licensing/}.

MySQL will offer MaxDB support to non-SAP customers.

The first rebranded version was MaxDB 7.5.00, which was
released in November 2003.

@node MaxDB Links, MaxDB Basics, MaxDB Licensing, MaxDB
@section MaxDB-Related Links

The main page for information about MaxDB is
@uref{http://www.mysql.com/products/maxdb}. Information formerly
available at @uref{http://www.sapdb.org} has been moved there.

@node MaxDB Basics, MaxDB-MySQL Differences, MaxDB Links, MaxDB
@section Basic Concepts of MaxDB

MaxDB operates as a client/server product. It was developed to meet
the demands of installations processing a high volume of online
transactions. Both online backup and expansion of the database are
supported. Microsoft Clustered Server is supported directly for
multiple server implementations; other failover solutions must be
scripted manually. Database management tools are provided in both
Windows and browser-based implementations.

@node MaxDB-MySQL Differences, MaxDB-MySQL Interoperability, MaxDB Basics, MaxDB
@section Feature Differences Between MaxDB and MySQL

The following list provides a short summary of the main differences
between MaxDB and MySQL; it is not complete.

@itemize @bullet
@item
MaxDB runs as a client/server system. MySQL can run as a client/server system
or as an embedded system.
@item
MaxDB might not run on all platforms supported by MySQL. For example,
MaxDB does not run on IBM's OS/2.
@item
MaxDB uses a proprietary network protocol for client/server
communication. MySQL uses either TCP/IP (with or without SSL
encryption), sockets (under Unix-like systems), or named pipes
(under Windows NT-family systems).
@item
MaxDB supports stored procedures. For MySQL, stored procedures are
implemented in version 5.0. MaxDB also supports programming of
triggers through an SQL extension, which is scheduled for MySQL
5.1. MaxDB contains a debugger for stored procedure languages,
can cascade nested triggers, and supports multiple triggers per
action and row.
@item
MaxDB is distributed with user interfaces that are text-based,
graphical, or Web-based. MySQL is distributed with text-based user
interfaces only; graphical user interface (MySQL Control Center, MySQL
Administrator)
are shipped separately from the main distributions. Web-based user
interfaces for MySQL are offered by third parties.
@item
MaxDB supports a number of programming interfaces that also are supported
by MySQL. However, MaxDB does not support RDO, ADO, or .NET, all of which are
supported by MySQL. MaxDB
supports embedded SQL only with C/C++.
@item
MaxDB includes administrative features that MySQL does not have:
job scheduling by time, event, and alert, and sending
messages to a database administrator on alert thresholds.
@end itemize

@c Maybe add table showing maxima for MaxDB and MySQL. Might be obtained from crash-me comparison.

@node MaxDB-MySQL Interoperability, MaxDB Reserved Words, MaxDB-MySQL Differences, MaxDB
@section Interoperability Features Between MaxDB and MySQL

The following features will be included in MaxDB versions to be
released shortly after the first 7.5.00 version. These features
will allow interoperation between MaxDB and MySQL.

@itemize @bullet
@item
There will be a MySQL proxy enabling connections to MaxDB using
the MySQL protocol. This makes it possible to use MySQL client
programs for MaxDB, such as the @command{mysql} command-line user interface,
the @command{mysqldump} dump utility, or the @command{mysqlimport} import
program. Using @command{mysqldump}, you can easily dump data from one
database system and export (or even pipe) those data to the other
database system.
@c For the utilities mentioned (and maybe for other utitilities as
@c well) it should be noted in the appropriate sections that they can
@c be used to communicate with the MaxDB server.
@item

Replication between MySQL and MaxDB will be supported in both
directions. That is, either MySQL or MaxDB can be used as the master
replication server. The long-range plan is to converge and extend the
replication syntax so that both database systems understand the same syntax.
@xref{Replication Intro}.
@c This item also in subsection 4.10.1 (Introduction to MySQL Replication)
@end itemize

@node MaxDB Reserved Words,  , MaxDB-MySQL Interoperability, MaxDB
@section Reserved Words in MaxDB

Like MySQL, MaxDB has a number of reserved words that have special meanings.
Normally, they cannot be used
as names of identifiers, such as database or table names. The following
table lists reserved words in MaxDB, indicates the context in which
those words are used, and indicates whether or not they have
counterparts in MySQL. If such a counterpart exists, the meaning
in MySQL might be identical or differing in some aspects. The main
purpose is to list in which respects MaxDB differs from MySQL;
therefore, this list is not complete.

For the list of reserved words in MySQL, see @ref{Reserved words}.

@multitable @columnfractions .20 .30 .50
@item @strong{Reserved in MaxDB}
 @tab @strong{Context of usage in MaxDB}
 @tab @strong{MySQL counterpart}
@item @code{@@}
 @tab Can prefix identifier, like ``@@table''
 @tab Not allowed
@item @code{ADDDATE()}
 @tab SQL function
 @tab @code{ADDDATE()}; new in MySQL 4.1.1
@item @code{ADDTIME()}
 @tab SQL function
 @tab @code{ADDTIME()}; new in MySQL 4.1.1
@item @code{ALPHA}
 @tab SQL function
 @tab Nothing comparable
@item @code{ARRAY}
 @tab Data type
 @tab Not implemented
@item @code{ASCII()}
 @tab SQL function
 @tab @code{ASCII()}, but implemented with a different meaning
@item @code{AUTOCOMMIT}
 @tab Transactions; @code{ON} by default
 @tab Transactions; @code{OFF} by default
@item @code{BOOLEAN}
 @tab Column types; @code{BOOLEAN} accepts as values only @code{TRUE}, @code{FALSE}, and @code{NULL}
 @tab @code{BOOLEAN} was added in MySQL 4.1.0; it is a synonym for @code{BOOL} which is mapped to @code{TINYINT(1)}. It accepts integer values in the same range as @code{TINYINT} as well as @code{NULL}. @code{TRUE} and @code{FALSE} can be used as aliases for @code{1} and @code{0}.
@item @code{CHECK}
 @tab @code{CHECK TABLE}
 @tab @code{CHECK TABLE}; similar, but not identical usage
@item @code{COLUMN}
 @tab Column types
 @tab @code{COLUMN}; noise word
@item @code{CHAR()}
 @tab SQL function
 @tab @code{CHAR()}; identical syntax; similar, not identical usage
@item @code{COMMIT}
 @tab Implicit commits of transactions happen when data definition statements are issued
 @tab Implicit commits of transactions happen when data definition statements are issued, and also with a number of other statements
@item @code{COSH()}
 @tab SQL function
 @tab Nothing comparable
@item @code{COT()}
 @tab SQL function
 @tab @code{COT()}; identical syntax and implementation
@item @code{CREATE}
 @tab SQL, data definition language
 @tab @code{CREATE}
@item @code{DATABASE}
 @tab SQL function
 @tab @code{DATABASE()}; @code{DATABASE} is used in a different context; for example, @code{CREATE DATABASE}
@item @code{DATE()}
 @tab SQL function
 @tab @code{CURRENT_DATE}
@item @code{DATEDIFF()}
 @tab SQL function
 @tab @code{DATEDIFF()}; new in MySQL 4.1.1
@item @code{DAY()}
 @tab SQL function
 @tab Nothing comparable
@item @code{DAYOFWEEK()}
 @tab SQL function
 @tab @code{DAYOFWEEK()}; by default, @code{1} represents Monday in MaxDB and Sunday in MySQL
@item @code{DISTINCT}
 @tab SQL functions @code{AVG}, @code{MAX}, @code{MIN}, @code{SUM}
 @tab @code{DISTINCT}; but used in a different context: @code{SELECT DISTINCT}
@item @code{DROP}
 @tab @code{DROP INDEX}, for example
 @tab @code{DROP INDEX}; similar, but not identical usage
@item @code{EBCDIC()}
 @tab SQL function
 @tab Nothing comparable
@item @code{EXPAND()}
 @tab SQL function
 @tab Nothing comparable
@item @code{EXPLAIN}
 @tab Optimization
 @tab @code{EXPLAIN}; similar, but not identical usage
@item @code{FIXED()}
 @tab SQL function
 @tab Nothing comparable
@item @code{FLOAT()}
 @tab SQL function
 @tab Nothing comparable
@item @code{HEX()}
 @tab SQL function
 @tab @code{HEX()}; similar, but not identical usage
@item @code{INDEX()}
 @tab SQL function
 @tab @code{INSTR()} or @code{LOCATE()}; similar, but not identical syntaxes and meanings
@item @code{INDEX}
 @tab @code{USE INDEX}, @code{IGNORE INDEX} and similar hints are used right after @code{SELECT}; for example, @code{SELECT ... USE INDEX}
 @tab @code{USE INDEX}, @code{IGNORE INDEX} and similar hints are used in the @code{FROM} clause of a @code{SELECT} query; for example, in @code{SELECT ... FROM ... USE INDEX}
@item @code{INITCAP()}
 @tab SQL function
 @tab Nothing comparable
@item @code{LENGTH()}
 @tab SQL function
 @tab @code{LENGTH()}; identical syntax, but slightly different implementation
@item @code{LFILL()}
 @tab SQL function
 @tab Nothing comparable
@item @code{LIKE}
 @tab Comparisons
 @tab @code{LIKE}; but the extended @code{LIKE} MaxDB provides rather resembles the MySQL @code{REGEX}
@item @code{LIKE} wildcards
 @tab MaxDB supports ``%'', ``_'', ``Control-underline'', ``Control-up arrow'', ``*'', and ``?'' as wildcards in @code{LIKE} comparisons
 @tab MySQL supports ``%'', and ``_'' as wildcards in @code{LIKE} comparisons
@item @code{LPAD()}
 @tab SQL function
 @tab @code{LPAD()}; slightly different implementation
@item @code{LTRIM()}
 @tab SQL function
 @tab @code{LTRIM()}; slightly different implementation
@item @code{MAKEDATE()}
 @tab SQL function
 @tab @code{MAKEDATE()}; new in MySQL 4.1.1
@item @code{MAKETIME()}
 @tab SQL function
 @tab @code{MAKETIME()}; new in MySQL 4.1.1
@item @code{MAPCHAR()}
 @tab SQL function
 @tab Nothing comparable
@item @code{MICROSECOND()}
 @tab SQL function
 @tab @code{MICROSECOND()}; new in MySQL 4.1.1
@item @code{NOROUND()}
 @tab SQL function
 @tab Nothing comparable
@item @code{NULL}
 @tab Column types; comparisons
 @tab @code{NULL}; MaxDB supports special @code{NULL} values that are returned by arithmetic operations that lead to an overflow or a division by zero; MySQL does not support such special values
@item @code{PI}
 @tab SQL function
 @tab @code{PI()}; identical syntax and implementation, but parentheses are mandatory in MySQL
@item @code{REF}
 @tab Data type
 @tab Nothing comparable
@item @code{RFILL()}
 @tab SQL function
 @tab Nothing comparable
@item @code{ROWNO}
 @tab Predicate in @code{WHERE} clause
 @tab Similar to @code{LIMIT} clause
@item @code{RPAD()}
 @tab SQL function
 @tab @code{RPAD()}; slightly different implementation
@item @code{RTRIM()}
 @tab SQL function
 @tab @code{RTRIM()}; slightly different implementation
@item @code{SEQUENCE}
 @tab @code{CREATE SEQUENCE}, @code{DROP SEQUENCE}
 @tab @code{AUTO_INCREMENT}; similar concept, but different implementation
@item @code{SINH()}
 @tab SQL function
 @tab Nothing comparable
@item @code{SOUNDS()}
 @tab SQL function
 @tab @code{SOUNDEX()}; slightly different syntax
@item @code{STATISTICS}
 @tab @code{UPDATE STATISTICS}
 @tab @code{ANALYZE TABLE}; similar concept, but different implementation
@item @code{SUBSTR()}
 @tab SQL function
 @tab @code{SUBSTRING()}; slightly different implementation
@item @code{SUBTIME()}
 @tab SQL function
 @tab @code{SUBTIME()}; new in MySQL 4.1.1
@item @code{SYNONYM}
 @tab Data definition language: @code{CREATE [PUBLIC] SYNONYM}, @code{RENAME SYNONYM}, @code{DROP SYNONYM}
 @tab Nothing comparable
@item @code{TANH()}
 @tab SQL function
 @tab Nothing comparable
@item @code{TIME()}
 @tab SQL function
 @tab @code{CURRENT_TIME}
@item @code{TIMEDIFF()}
 @tab SQL function
 @tab @code{TIMEDIFF()}; new in MySQL 4.1.1
@item @code{TIMESTAMP()}
 @tab SQL function
 @tab @code{TIMESTAMP()}; new in MySQL 4.1.1
@item @code{TIMESTAMP()} as argument to @code{DAYOFMONTH()} and @code{DAYOFYEAR()}
 @tab SQL function
 @tab Nothing comparable
@item @code{TIMEZONE()}
 @tab SQL function
 @tab Nothing comparable
@item @code{TRANSACTION()}
 @tab Returns the ID of the current transaction
 @tab Nothing comparable
@item @code{TRANSLATE()}
 @tab SQL function
 @tab @code{REPLACE()}; identical syntax and implementation
@item @code{TRIM()}
 @tab SQL function
 @tab @code{TRIM()}; slightly different implementation
@item @code{TRUNC()}
 @tab SQL function
 @tab @code{TRUNCATE()}; slightly different syntax and implementation
@item @code{USE}
 @tab Switches to a new database instance; terminates the connection to the 
	current database instance; all subsequent commands are referred to this 
	database instance
 @tab @code{USE}; identical syntax, but does not terminate the connection to
	the current database
@item @code{USER}
 @tab SQL function
 @tab @code{USER()}; identical syntax, but slightly different implementation, and parentheses are mandatory in MySQL
@item @code{UTC_DIFF()}
 @tab SQL function
 @tab @code{UTC_DATE()}; provides a means to calculate the same result as @code{UTC_DIFF()}
@item @code{VALUE()}
 @tab SQL function, alias for @code{COALESCE()}
 @tab @code{COALESCE()}; identical syntax and implementation
@item @code{VARIANCE()}
 @tab SQL function
 @tab @code{VARIANCE()}; new in MySQL 4.1.0
@item @code{WEEKOFYEAR()}
 @tab SQL function
 @tab @code{WEEKOFYEAR()}; new in MySQL 4.1.1
@end multitable

@c commented these out because they have no content

@c @node MaxDB Functions, MaxDB Column Types, MaxDB Reserved Words, MaxDB
@c @section Functions
@c 
@c @c Should go to Functions chapter
@c 
@c @node MaxDB Column Types,  , MaxDB Functions, MaxDB
@c @section Column Types
@c 
@c @c Should go to Column Types chapter


@node Spatial extensions in MySQL, Stored Procedures, MaxDB, Top
@chapter Spatial Extensions in MySQL
@cindex GIS

@c help_category Geographic features

MySQL 4.1 introduces spatial extensions to allow the
generation, storage, and analysis of geographic features.
Currently, these features are available for @code{MyISAM} tables only.

This chapter covers the following topics:

@itemize @bullet

@item
The basis of these spatial extensions in the OpenGIS geometry model

@item
Data formats for representing spatial data

@item
How to use spatial data in MySQL

@item
Use of indexing for spatial data

@item
MySQL differences from the OpenGIS specification

@end itemize

@menu
* GIS introduction::            Introduction
* OpenGIS geometry model::      The OpenGIS Geometry Model
* Supported spatial data formats::  Supported Spatial Data Formats
* Creating a spatially enabled MySQL database::  Creating a Spatially Enabled MySQL Database
* Analysing spatial information::  Analyzing Spatial Information
* Optimizing spatial analysis::  Optimizing Spatial Analysis
* MySQL GIS conformance and compatibility::  MySQL Conformance and Compatibility
@end menu


@node GIS introduction, OpenGIS geometry model, Spatial extensions in MySQL, Spatial extensions in MySQL
@section Introduction

@cindex Spatial Extensions in MySQL

@cindex GIS
@cindex OpenGIS

MySQL implements spatial extensions following the specification of
the @code{Open GIS Consortium} (OGC). This is an international consortium
of more than 250 companies, agencies, and universities participating
in the development of publicly available conceptual solutions that can be
useful with all kinds of applications that manage spatial data.
The OGC maintains a Web site at @uref{http://www.opengis.org/}.

In 1997, the Open GIS Consortium published the
@cite{OpenGIS (R) Simple Features Specifications For SQL}, a document that
proposes several conceptual ways for extending an SQL RDBMS to support spatial
data. This specification is available from the Open GIS Web site at
@uref{http://www.opengis.org/docs/99-049.pdf}.
It contains additional information relevant to this chapter.

MySQL implements a subset of the @strong{SQL with Geometry Types}
environment proposed by OGC.
This term refers to an SQL environment that has been extended with a
set of geometry types. A geometry-valued SQL column is implemented as
a column that has a geometry type. The specifications describe a set of SQL
geometry types, as well as functions on those types to create and
analyze geometry values.

@cindex geographic feature

A @strong{geographic feature} is anything in the world that has a location.
A feature can be:

@itemize @bullet
@item
An entity. For example, a mountain, a pond, a city.
@item
A space. For example, a postcode area, the tropics.
@item
A definable location. For example, a crossroad,
as a particular place where two streets intersect.
@end itemize

@cindex geospatial feature

You can also find documents that use the term @strong{geospatial feature} to
refer to geographic features.

@cindex geometry

@strong{Geometry} is another word that denotes a geographic feature.
Originally the word @strong{geometry} meant measurement of the earth.
Another meaning comes from cartography, referring to the geometric
features that cartographers use to map the world.

This chapter uses all of these terms synonymously:
@strong{geographic feature}, @strong{geospatial feature},
@strong{feature}, or @strong{geometry}.
The term most commonly used here is @strong{geometry}.

Let's define a @strong{geometry} as @emph{a point or an aggregate of
points representing anything in the world that has a location}.


@node OpenGIS geometry model, Supported spatial data formats, GIS introduction, Spatial extensions in MySQL
@section The OpenGIS Geometry Model

The set of geometry types proposed by OGC's @strong{SQL with Geometry Types}
environment is based on the @strong{OpenGIS Geometry Model}. In this model,
each geometric object has the following general properties:

@itemize @bullet
@item
It is associated with a Spatial Reference System, which describes the
coordinate space in which the object is defined.
@item
It belongs to some geometry class.
@end itemize


@menu
* GIS geometry class hierarchy::  The Geometry Class Hierarchy
* GIS class geometry::          Class @code{Geometry}
* GIS class point::             Class @code{Point}
* GIS class curve::             Class @code{Curve}
* GIS class linestring::        Class @code{LineString}
* GIS class surface::           Class @code{Surface}
* GIS class polygon::           Class @code{Polygon}
* GIS class geometrycollection::  Class @code{GeometryCollection}
* GIS class multipoint::        Class @code{MultiPoint}
* GIS class multicurve::        Class @code{MultiCurve}
* GIS class multilinestring::   Class @code{MultiLineString}
* GIS class multisurface::      Class @code{MultiSurface}
* GIS class multipolygon::      Class @code{MultiPolygon}
@end menu


@node GIS geometry class hierarchy, GIS class geometry, OpenGIS geometry model, OpenGIS geometry model
@subsection The Geometry Class Hierarchy

The geometry classes define a hierarchy as follows:

@itemize @bullet
@item @code{Geometry} (non-instantiable)
@itemize @bullet
@item @code{Point} (instantiable)

@item @code{Curve} (non-instantiable)
@itemize @bullet
@item @code{LineString} (instantiable)
@itemize @bullet
@item @code{Line}
@item @code{LinearRing}
@end itemize
@end itemize

@item @code{Surface} (non-instantiable)
@itemize @bullet
@item @code{Polygon} (instantiable)
@end itemize

@item @code{GeometryCollection} (instantiable)
@itemize @bullet
@item @code{MultiPoint} (instantiable)
@item @code{MultiCurve} (non-instantiable)
@itemize @bullet
@item @code{MultiLineString} (instantiable)
@end itemize
@item @code{MultiSurface} (non-instantiable)
@itemize @bullet
@item @code{MultiPolygon} (instantiable)
@end itemize
@end itemize

@end itemize
@end itemize

It is not possible to create objects in non-instantiable classes.
It is possible to create objects in instantiable classes.
All classes have properties, and instantiable classes may also
have assertions (rules that define valid class instances).

@c help_category Geographic features
@c description_for_help_topic Geometry hierarchy
@code{Geometry} is the base class. It's an abstract class.
The instantiable subclasses of @code{Geometry} are restricted to zero-, one-,
and two-dimensional geometric objects that exist in
two-dimensional coordinate space. All instantiable geometry classes are
defined so that valid instances of a geometry class are topologically closed
(that is, all defined geometries include their boundary).

The base @code{Geometry} class has subclasses for @code{Point},
@code{Curve}, @code{Surface}, and @code{GeometryCollection}:

@itemize @bullet

@item
@code{Point} represents zero-dimensional objects.

@item
@code{Curve} represents one-dimensional objects, and has subclass
@code{LineString}, with sub-subclasses @code{Line} and @code{LinearRing}.

@item
@code{Surface} is designed for two-dimensional objects and
has subclass @code{Polygon}.

@item
@code{GeometryCollection}
has specialized zero-, one-, and two-dimensional collection classes named
@code{MultiPoint}, @code{MultiLineString}, and @code{MultiPolygon}
for modeling geometries corresponding to collections of
@code{Points}, @code{LineStrings}, and @code{Polygons}, respectively.
@code{MultiCurve} and @code{MultiSurface} are introduced as abstract superclasses
that generalize the collection interfaces to handle @code{Curves} and @code{Surfaces}.

@end itemize

@code{Geometry}, @code{Curve}, @code{Surface}, @code{MultiCurve},
and @code{MultiSurface} are defined as non-instantiable classes.
They define a common set of methods for their subclasses and
are included for extensibility.

@code{Point}, @code{LineString}, @code{Polygon}, @code{GeometryCollection},
@code{MultiPoint}, @code{MultiLineString}, and
@code{MultiPolygon} are instantiable classes.
@c end_description_for_help_topic

@node GIS class geometry, GIS class point, GIS geometry class hierarchy, OpenGIS geometry model
@subsection Class @code{Geometry}

@code{Geometry} is the root class of the hierarchy.  It is a
non-instantiable class but has a number of properties that are common to
all geometry values created from any of the @code{Geometry} subclasses.
These properties are described in the following list.  (Particular
subclasses have their own specific properties, described later.)


@subsubheading Geometry Properties

A geometry value has the following properties:

@itemize @bullet

@item
Its @strong{type}.
Each geometry belongs to one of the instantiable classes in the hierarchy.

@item
Its @strong{SRID}, or Spatial Reference Identifier. This value identifies
the geometry's associated Spatial Reference System that describes the
coordinate space in which the geometry object is defined.

In MySQL, the SRID value is just an integer associated with the geometry
value. All calculations are done assuming Euclidean (planar) geometry.

@item
Its @strong{coordinates} in its Spatial Reference System,
represented as double-precision (eight-byte) numbers. All non-empty geometries
include at least one pair of (X,Y) coordinates. Empty geometries contain
no coordinates.

Coordinates are related to the SRID.
For example, in different coordinate systems, the distance between two objects
may differ even when objects have the same coordinates, because the distance
on the @strong{planar} coordinate system and the distance on the @strong{geocentric}
system (coordinates on the Earth's surface) are different things.

@item
Its @strong{interior}, @strong{boundary}, and @strong{exterior}.
@c help_category MBR@Geographic features
@c description_for_help_topic MBR definition
Every geometry occupies some position in space. The exterior of
a geometry is all space not occupied by the geometry. The interior
is the space occupied by the geometry. The boundary is the
interface between the geometry's interior and exterior.

@item
Its @strong{MBR} (Minimum Bounding Rectangle), or Envelope.
This is the bounding geometry, formed by the minimum and maximum (X,Y)
coordinates:
@c end_description_for_help_topic

@c example_for_help_topic MBR definition
@example
((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))
@end example

@item
Whether the value is @strong{simple} or @strong{non-simple}.
Geometry values of types (@code{LineString}, @code{MultiPoint},
@code{MultiLineString})
are either simple or non-simple. Each type determines its own assertions
for being simple or non-simple.

@item
Whether the value is @strong{closed} or @strong{not closed}.
Geometry values of types (@code{LineString}, @code{MultiString}) are
either closed
or not closed. Each type determines its own assertions for being closed
or not closed.

@item
Whether the value is @strong{empty} or @strong{non-empty}
A geometry is empty if it does not have any points.
Exterior, interior, and boundary of an empty geometry
are not defined (that is, they are represented by a @code{NULL} value).
An empty geometry is defined to be always simple and has an area of 0.

@item
Its @strong{dimension}. A geometry can have a dimension of @minus{}1, 0, 1,
or 2:

@itemize @bullet

@item @minus{}1 for an empty geometry.

@item 0 for a geometry with no length and no area.

@item 1 for a geometry with non-zero length and zero area.

@item 2 for a geometry with non-zero area.

@end itemize

@code{Point} objects have a dimension of zero.  @code{LineString}
objects have a dimension of 1. @code{Polygon} objects have a
dimension of 2.  The dimensions of @code{MultiPoint},
@code{MultiLineString}, and @code{MultiPolygon} objects are the
same as the dimensions of the elements they consist of.

@end itemize


@node GIS class point, GIS class curve, GIS class geometry, OpenGIS geometry model
@subsection Class @code{Point}

A @code{Point} is a geometry that represents a single
location in coordinate space.

@subsubheading @code{Point} Examples

@itemize @bullet

@item
Imagine a large-scale map of the world with many cities.
A @code{Point} object could represent each city.

@item
On a city map, a @code{Point} object could represent a bus stop.
@end itemize

@subsubheading @code{Point} Properties

@itemize @bullet

@item
X-coordinate value.

@item
Y-coordinate value.

@item
@code{Point} is defined as a zero-dimensional geometry.

@item
The boundary of a @code{Point} is the empty set.
@end itemize


@node GIS class curve, GIS class linestring, GIS class point, OpenGIS geometry model
@subsection Class @code{Curve}

A @code{Curve} is a one-dimensional geometry, usually represented by a sequence
of points. Particular subclasses of @code{Curve} define the type of
interpolation between points. @code{Curve} is a non-instantiable class.

@subsubheading @code{Curve} Properties

@itemize @bullet

@item
A @code{Curve} has the coordinates of its points.

@item
A @code{Curve} is defined as a one-dimensional geometry.

@item
A @code{Curve} is simple if it does not pass through the same point twice.

@item
A @code{Curve} is closed if its start point is equal to its end point.

@item
The boundary of a closed @code{Curve} is empty.

@item
The boundary of a non-closed @code{Curve} consists of its two end points.

@item
A @code{Curve} that is simple and closed is a @code{LinearRing}.

@end itemize


@node GIS class linestring, GIS class surface, GIS class curve, OpenGIS geometry model
@subsection Class @code{LineString}

A @code{LineString} is a @code{Curve} with linear interpolation between points.

@subsubheading @code{LineString} Examples

@itemize @bullet

@item
On a world map, @code{LineString} objects could represent rivers.

@item
In a city map, @code{LineString} objects could represent streets.

@end itemize

@subsubheading @code{LineString} Properties

@itemize @bullet

@item
A @code{LineString} has coordinates of segments, defined by each consecutive pair of points.

@item
A @code{LineString} is a @code{Line} if it consists of exactly two points.

@item
A @code{LineString} is a @code{LinearRing} if it is both closed and simple.

@end itemize


@node GIS class surface, GIS class polygon, GIS class linestring, OpenGIS geometry model
@subsection Class @code{Surface}

@c TODO: need examples

A @code{Surface} is a two-dimensional geometry. It is a non-instantiable
class. Its only instantiable subclass is @code{Polygon}.

@c Simple surfaces in three-dimensional space are isomorphic to planar surfaces.
@c Polyhedral surfaces are formed by 'stitching' together simple surfaces along
@c their boundaries, polyhedral surfaces in three-dimensional space may not be
@c planar as a whole.

@subsubheading @code{Surface} Properties

@itemize @bullet

@item
A @code{Surface} is defined as a two-dimensional geometry.

@item
The OpenGIS specification defines a simple @code{Surface} as a geometry that
consists of a single ``patch'' that is associated with a single exterior
boundary and zero or more interior boundaries.

@item
The boundary of a simple @code{Surface} is the set of closed curves
corresponding to its exterior and interior boundaries.

@end itemize


@node GIS class polygon, GIS class geometrycollection, GIS class surface, OpenGIS geometry model
@subsection Class @code{Polygon}

A @code{Polygon} is a planar @code{Surface} representing a multisided
geometry. It is defined by a single exterior boundary and zero or more
interior boundaries, where
each interior boundary defines a hole in the @code{Polygon}.

@subsubheading @code{Polygon} Examples

@itemize @bullet

@item
On a region map, @code{Polygon} objects could represent forests, districts, an
so on.

@end itemize

@subsubheading @code{Polygon} Assertions

@itemize @bullet

@item
The boundary of a @code{Polygon} consists of a set of @code{LinearRing} objects
(that is, @code{LineString} objects that are both simple and closed) that make up its
exterior and interior boundaries.

@item
A @code{Polygon} has no rings that cross. The rings in the boundary of a
@code{Polygon} may intersect at a @code{Point}, but only as a tangent.

@item
A @code{Polygon} has no lines, spikes, or punctures.

@item
A @code{Polygon} has an interior that is a connected point set.

@item
A @code{Polygon} may have holes.
The exterior of a @code{Polygon} with holes is not connected.
Each hole defines a connected component of the exterior.

@end itemize

The preceding assertions make a @code{Polygon} a simple geometry.

@c Interior, Closure and Exterior have the standard topological definitions.
@c The combination of 1 and 3 make a Polygon a Regular Closed point set.


@node GIS class geometrycollection, GIS class multipoint, GIS class polygon, OpenGIS geometry model
@subsection Class @code{GeometryCollection}

A @code{GeometryCollection} is a geometry that is a collection of one or more
geometries of any class.

All the elements in a @code{GeometryCollection} must be in
the same Spatial Reference System (that is, in the same coordinate system).
There are no other constraints on the elements of a @code{GeometryCollection},
although the
subclasses of @code{GeometryCollection} described in the following sections
may restrict membership. Restrictions may be based on:

@itemize @bullet

@item
Element type (for example, a @code{MultiPoint} may contain only @code{Point}
elements)

@item
Dimension

@item
Constraints on the degree of spatial overlap between elements

@end itemize


@node GIS class multipoint, GIS class multicurve, GIS class geometrycollection, OpenGIS geometry model
@subsection Class @code{MultiPoint}

A @code{MultiPoint} is a geometry collection composed of
@code{Point} elements. The points are not connected or ordered
in any way.

@subsubheading @code{MultiPoint} Examples

@itemize @bullet

@item
On a world map, a @code{MultiPoint} could represent a chain of small islands.

@item
On a city map, a @code{MultiPoint} could represent the outlets for a ticket
office.

@end itemize

@subsubheading @code{MultiPoint} Properties

@itemize @bullet

@item
A @code{MultiPoint} is a zero-dimensional geometry.

@item
A @code{MultiPoint} is simple if no two of its @code{Point} values are
equal (have identical coordinate values).

@item
The boundary of a @code{MultiPoint} is the empty set.

@end itemize


@node GIS class multicurve, GIS class multilinestring, GIS class multipoint, OpenGIS geometry model
@subsection Class @code{MultiCurve}

A @code{MultiCurve} is a geometry collection composed of
@code{Curve} elements. @code{MultiCurve} is a non-instantiable class.

@subsubheading @code{MultiCurve} Properties

@itemize @bullet

@item
A @code{MultiCurve} is a one-dimensional geometry.

@item
A @code{MultiCurve} is simple if and only if all of its elements are simple;
the only intersections between any two elements occur at points that are
on the boundaries of both elements.

@item
A @code{MultiCurve} boundary is obtained by applying the ``mod 2 union
rule'' (also known as the ``odd-even rule''):
A point is in the boundary of a @code{MultiCurve} if it is in the
boundaries of an odd number of @code{MultiCurve} elements.

@item
A @code{MultiCurve} is closed if all of its elements are closed.

@item
The boundary of a closed @code{MultiCurve} is always empty.

@end itemize


@node GIS class multilinestring, GIS class multisurface, GIS class multicurve, OpenGIS geometry model
@subsection Class @code{MultiLineString}

A @code{MultiLineString} is a @code{MultiCurve} geometry collection composed
of @code{LineString} elements.

@subsubheading @code{MultiLineString} Examples

@itemize @bullet

@item
On a region map, a @code{MultiLineString} could represent a river system or
a highway system.

@end itemize


@node GIS class multisurface, GIS class multipolygon, GIS class multilinestring, OpenGIS geometry model
@subsection Class @code{MultiSurface}

A @code{MultiSurface} is a geometry collection composed of surface elements.
@code{MultiSurface} is a non-instantiable class. Its only instantiable
subclass is @code{MultiPolygon}.

@subsubheading @code{MultiSurface} Assertions

@itemize @bullet

@item
Two @code{MultiSurface} surfaces have no interiors that intersect.

@item
Two @code{MultiSurface} elements have boundaries that
intersect at most at a finite number of points.

@end itemize


@node GIS class multipolygon,  , GIS class multisurface, OpenGIS geometry model
@subsection Class @code{MultiPolygon}

A @code{MultiPolygon} is a @code{MultiSurface} object composed of
@code{Polygon} elements.

@subsubheading @code{MultiPolygon} Examples

@itemize @bullet

@item
On a region map, a @code{MultiPolygon} could represent a system of lakes.

@end itemize

@subsubheading @code{MultiPolygon} Assertions

@itemize @bullet

@item
A @code{MultiPolygon} has no two @code{Polygon} elements with interiors
that intersect.

@item
A @code{MultiPolygon} has no two @code{Polygon} elements that cross
(crossing is also forbidden by the previous assertion), or that
touch at an infinite number of points.

@item
A @code{MultiPolygon} may not have cut lines, spikes, or punctures. A
@code{MultiPolygon} is a regular, closed point set.

@item
A @code{MultiPolygon} that has more than one @code{Polygon} has an
interior that is not connected. The number of connected components of the interior
of a @code{MultiPolygon} is equal to the number of @code{Polygon} values in
the @code{MultiPolygon}.

@end itemize

@subsubheading @code{MultiPolygon} Properties

@itemize @bullet

@item
A @code{MultiPolygon} is a two-dimensional geometry.

@item
A @code{MultiPolygon} boundary is a set of closed curves
(@code{LineString} values) corresponding to the boundaries of its
@code{Polygon} elements.

@item
Each @code{Curve} in the boundary of the @code{MultiPolygon} is in the
boundary of exactly one @code{Polygon} element.

@item
Every @code{Curve} in the boundary of an @code{Polygon} element is
in the boundary of the @code{MultiPolygon}.

@end itemize


@node Supported spatial data formats, Creating a spatially enabled MySQL database, OpenGIS geometry model, Spatial extensions in MySQL
@section Supported Spatial Data Formats

This section describes the standard spatial data formats that are used
to represent geometry objects in queries.
They are:

@itemize @bullet

@item Well-Known Text (WKT) format

@item Well-Known Binary (WKB) format

@end itemize

Internally, MySQL stores geometry values in a format that is not identical
to either WKT or WKB format.


@menu
* GIS WKT format::              Well-Known Text (WKT) Format
* GIS WKB format::              Well-Known Binary (WKB) Format
@end menu


@node GIS WKT format, GIS WKB format, Supported spatial data formats, Supported spatial data formats
@subsection Well-Known Text (WKT) Format

@cindex WKT format
@cindex Well-Known Text format

@c help_category WKT@Geographic features
@c description_for_help_topic WKT definition
The Well-Known Text (WKT) representation of Geometry is designed to
exchange geometry data in ASCII form.
@c end_description_for_help_topic

@c TODO: should explain the notation better, for example, to note the
@c absence of comma between X and Y coordinates.

Examples of WKT representations of geometry objects are:

@itemize @bullet

@item
A @code{Point}:

@example
POINT(15 20)
@end example

Note that point coordinates are specified with no separating comma.

@item
A @code{LineString} with four points:

@example
LINESTRING(0 0, 10 10, 20 25, 50 60)
@end example

Note that point coordinate pairs are separated by commas.

@item
A @code{Polygon} with one exterior ring and one interior ring:

@example
POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))
@end example

@item
A @code{MultiPoint} with three @code{Point} values:

@example
MULTIPOINT(0 0, 20 20, 60 60)
@end example

@item
@c TODO: change this example
A @code{MultiLineString} with two @code{LineString} values:

@example
MULTILINESTRING((10 10, 20 20), (15 15, 30 15))
@end example

@item
@c TODO: change this example
A @code{MultiPolygon} with two @code{Polygon} values:

@example
MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5)))
@end example

@item
@c TODO: change this example
A @code{GeometryCollection} consisting of two @code{Point} values and one
@code{LineString}:

@example
GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))
@end example

@end itemize

A Backus-Naur grammar that specifies the formal production rules for writing
WKT values can be found in the OGC specification document referenced near the
beginning of this chapter.

@node GIS WKB format,  , GIS WKT format, Supported spatial data formats
@subsection Well-Known Binary (WKB) Format

@cindex WKB format
@cindex Well-Known Binary format

The Well-Known Binary (WKB) representation for geometric values is defined by
the OpenGIS specifications.
It is also defined in the ISO ``SQL/MM Part 3: Spatial'' standard.

WKB is used to exchange geometry data as binary streams represented by
@code{BLOB} values containing geometric WKB information.

WKB uses one-byte unsigned integers, four-byte unsigned integers, and eight-byte
double-precision numbers (IEEE 754 format). A byte is eight bits.

For example, a WKB value that corresponds to @code{POINT(1 1)} consists of
this sequence of 21 bytes (each represented here by two hex digits):

@example
0101000000000000000000F03F000000000000F03F
@end example

The sequence may be broken down into these components:

@example
Byte order : 01
WKB type   : 01000000
X          : 000000000000F03F
Y          : 000000000000F03F
@end example

Component representation is as follows:

@itemize @bullet

@item
The byte order may be either 0 or 1 to indicate little-endian or big-endian
storage. The little-endian and big-endian byte orders are also known as
Network Data Representation (NDR) and External Data Representation (XDR),
respectively.

@item
The WKB type is a code that indicates the geometry type. Values from 1 through
7 indicate
@code{Point},
@code{LineString},
@code{Polygon},
@code{MultiPoint},
@code{MultiLineString},
@code{MultiPolygon},
and
@code{GeometryCollection}.

@item
A @code{Point} value has X and Y coordinates, each represented as a
double-precision value.

@end itemize

WKB values for more complex geometry values are represented by more complex
data structures, as detailed in the OpenGIS specification.

@node Creating a spatially enabled MySQL database, Analysing spatial information, Supported spatial data formats, Spatial extensions in MySQL
@section Creating a Spatially Enabled MySQL Database

@c TODO: It would be useful to have a simple example here of table creation
@c and row insertion, to give the reader a taste of what is to come

@c TODO: This section has examples of use, but it also contains function
@c descriptions that may be better placed in an API section.

This section describes the data types you can use for representing
spatial data in MySQL, and the functions available for creating and retrieving
spatial values.

@menu
* MySQL spatial datatypes::     MySQL Spatial Data Types
* Creating spatial values::     Creating Spatial Values
* Creating spatial columns::    Creating Spatial Columns
* Populating spatial columns::  Populating Spatial Columns
* Fetching spatial data::       Fetching Spatial Data
@end menu


@node MySQL spatial datatypes, Creating spatial values, Creating a spatially enabled MySQL database, Creating a spatially enabled MySQL database
@subsection MySQL Spatial Data Types

@tindex GEOMETRY
@tindex POINT
@tindex LINESTRING
@tindex POLYGON
@tindex MULTIPOINT
@tindex MULTILINESTRING
@tindex MULTIPOLYGON
@tindex GEOMETRYCOLLECTION

MySQL has data types that correspond to OpenGIS classes.
Some of these types hold single geometry values:

@itemize @bullet
@item @code{GEOMETRY}
@item @code{POINT}
@item @code{LINESTRING}
@item @code{POLYGON}
@end itemize

@code{GEOMETRY} can store geometry values of any type.
The other single-value types,
@code{POINT} and @code{LINESTRING} and @code{POLYGON},
restrict their values to a particular geometry type.

The other data types hold collections of values:

@itemize @bullet
@item @code{MULTIPOINT}
@item @code{MULTILINESTRING}
@item @code{MULTIPOLYGON}
@item @code{GEOMETRYCOLLECTION}
@end itemize

@code{GEOMETRYCOLLECTION} can store a collection of objects
of any type. The other collection types,
@code{MULTIPOINT} and @code{MULTILINESTRING} and @code{MULTIPOLYGON} and @code{GEOMETRYCOLLECTION},
restrict collection members to those having a particular geometry type.


@node Creating spatial values, Creating spatial columns, MySQL spatial datatypes, Creating a spatially enabled MySQL database
@subsection Creating Spatial Values

This section describes how to create spatial values using Well-Known Text
and Well-Known Binary functions that are defined in the OpenGIS standard,
and using MySQL-specific functions.

@menu
* GIS WKT Functions::           Creating Geometry Values Using WKT Functions
* GIS WKB Functions::           Creating Geometry Values Using WKB Functions
* GIS MySQL-Specific Functions::  Creating Geometry Values Using MySQL-Specific Functions
@end menu


@node GIS WKT Functions, GIS WKB Functions, Creating spatial values, Creating spatial values
@subsubsection Creating Geometry Values Using WKT Functions

MySQL provides a number of functions that take as input parameters a
Well-Known Text representation and, optionally, a spatial reference
system identifier (SRID). They return the corresponding geometry.

@code{GeomFromText()} accepts a WKT of any geometry type as its first
argument.  An implementation also provides type-specific construction
functions for construction of geometry values of each geometry type.

@c help_category WKT@Geographic features

@table @code

@c description_for_help_topic GeomCollFromText  GEOMETRYCOLLECTIONFROMTEXT
@item GeomCollFromText(@var{wkt}[,@var{srid}])
@itemx GeometryCollectionFromText(@var{wkt}[,@var{srid}])
@findex GeomCollFromText()
@findex GeometryCollectionFromText()
Constructs a @code{GEOMETRYCOLLECTION} value using its WKT representation and SRID.
@c end_description_for_help_topic

@c description_for_help_topic GeomFromText  GeometryFromText
@item GeomFromText(@var{wkt}[,@var{srid}])
@itemx GeometryFromText(@var{wkt}[,@var{srid}])
@findex GeomFromText()
@findex GeometryFromText()
Constructs a geometry value of any type using its WKT representation and SRID.
@c end_description_for_help_topic

@c description_for_help_topic LineFromText  LineStringFromText.
@item LineFromText(@var{wkt}[,@var{srid}])
@itemx LineStringFromText(@var{wkt}[,@var{srid}])
@findex LineFromText()
@findex LineStringFromText()
Constructs a @code{LINESTRING} value using its WKT representation and SRID.
@c end_description_for_help_topic

@c description_for_help_topic MLineFromText  MultiLineStringFromText
@item MLineFromText(@var{wkt}[,@var{srid}])
@itemx MultiLineStringFromText(@var{wkt}[,@var{srid}])
@findex MLineFromText()
@findex MultiLineStringFromText()
Constructs a @code{MULTILINESTRING} value using its WKT representation and SRID.
@c end_description_for_help_topic

@c description_for_help_topic MPointFromText  MultiPointFromText
@item MPointFromText(@var{wkt}[,@var{srid}])
@itemx MultiPointFromText(@var{wkt}[,@var{srid}])
@findex MPointFromText()
@findex MultiPointFromText()
Constructs a @code{MULTIPOINT} value using its WKT representation and SRID.
@c end_description_for_help_topic

@c description_for_help_topic MPolyFromText  MultiPolygonFromText
@item MPolyFromText(@var{wkt}[,@var{srid}])
@itemx MultiPolygonFromText(@var{wkt}[,@var{srid}])
@findex MPolyFromText()
@findex MultiPolygonFromText()
Constructs a @code{MULTIPOLYGON} value using its WKT representation and SRID.
@c end_description_for_help_topic

@c description_for_help_topic PointFromText
@item PointFromText(@var{wkt}[,@var{srid}])
@findex PointFromText()
Constructs a @code{POINT} value using its WKT representation and SRID.
@c end_description_for_help_topic

@c description_for_help_topic PolyFromText  PolygonFromText
@item PolyFromText(@var{wkt}[,@var{srid}])
@itemx PolygonFromText(@var{wkt}[,@var{srid}])
@findex PolyFromText()
@findex PolygonFromText()
Constructs a @code{POLYGON} value using its WKT representation and SRID.
@c end_description_for_help_topic

@end table

The OpenGIS specification also describes optional functions for constructing
@code{Polygon} or @code{MultiPolygon} values based on the WKT representation
of a collection of rings or closed @code{LineString} values. These values
may intersect.  MySQL does not implement these functions:

@table @code

@item BdMPolyFromText(@var{wkt},@var{srid})
@findex BdMPolyFromText()
Constructs a @code{MultiPolygon} value from a
@code{MultiLineString} value in WKT format containing
an arbitrary collection of closed @code{LineString} values.

@item BdPolyFromText(@var{wkt},@var{srid})
@findex BdPolyFromText()
Constructs a @code{Polygon} value from a
@code{MultiLineString} value in WKT format containing
an arbitrary collection of closed @code{LineString} values.

@end table


@node GIS WKB Functions, GIS MySQL-Specific Functions, GIS WKT Functions, Creating spatial values
@subsubsection Creating Geometry Values Using WKB Functions

MySQL provides a number of functions that take as input parameters a
@code{BLOB} containing a Well-Known Binary representation
and, optionally, a spatial reference
system identifier (SRID). They return the corresponding geometry.

@code{GeomFromWKT()} accepts a WKB of any geometry type as its first
argument.  An implementation also provides type-specific construction
functions for construction of geometry values of each geometry type.

@c help_category WKB@Geographic features

@table @code

@c description_for_help_topic GeomCollFromWKB  GeometryCollectionFromWKB
@item GeomCollFromWKB(@var{wkb}[,@var{srid}])
@itemx GeometryCollectionFromWKB(@var{wkt}[,@var{srid}])
@findex GeomCollFromWKB()
@findex GeometryCollectionFromWKB()
Constructs a @code{GEOMETRYCOLLECTION} value using its WKB representation and SRID.
@c end_description_for_help_topic

@c description_for_help_topic GeomFromWKB  GeometryFromWKB
@item GeomFromWKB(@var{wkb}[,@var{srid}])
@itemx GeometryFromWKB(@var{wkt}[,@var{srid}])
@findex GeomFromWKB()
@findex GeometryFromWKB()
Constructs a geometry value of any type using its WKB representation and SRID.
@c end_description_for_help_topic

@c description_for_help_topic LineFromWKB  LineStringFromWKB
@item LineFromWKB(@var{wkb}[,@var{srid}])
@itemx LineStringFromWKB(@var{wkb}[,@var{srid}])
@findex LineFromWKB()
@findex LineStringFromWKB()
Constructs a @code{LINESTRING} value using its WKB representation and SRID.
@c end_description_for_help_topic

@c description_for_help_topic MLineFromWKB  MultiLineStringFromWKB
@item MLineFromWKB(@var{wkb}[,@var{srid}])
@itemx MultiLineStringFromWKB(@var{wkb}[,@var{srid}])
@findex MLineFromWKB()
@findex MultiLineStringFromWKB()
Constructs a @code{MULTILINESTRING} value using its WKB representation and SRID.
@c end_description_for_help_topic

@c description_for_help_topic MPointFromWKB  MultiPointFromWKB
@item MPointFromWKB(@var{wkb}[,@var{srid}])
@itemx MultiPointFromWKB(@var{wkb}[,@var{srid}])
@findex MPointFromWKB()
@findex MultiPointFromWKB()
Constructs a @code{MULTIPOINT} value using its WKB representation and SRID.
@c end_description_for_help_topic

@c description_for_help_topic MPolyFromWKB  MultiPolygonFromWKB
@item MPolyFromWKB(@var{wkb}[,@var{srid}])
@itemx MultiPolygonFromWKB(@var{wkb}[,@var{srid}])
@findex MPolyFromWKB()
@findex MultiPolygonFromWKB()
Constructs a @code{MULTIPOLYGON} value using its WKB representation and SRID.
@c end_description_for_help_topic

@c description_for_help_topic PointFromWKB
@item PointFromWKB(@var{wkb}[,@var{srid}])
@findex PointFromWKB()
Constructs a @code{POINT} value using its WKB representation and SRID.
@c end_description_for_help_topic

@c description_for_help_topic PolyFromWKB  PolygonFromWKB
@item PolyFromWKB(@var{wkb}[,@var{srid}])
@itemx PolygonFromWKB(@var{wkb}[,@var{srid}])
@findex PolyFromWKB()
@findex PolygonFromWKB()
Constructs a @code{POLYGON} value using its WKB representation and SRID.
@c end_description_for_help_topic

@end table

The OpenGIS specification also describes optional functions for constructing
@code{Polygon} or @code{MultiPolygon} values based on the WKB representation
of a collection of rings or closed @code{LineString} values. These values
may intersect.  MySQL does not implement these functions:

@table @code

@item BdMPolyFromWKB(@var{wkb},@var{srid})
@findex BdMPolyFromWKB()
Constructs a @code{MultiPolygon} value from a
@code{MultiLineString} value in WKB format containing
an arbitrary collection of closed @code{LineString} values.

@item BdPolyFromWKB(@var{wkb},@var{srid})
@findex BdPolyFromWKB()
Constructs a @code{Polygon} value from a
@code{MultiLineString} value in WKB format containing
an arbitrary collection of closed @code{LineString} values.

@end table


@node GIS MySQL-Specific Functions,  , GIS WKB Functions, Creating spatial values
@subsubsection Creating Geometry Values Using MySQL-Specific Functions

@strong{Note}: MySQL does not implement the functions listed in this
section.

MySQL provides a set of useful functions for creating geometry WKB
representations. The functions described in this section are MySQL
extensions to the OpenGIS specifications. The results of these
functions are @code{BLOB} values containing WKB representations of geometry
values with no SRID.
The results of these functions can be substituted as the first argument
for any function in the @code{GeomFromWKB()} function family.

@table @code

@c help_category Geometry constructors@Geographic features

@c description_for_help_topic GEOMETRYCOLLECTION
@item GeometryCollection(@var{g1},@var{g2},...)
@findex GeometryCollection()
Constructs a WKB @code{GeometryCollection}. If any argument is not a
well-formed WKB representation of a geometry, the return value is
@code{NULL}.
@c end_description_for_help_topic

@c description_for_help_topic LINESTRING
@item LineString(@var{pt1},@var{pt2},...)
@findex LineString()
Constructs a WKB @code{LineString} value from a number of WKB @code{Point}
arguments.  If any argument is not a WKB @code{Point}, the return value
is @code{NULL}.  If the number of @code{Point} arguments is less than two,
the return value is @code{NULL}.
@c end_description_for_help_topic

@c description_for_help_topic MULTILINESTRING
@item MultiLineString(@var{ls1},@var{ls2},...)
@findex MultiLineString()
Constructs a WKB @code{MultiLineString} value using using WKB @code{LineString}
arguments.  If any argument is not a WKB @code{LineString}, the return
value is @code{NULL}.
@c end_description_for_help_topic

@c description_for_help_topic MULTIPOINT
@item MultiPoint(@var{pt1},@var{pt2},...)
@findex MultiPoint()
Constructs a WKB @code{MultiPoint} value using WKB @code{Point} arguments.
If any argument is not a WKB @code{Point}, the return value is @code{NULL}.
@c end_description_for_help_topic

@c description_for_help_topic MULTIPOLYGON
@item MultiPolygon(@var{poly1},@var{poly2},...)
@findex MultiPolygon()
Constructs a WKB @code{MultiPolygon} value from a set of WKB @code{Polygon}
arguments.
If any argument is not a WKB @code{Polygon}, the rerurn value is @code{NULL}.
@c end_description_for_help_topic

@c description_for_help_topic POINT
@item Point(@var{x},@var{y})
@findex Point()
Constructs a WKB @code{Point} using its coordinates.
@c end_description_for_help_topic

@c description_for_help_topic POLYGON
@item Polygon(@var{ls1},@var{ls2},...)
@findex Polygon()
Constructs a WKB @code{Polygon} value from a number of WKB @code{LineString}
arguments. If any argument does not represent the WKB of a @code{LinearRing}
(that is, not a closed and simple @code{LineString}) the return value
is @code{NULL}.
@c end_description_for_help_topic

@end table


@node Creating spatial columns, Populating spatial columns, Creating spatial values, Creating a spatially enabled MySQL database
@subsection Creating Spatial Columns

@c help_category Geographic features

@c description_for_help_topic GEOMETRY
MySQL provides a standard way of creating spatial columns for
geometry types, for example, with @code{CREATE TABLE} or @code{ALTER TABLE}.
Currently, spatial columns are supported only for @code{MyISAM} tables.
@c end_description_for_help_topic

@itemize @bullet

@item
Use the @code{CREATE TABLE} statement to create a table with a spatial column:

@c example_for_help_topic GEOMETRY
@example
mysql> CREATE TABLE geom (g GEOMETRY);
Query OK, 0 rows affected (0.02 sec)
@end example

@item
Use the @code{ALTER TABLE} statement to add or drop a spatial column to or
from an existing table:

@example
mysql> ALTER TABLE geom ADD pt POINT;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> ALTER TABLE geom DROP pt;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0
@end example

@end itemize


@node Populating spatial columns, Fetching spatial data, Creating spatial columns, Creating a spatially enabled MySQL database
@subsection Populating Spatial Columns

After you have created spatial columns, you can populate them
with spatial data.

Values should be stored in internal geometry format, but you can convert them
to that format from either Well-Known Text (WKT) or Well-Known Binary (WKB)
format. The following examples demonstrate how to insert geometry values into
a table by converting WKT values into internal geometry format.

You can perform the conversion directly in the @code{INSERT} statement:

@example
INSERT INTO geom VALUES (GeomFromText('POINT(1 1)'));

SET @@g = 'POINT(1 1)';
INSERT INTO geom VALUES (GeomFromText(@@g));
@end example

Or you can perform the conversion prior to the @code{INSERT}:

@example
SET @@g = GeomFromText('POINT(1 1)');
INSERT INTO geom VALUES (@@g);
@end example

The following examples insert more complex geometries into the table:

@example
SET @@g = 'LINESTRING(0 0,1 1,2 2)';
INSERT INTO geom VALUES (GeomFromText(@@g));

SET @@g = 'POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))';
INSERT INTO geom VALUES (GeomFromText(@@g));

SET @@g =
'GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))';
INSERT INTO geom VALUES (GeomFromText(@@g));
@end example

The preceding examples all use @code{GeomFromText()} to create geometry
values.  You can also use type-specific functions:

@example
SET @@g = 'POINT(1 1)';
INSERT INTO geom VALUES (PointFromText(@@g));

SET @@g = 'LINESTRING(0 0,1 1,2 2)';
INSERT INTO geom VALUES (LineStringFromText(@@g));

SET @@g = 'POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))';
INSERT INTO geom VALUES (PolygonFromText(@@g));

SET @@g =
'GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))';
INSERT INTO geom VALUES (GeomCollFromText(@@g));
@end example

Note that if a client application program wants to use WKB representations
of geometry values, it is responsible for sending correctly formed WKB in
queries to the server. However, there are several ways of satisfying this
requirement. For example:

@itemize @bullet

@item Inserting a @code{POINT(1 1)} value with hex literal syntax:
@example
mysql> INSERT INTO geom VALUES
    -> (GeomFromWKB(0x0101000000000000000000F03F000000000000F03F));
@end example

@item An ODBC application can send a WKB representation, binding it to a
placeholder using an argument of @code{BLOB} type:
@example
INSERT INTO geom VALUES (GeomFromWKB(?))
@end example

Other programming interfaces may support a similar placeholder mechanism.

@item In a C program, you can escape a binary value using
@code{mysql_real_escape_string()} and include the result in a query string
that is sent to the server.
@xref{mysql_real_escape_string, , @code{mysql_real_escape_string()}}.

@end itemize


@node Fetching spatial data,  , Populating spatial columns, Creating a spatially enabled MySQL database
@subsection Fetching Spatial Data

Geometry values stored in a table can be fetched in internal
format. You can also convert them into WKT or WKB format.

@menu
* Fetching spatial data in internal format::  Fetching Spatial Data in Internal Format
* Fetching spatial data in WKT format::  Fetching Spatial Data in WKT Format
* Fetching spatial data in WKB format::  Fetching Spatial Data in WKB Format
@end menu


@node Fetching spatial data in internal format, Fetching spatial data in WKT format, Fetching spatial data, Fetching spatial data
@subsubsection Fetching Spatial Data in Internal Format

Fetching geometry values using internal format can be useful in
table-to-table transfers:

@example
CREATE TABLE geom2 (g GEOMETRY) SELECT g FROM geom;
@end example


@node Fetching spatial data in WKT format, Fetching spatial data in WKB format, Fetching spatial data in internal format, Fetching spatial data
@subsubsection Fetching Spatial Data in WKT Format

The @code{AsText()} function converts a geometry from internal format into a WKT string.

@c help_category WKT@Geographic features

@c example_for_help_topic AsText
@example
mysql> SELECT AsText(g) FROM geom;
+-------------------------+
| AsText(p1)              |
+-------------------------+
| POINT(1 1)              |
| LINESTRING(0 0,1 1,2 2) |
+-------------------------+
@end example


@node Fetching spatial data in WKB format,  , Fetching spatial data in WKT format, Fetching spatial data
@subsubsection Fetching Spatial Data in WKB Format

The @code{AsBinary()} function converts a geometry from internal format into a @code{BLOB} containing
the WKB value.

@c help_category WKB@Geographic features
@c example_for_help_topic AsBinary
@example
SELECT AsBinary(g) FROM geom;
@end example


@node Analysing spatial information, Optimizing spatial analysis, Creating a spatially enabled MySQL database, Spatial extensions in MySQL
@section Analyzing Spatial Information


@menu
* Functions to convert geometries between formats::  Geometry Format Conversion Functions
* Geometry property functions::  @code{Geometry} Functions
* Functions that create new geometries from existing ones::  Functions That Create New Geometries from Existing Ones
* Functions for testing spatial relations between geometric objects::  Functions for Testing Spatial Relations Between Geometric Objects
* Relations on geometry MBR::   Relations on Geometry Minimal Bounding Rectangles (MBRs)
* Functions that test spatial relationships between geometries::  Functions That Test Spatial Relationships Between Geometries
@end menu


After populating spatial columns with values, you are ready to
query and analyze them.  MySQL provides a set of functions to
perform various operations on spatial data. These functions can be
grouped into four major categories according to the type of operation
they perform:

@itemize @bullet

@item
Functions that convert geometries between various formats

@item
Functions that provide access to qualitative or quantitative properties of a geometry

@item
Functions that describe relations between two geometries

@item
Functions that create new geometries from existing ones

@end itemize

Spatial analysis functions can be used in many contexts, such as:

@itemize @bullet

@item
Any interactive SQL program, such as @command{mysql} or @command{MySQLCC}

@item
Application programs written in any language that supports a MySQL client API

@end itemize


@node Functions to convert geometries between formats, Geometry property functions, Analysing spatial information, Analysing spatial information
@subsection Geometry Format Conversion Functions

MySQL supports the following functions for converting geometry values between
internal format and either WKT or WKB format:

@table @code

@c help_category WKB@Geographic features

@c description_for_help_topic AsBinary
@item AsBinary(@var{g})
@findex AsBinary()
Converts a value in internal geometry format to its WKB representation
and returns the binary result.
@c end_description_for_help_topic

@c help_category WKT@Geographic features

@c description_for_help_topic AsText
@item AsText(@var{g})
@findex AsText()
Converts a value in internal geometry format to its WKT representation
and returns the string result.
@c end_description_for_help_topic

@example
mysql> SET @@g = 'LineString(1 1,2 2,3 3)';
mysql> SELECT AsText(GeomFromText(@@g));
+--------------------------+
| AsText(GeomFromText(@@G)) |
+--------------------------+
| LINESTRING(1 1,2 2,3 3)  |
+--------------------------+
@end example

@item GeomFromText(@var{wkt}[,@var{srid}])
@findex GeomFromText()
Converts a string value from its WKT representation into internal geometry
format and returns the result.
A number of type-specific functions are also supported, such as
@code{PointFromText()} and @code{LineFromText()}; see
@ref{GIS WKT Functions}.

@item GeomFromWKB(@var{wkb}[,@var{srid}])
@findex GeomFromWKB()
Converts a binary value from its WKB representation into internal geometry
format and returns the result.
A number of type-specific functions are also supported, such as
@code{PointFromWKB()} and @code{LineFromWKB()}; see
@ref{GIS WKB Functions}.

@end table


@node Geometry property functions, Functions that create new geometries from existing ones, Functions to convert geometries between formats, Analysing spatial information
@subsection @code{Geometry} Functions

Each function that belongs to this group takes a geometry value as its
argument and returns some quantitative or qualitative property of the
geometry. Some functions restrict their argument type. Such functions
return @code{NULL} if the argument is of an incorrect geometry
type.  For example, @code{Area()} returns @code{NULL} if the object
type is neither @code{Polygon} nor @code{MultiPolygon}.


@menu
* General geometry property functions::  General Geometry Functions
* Point property functions::    @code{Point} Functions
* Linestring property functions::  @code{LineString} Functions
* Multilinestring property functions::  @code{MultiLineString} Functions
* Polygon property functions::  @code{Polygon} Functions
* Multipolygon property functions::  @code{MultiPolygon} Functions
* Geometrycollection property functions::  @code{GeometryCollection} Functions
@end menu


@node General geometry property functions, Point property functions, Geometry property functions, Geometry property functions
@subsubsection General Geometry Functions

The functions listed in this section do not restrict their argument and
accept a geometry value of any type.

@table @code

@c help_category Geometry properties@Geographic features

@c description_for_help_topic Dimension
@item Dimension(@var{g})
@findex Dimension()
Returns the inherent dimension of the geometry value @var{g}. The result
can be @minus{}1, 0, 1, or 2. (The meaning of these values is given in
@ref{GIS class geometry}.)
@c end_description_for_help_topic

@c example_for_help_topic Dimension
@example
mysql> SELECT Dimension(GeomFromText('LineString(1 1,2 2)'));
+------------------------------------------------+
| Dimension(GeomFromText('LineString(1 1,2 2)')) |
+------------------------------------------------+
|                                              1 |
+------------------------------------------------+
@end example

@c description_for_help_topic Envelope
@item Envelope(@var{g})
@findex Envelope()
Returns the Minimum Bounding Rectangle (MBR) for the geometry value @var{g}.
The result is returned as a @code{Polygon} value.

@c example_for_help_topic Envelope
@example
mysql> SELECT AsText(Envelope(GeomFromText('LineString(1 1,2 2)')));
+-------------------------------------------------------+
| AsText(Envelope(GeomFromText('LineString(1 1,2 2)'))) |
+-------------------------------------------------------+
| POLYGON((1 1,2 1,2 2,1 2,1 1))                        |
+-------------------------------------------------------+
@end example

The polygon is defined by the corner points of the bounding box:

@example
POLYGON((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))
@end example
@c end_description_for_help_topic

@c description_for_help_topic GeometryType
@item GeometryType(@var{g})
@findex GeometryType()
Returns as a string the name of the geometry type of which
the geometry instance @var{g} is a member.
The name will correspond to one of the instantiable @code{Geometry} subclasses.
@c end_description_for_help_topic

@c example_for_help_topic GeometryType
@example
mysql> SELECT GeometryType(GeomFromText('POINT(1 1)'));
+------------------------------------------+
| GeometryType(GeomFromText('POINT(1 1)')) |
+------------------------------------------+
| POINT                                    |
+------------------------------------------+
@end example

@c description_for_help_topic SRID
@item SRID(@var{g})
@findex SRID()
Returns an integer indicating the Spatial Reference System ID for the geometry
value @var{g}.

In MySQL, the SRID value is just an integer associated with the geometry
value. All calculations are done assuming Euclidean (planar) geometry.
@c end_description_for_help_topic

@c example_for_help_topic SRID
@example
mysql> SELECT SRID(GeomFromText('LineString(1 1,2 2)',101));
+-----------------------------------------------+
| SRID(GeomFromText('LineString(1 1,2 2)',101)) |
+-----------------------------------------------+
|                                           101 |
+-----------------------------------------------+
@end example

@end table


The OpenGIS specification also defines the following functions, which MySQL
does not implement:

@table @code

@c description_for_help_topic Boundary
@item Boundary(@var{g})
@findex Boundary()
Returns a geometry that is the closure of the combinatorial boundary of the
geometry value @var{g}.
@c end_description_for_help_topic

@c description_for_help_topic IsEmpty
@item IsEmpty(@var{g})
@findex IsEmpty()
Returns 1 if the geometry value @var{g} is the empty geometry, 0 if it is not
empty, and @minus{}1 if the argument is @code{NULL}.
If the geometry is empty, it represents the empty point set.
@c end_description_for_help_topic

@c description_for_help_topic IsSimple
@item IsSimple(@var{g})
@findex IsSimple()

Currently, this function is a placeholder and should not be used.
If implemented, its behavior will be as described in the next paragraph.

Returns 1 if the geometry value @var{g} has no anomalous geometric points,
such as self-intersection or self-tangency. @code{IsSimple()} returns 0 if the
argument is not simple, and @minus{}1 if it is @code{NULL}.

The description of each instantiable geometric class given earlier in
the chapter includes the specific conditions that cause an instance of
that class to be classified as not simple.
@c end_description_for_help_topic

@end table

@c help_category Point properties@Geographic features

@node Point property functions, Linestring property functions, General geometry property functions, Geometry property functions
@subsubsection @code{Point} Functions

A @code{Point} consists of X and Y coordinates, which may be obtained
using the following functions:

@table @code

@c description_for_help_topic X
@item X(@var{p})
@findex X()
Returns the X-coordinate value for the point @var{p} as a double-precision
number.
@c end_description_for_help_topic
@c example_for_help_topic X
@example
mysql> SELECT X(GeomFromText('Point(56.7 53.34)'));
+--------------------------------------+
| X(GeomFromText('Point(56.7 53.34)')) |
+--------------------------------------+
|                                 56.7 |
+--------------------------------------+
@end example

@c description_for_help_topic Y
@item Y(@var{p})
@findex Y()
Returns the Y-coordinate value for the point @var{p} as a double-precision
number.
@c end_description_for_help_topic
@c example_for_help_topic Y
@example
mysql> SELECT Y(GeomFromText('Point(56.7 53.34)'));
+--------------------------------------+
| Y(GeomFromText('Point(56.7 53.34)')) |
+--------------------------------------+
|                                53.34 |
+--------------------------------------+
@end example

@end table


@node Linestring property functions, Multilinestring property functions, Point property functions, Geometry property functions
@subsubsection @code{LineString} Functions

A @code{LineString} consists of @code{Point} values. You can extract
particular points of a @code{LineString}, count the number of points that it
contains, or obtain its length.

@c help_category LineString properties@Geographic features

@table @code

@c description_for_help_topic EndPoint
@item EndPoint(@var{ls})
@findex EndPoint()
Returns the @code{Point} that is the end point of the @code{LineString} value
@var{ls}.
@c end_description_for_help_topic

@c example_for_help_topic EndPoint
@example
mysql> SET @@ls = 'LineString(1 1,2 2,3 3)';
mysql> SELECT AsText(EndPoint(GeomFromText(@@ls)));
+-------------------------------------+
| AsText(EndPoint(GeomFromText(@@ls))) |
+-------------------------------------+
| POINT(3 3)                          |
+-------------------------------------+
@end example

@c description_for_help_topic GLength
@item GLength(@var{ls})
@findex GLength()
Returns as a double-precision number the length of the @code{LineString}
value @var{ls} in its associated spatial reference.
@c end_description_for_help_topic

@c example_for_help_topic GLength
@example
mysql> SET @@ls = 'LineString(1 1,2 2,3 3)';
mysql> SELECT GLength(GeomFromText(@@ls));
+----------------------------+
| GLength(GeomFromText(@@ls)) |
+----------------------------+
|            2.8284271247462 |
+----------------------------+
@end example

@c description_for_help_topic IsClosed
@item IsClosed(@var{ls})
@findex IsClosed()
Returns 1 if the @code{LineString} value @var{ls} is closed
(that is, its @code{StartPoint()} and @code{EndPoint()} values are the same).
Returns 0 if @var{ls} is not closed, and @minus{}1 if it is @code{NULL}.
@c end_description_for_help_topic

@c example_for_help_topic IsClosed
@example
mysql> SET @@ls = 'LineString(1 1,2 2,3 3)';
mysql> SELECT IsClosed(GeomFromText(@@ls));
+-----------------------------+
| IsClosed(GeomFromText(@@ls)) |
+-----------------------------+
|                           0 |
+-----------------------------+
@end example

@c description_for_help_topic NumPoints
@item NumPoints(@var{ls})
@findex NumPoints()
Returns the number of points in the @code{LineString} value @var{ls}.
@c end_description_for_help_topic

@c example_for_help_topic NumPoints
@example
mysql> SET @@ls = 'LineString(1 1,2 2,3 3)';
mysql> SELECT NumPoints(GeomFromText(@@ls));
+------------------------------+
| NumPoints(GeomFromText(@@ls)) |
+------------------------------+
|                            3 |
+------------------------------+
@end example

@c description_for_help_topic PointN
@item PointN(@var{ls},@var{n})
@findex PointN()
Returns the @var{n}-th point in the @code{Linestring} value @var{ls}.
Point numbers begin at 1.
@c end_description_for_help_topic

@c example_for_help_topic PointN
@example
mysql> SET @@ls = 'LineString(1 1,2 2,3 3)';
mysql> SELECT AsText(PointN(GeomFromText(@@ls),2));
+-------------------------------------+
| AsText(PointN(GeomFromText(@@ls),2)) |
+-------------------------------------+
| POINT(2 2)                          |
+-------------------------------------+
@end example

@c description_for_help_topic StartPoint
@item StartPoint(@var{ls})
@findex StartPoint()
Returns the @code{Point} that is the start point of the @code{LineString} value
@var{ls}.
@c end_description_for_help_topic

@c example_for_help_topic StartPoint
@example
mysql> SET @@ls = 'LineString(1 1,2 2,3 3)';
mysql> SELECT AsText(StartPoint(GeomFromText(@@ls)));
+---------------------------------------+
| AsText(StartPoint(GeomFromText(@@ls))) |
+---------------------------------------+
| POINT(1 1)                            |
+---------------------------------------+
@end example

@end table

The OpenGIS specification also defines the following function, which MySQL
does not implement:

@table @code

@item IsRing(@var{ls})
@findex IsRing()
Returns 1 if the @code{LineString} value @var{ls} is closed
(that is, its @code{StartPoint()} and @code{EndPoint()} values are the same)
and is simple (does not pass through the same point more than once).
Returns 0 if @var{ls} is not a ring, and @minus{}1 if it is @code{NULL}.

@end table


@node Multilinestring property functions, Polygon property functions, Linestring property functions, Geometry property functions
@subsubsection @code{MultiLineString} Functions

@c TODO: Add introductory descriptive sentence.

@table @code

@item GLength(@var{mls})
@findex GLength()
Returns as a double-precision number
the length of the @code{MultiLineString} value @var{mls}. The length of
@var{mls} is equal to the sum of the lengths of its elements.

@example
mysql> SET @@mls = 'MultiLineString((1 1,2 2,3 3),(4 4,5 5))';
mysql> SELECT GLength(GeomFromText(@@mls));
+-----------------------------+
| GLength(GeomFromText(@@mls)) |
+-----------------------------+
|             4.2426406871193 |
+-----------------------------+
@end example

@item IsClosed(@var{mls})
@findex IsClosed()
Returns 1 if the @code{MultiLineString} value @var{mls} is closed
(that is, the @code{StartPoint()} and @code{EndPoint()} values are the same
for each @code{LineString} in @var{mls}).
Returns 0 if @var{mls} is not closed, and @minus{}1 if it is @code{NULL}.

@example
mysql> SET @@mls = 'MultiLineString((1 1,2 2,3 3),(4 4,5 5))';
mysql> SELECT IsClosed(GeomFromText(@@mls));
+------------------------------+
| IsClosed(GeomFromText(@@mls)) |
+------------------------------+
|                            0 |
+------------------------------+
@end example

@end table


@node Polygon property functions, Multipolygon property functions, Multilinestring property functions, Geometry property functions
@subsubsection @code{Polygon} Functions

@c TODO: Add introductory descriptive sentence.

@c help_category Polygon properties@Geographic features

@table @code

@c description_for_help_topic Area
@item Area(@var{poly})
@findex Area()
Returns as a double-precision number the area of the @code{Polygon} value
@var{poly}, as measured in its spatial reference system.
@c end_description_for_help_topic

@c example_for_help_topic Area
@example
mysql> SET @@poly = 'Polygon((0 0,0 3,3 0,0 0),(1 1,1 2,2 1,1 1))';
mysql> SELECT Area(GeomFromText(@@poly));
+---------------------------+
| Area(GeomFromText(@@poly)) |
+---------------------------+
|                         4 |
+---------------------------+
@end example

@c description_for_help_topic ExteriorRing
@item ExteriorRing(@var{poly})
@findex ExteriorRing()
Returns the exterior ring of the @code{Polygon} value @var{poly}
as a @code{LineString}.
@c end_description_for_help_topic
@c example_for_help_topic ExteriorRing
@example
mysql> SET @@poly =
    -> 'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';
mysql> SELECT AsText(ExteriorRing(GeomFromText(@@poly)));
+-------------------------------------------+
| AsText(ExteriorRing(GeomFromText(@@poly))) |
+-------------------------------------------+
| LINESTRING(0 0,0 3,3 3,3 0,0 0)           |
+-------------------------------------------+
@end example

@c description_for_help_topic InteriorRingN
@item InteriorRingN(@var{poly},@var{n})
@findex InteriorRingN()
Returns the @var{n}-th interior ring for the @code{Polygon} value
@var{poly} as a @code{LineString}.
Ring numbers begin at 1.
@c end_description_for_help_topic
@c example_for_help_topic InteriorRingN
@example
mysql> SET @@poly =
    -> 'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';
mysql> SELECT AsText(InteriorRingN(GeomFromText(@@poly),1));
+----------------------------------------------+
| AsText(InteriorRingN(GeomFromText(@@poly),1)) |
+----------------------------------------------+
| LINESTRING(1 1,1 2,2 2,2 1,1 1)              |
+----------------------------------------------+
@end example

@c description_for_help_topic NumInteriorRings
@item NumInteriorRings(@var{poly})
@findex NumInteriorRings()
Returns the number of interior rings in the @code{Polygon} value @var{poly}.
@c end_description_for_help_topic
@c example_for_help_topic NumInteriorRings
@example
mysql> SET @@poly =
    -> 'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';
mysql> SELECT NumInteriorRings(GeomFromText(@@poly));
+---------------------------------------+
| NumInteriorRings(GeomFromText(@@poly)) |
+---------------------------------------+
|                                     1 |
+---------------------------------------+
@end example

@end table

@node Multipolygon property functions, Geometrycollection property functions, Polygon property functions, Geometry property functions
@subsubsection @code{MultiPolygon} Functions

@c TODO: Add introductory descriptive sentence.

@table @code

@item Area(@var{mpoly})
@findex Area()

Returns as a double-precision number the area of the @code{MultiPolygon}
value @var{mpoly}, as measured in its spatial reference system.

@example
mysql> SET @@mpoly =
    -> 'MultiPolygon(((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1)))';
mysql> SELECT Area(GeomFromText(@@mpoly));
+----------------------------+
| Area(GeomFromText(@@mpoly)) |
+----------------------------+
|                          8 |
+----------------------------+
@end example

@end table


The OpenGIS specification also defines the following functions, which MySQL
does not implement:

@table @code

@item Centroid(@var{mpoly})
@findex Centroid()
Returns the mathematical centroid for the @code{MultiPolygon} value
@var{mpoly} as a @code{Point}.  The result is not guaranteed to be on
the @code{MultiPolygon}.

@item PointOnSurface(@var{mpoly})
@findex PointOnSurface()
Returns a @code{Point} value that is guaranteed to be on the
@code{MultiPolygon} value @var{mpoly}.

@end table

@c help_category GeometryCollection properties@Geographic features

@node Geometrycollection property functions,  , Multipolygon property functions, Geometry property functions
@subsubsection @code{GeometryCollection} Functions

@c TODO: Add introductory descriptive sentence.

@table @code

@c description_for_help_topic GeometryN
@item GeometryN(@var{gc},@var{n})
@findex GeometryN()
Returns the @var{n}-th geometry in the @code{GeometryCollection} value
@var{gc}.  Geometry numbers begin at 1.
@c end_description_for_help_topic

@c example_for_help_topic GeometryN
@example
mysql> SET @@gc = 'GeometryCollection(Point(1 1),LineString(2 2, 3 3))';
mysql> SELECT AsText(GeometryN(GeomFromText(@@gc),1));
+----------------------------------------+
| AsText(GeometryN(GeomFromText(@@gc),1)) |
+----------------------------------------+
| POINT(1 1)                             |
+----------------------------------------+
@end example

@c description_for_help_topic NumGeometries
@item NumGeometries(@var{gc})
@findex NumGeometries()
Returns the number of geometries in the @code{GeometryCollection} value
@var{gc}.
@c end_description_for_help_topic

@c example_for_help_topic NumGeometries
@example
mysql> SET @@gc = 'GeometryCollection(Point(1 1),LineString(2 2, 3 3))';
mysql> SELECT NumGeometries(GeomFromText(@@gc));
+----------------------------------+
| NumGeometries(GeomFromText(@@gc)) |
+----------------------------------+
|                                2 |
+----------------------------------+
@end example

@end table


@node Functions that create new geometries from existing ones, Functions for testing spatial relations between geometric objects, Geometry property functions, Analysing spatial information
@subsection Functions That Create New Geometries from Existing Ones

@c TODO: Add introductory descriptive sentence.


@menu
* Functions that produce new geometries::  Geometry Functions That Produce New Geometries
* Spatial operators::           Spatial Operators
@end menu

@node Functions that produce new geometries, Spatial operators, Functions that create new geometries from existing ones, Functions that create new geometries from existing ones
@subsubsection Geometry Functions That Produce New Geometries

In the section @ref{Geometry property functions},
we've already discussed some functions that can construct new geometries
from the existing ones:

@itemize @bullet
@item @code{Envelope(@var{g})}
@item @code{StartPoint(@var{ls})}
@item @code{EndPoint(@var{ls})}
@item @code{PointN(@var{ls},@var{n})}
@item @code{ExteriorRing(@var{poly})}
@item @code{InteriorRingN(@var{poly},@var{n})}
@item @code{GeometryN(@var{gc},@var{n})}
@end itemize


@node Spatial operators,  , Functions that produce new geometries, Functions that create new geometries from existing ones
@subsubsection Spatial Operators

OpenGIS proposes a number of other functions that can produce
geometries. They are designed to implement spatial operators.

These functions are not implemented in MySQL.
They may appear in future releases.

@table @code

@item Buffer(@var{g},@var{d})
@findex Buffer()
Returns a geometry that represents all points whose distance from the geometry
value @var{g} is less than or equal to a distance of @var{d}.

@item ConvexHull(@var{g})
@findex ConvexHull()
Returns a geometry that represents the convex hull of the geometry value
@var{g}.

@item Difference(@var{g1},@var{g2})
@findex Difference()
Returns a geometry that represents the point set difference of the geometry
value @var{g1} with @var{g2}.

@item Intersection(@var{g1},@var{g2})
@findex Intersection()
Returns a geometry that represents the point set intersection of the geometry
values @var{g1} with @var{g2}.

@item SymDifference(@var{g1},@var{g2})
@findex SymDifference()
Returns a geometry that represents the point set symmetric difference of the
geometry value @var{g1} with @var{g2}.

@item Union(@var{g1},@var{g2})
@findex Union()
Returns a geometry that represents the point set union of the geometry values
@var{g1} and @var{g2}.

@end table


@node Functions for testing spatial relations between geometric objects, Relations on geometry MBR, Functions that create new geometries from existing ones, Analysing spatial information
@subsection Functions for Testing Spatial Relations Between Geometric Objects

The functions described in these sections take two geometries as input
parameters and return a qualitative or quantitative relation between them.

@node Relations on geometry MBR, Functions that test spatial relationships between geometries, Functions for testing spatial relations between geometric objects, Analysing spatial information
@subsection Relations on Geometry Minimal Bounding Rectangles (MBRs)

@cindex MBR
@cindex Minimum Bounding Rectangle

@c help_category MBR@Geographic features

MySQL provides some functions that can test relations
between minimal bounding rectangles of two geometries @code{g1} and @code{g2}.
They include:

@table @code

@c description_for_help_topic MBRContains
@item MBRContains(@var{g1},@var{g2})
@findex MBRContains()
Returns 1 or 0 to indicate whether or not the Minimum Bounding Rectangle of
@var{g1} contains the Minimum Bounding Rectangle of @var{g2}.
@c end_description_for_help_topic

@c example_for_help_topic MBRContains
@example
mysql> SET @@g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
mysql> SET @@g2 = GeomFromText('Point(1 1)');
mysql> SELECT MBRContains(@@g1,@@g2), MBRContains(@@g2,@@g1);
----------------------+----------------------+
| MBRContains(@@g1,@@g2) | MBRContains(@@g2,@@g1) |
+----------------------+----------------------+
|                    1 |                    0 |
+----------------------+----------------------+
@end example

@c description_for_help_topic MBRDisjoint
@item MBRDisjoint(@var{g1},@var{g2})
@findex MBRDisjoint()
Returns 1 or 0 to indicate whether or not the Minimum Bounding Rectangles of
the two geometries @var{g1} and @var{g2} are disjoint (do not intersect).
@c end_description_for_help_topic

@c description_for_help_topic MBREqual
@item MBREqual(@var{g1},@var{g2})
@findex MBREqual()
Returns 1 or 0 to indicate whether or not the Minimum Bounding Rectangles of
the two geometries @var{g1} and @var{g2} are the same.
@c end_description_for_help_topic

@c description_for_help_topic MBRIntersects
@item MBRIntersects(@var{g1},@var{g2})
@findex MBRIntersects()
Returns 1 or 0 to indicate whether or not the Minimum Bounding Rectangles of
the two geometries @var{g1} and @var{g2} intersect.
@c end_description_for_help_topic

@c description_for_help_topic MBROverlaps
@item MBROverlaps(@var{g1},@var{g2})
@findex MBROverlaps()
Returns 1 or 0 to indicate whether or not the Minimum Bounding Rectangles of
the two geometries @var{g1} and @var{g2} overlap.
@c end_description_for_help_topic

@c description_for_help_topic MBRTouches
@item MBRTouches(@var{g1},@var{g2})
@findex MBRTouches()
Returns 1 or 0 to indicate whether or not the Minimum Bounding Rectangles of
the two geometries @var{g1} and @var{g2} touch.
@c end_description_for_help_topic

@c description_for_help_topic MBRWithin
@item MBRWithin(@var{g1},@var{g2})
@findex MBRWithin()
Returns 1 or 0 to indicate whether or not the Minimum Bounding Rectangle
of @var{g1} is within the Minimum Bounding Rectangle of @var{g2}.
@c end_description_for_help_topic

@c example_for_help_topic MBRWithin
@example
mysql> SET @@g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
mysql> SET @@g2 = GeomFromText('Polygon((0 0,0 5,5 5,5 0,0 0))');
mysql> SELECT MBRWithin(@@g1,@@g2), MBRWithin(@@g2,@@g1);
+--------------------+--------------------+
| MBRWithin(@@g1,@@g2) | MBRWithin(@@g2,@@g1) |
+--------------------+--------------------+
|                  1 |                  0 |
+--------------------+--------------------+
@end example

@end table


@node Functions that test spatial relationships between geometries,  , Relations on geometry MBR, Analysing spatial information
@subsection Functions That Test Spatial Relationships Between Geometries

The OpenGIS specification defines the following functions. Currently,
MySQL does not implement them according to the specification. Those that
are implemented return the same result as the corresponding
MBR-based functions.  This includes functions in the following list
other than @code{Distance()} and @code{Related()}.

@c TODO: Crosses() is an exception here: It exists but MBRCrosses() does not.

These functions may be implemented in future releases with full
support for spatial analysis, not just MBR-based support.

The functions operate on two geometry values @code{g1} and @code{g2}.

@table @code

@c help_category Geometry relations@Geographic features

@c description_for_help_topic Contains
@item Contains(@var{g1},@var{g2})
@findex Contains()
Returns 1 or 0 to indicate whether or not @var{g1} completely contains
@var{g2}.
@c end_description_for_help_topic

@c description_for_help_topic Crosses
@item Crosses(@var{g1},@var{g2})
@findex Crosses()
Returns 1 if @var{g1} spatially crosses @var{g2}.
Returns @code{NULL} if @code{g1} is a @code{Polygon} or a @code{MultiPolygon},
or if @var{g2} is a @code{Point} or a @code{MultiPoint}.
Otherwise, returns 0.

The term @emph{spatially crosses} denotes a spatial relation between two given
geometries that has the following properties:

@itemize @bullet

@item
The two geometries intersect

@item
Their intersection results in a geometry that has
a dimension that is one less than the maximum dimension of the two given
geometries

@item
Their intersection is not equal to either of the two given geometries

@end itemize
@c end_description_for_help_topic

@c description_for_help_topic Disjoint
@item Disjoint(@var{g1},@var{g2})
@findex Disjoint()
Returns 1 or 0 to indicate whether or not @var{g1} is spatially disjoint
from (does not intersect) @var{g2}.
@c end_description_for_help_topic

@c description_for_help_topic Distance
@item Distance(@var{g1},@var{g2})
@findex Distance()
Returns as a double-precision number
the shortest distance between any two points in the two geometries.
@c end_description_for_help_topic

@c description_for_help_topic Equals
@item Equals(@var{g1},@var{g2})
@findex Equals()
Returns 1 or 0 to indicate whether or not @var{g1} is spatially equal to
@var{g2}.
@c end_description_for_help_topic

@c description_for_help_topic Intersects
@item Intersects(@var{g1},@var{g2})
@findex Intersects()
Returns 1 or 0 to indicate whether or not @var{g1} spatially intersects
@var{g2}.
@c end_description_for_help_topic

@c description_for_help_topic Overlaps
@item Overlaps(@var{g1},@var{g2})
@findex Overlaps()
Returns 1 or 0 to indicate whether or not @var{g1} spatially overlaps
@var{g2}.
The term @emph{spatially overlaps} is used if two
geometries intersect and their intersection results in a geometry of the
same dimension but not equal to either of the given geometries.
@c end_description_for_help_topic

@c description_for_help_topic Related
@item Related(@var{g1},@var{g2},@var{pattern_matrix})
@findex Related()
Returns 1 or 0 to indicate whether or not the spatial relationship specified
by @var{pattern_matrix} exists between @var{g1} and @var{g2}.
Returns @minus{}1 if the arguments are @code{NULL}.
The pattern matrix is a string. Its specification will be noted here if this
function is implemented.
@c end_description_for_help_topic

@c description_for_help_topic Touches
@item Touches(@var{g1},@var{g2})
@findex Touches()
Returns 1 or 0 to indicate whether or not @var{g1} spatially touches
@var{g2}. Two geometries @emph{spatially touch} if the interiors of
the geometries do not intersect, but the boundary of one of the geometries
intersects either the boundary or the interior of the other.
@c end_description_for_help_topic

@c description_for_help_topic Within
@item Within(@var{g1},@var{g2})
@findex Within()
Returns 1 or 0 to indicate whether or not @var{g1} is spatially within
@var{g2}.
@c end_description_for_help_topic

@end table


@node Optimizing spatial analysis, MySQL GIS conformance and compatibility, Analysing spatial information, Spatial extensions in MySQL
@section Optimizing Spatial Analysis

Search operations in non-spatial databases can be optimized
using indexes. This is true for spatial databases as well.
With the help of a great variety of multi-dimensional indexing methods that
have already been designed, it is possible to optimize
spatial searches. The most typical of these are:

@itemize @bullet

@item Point queries that search for all objects that contain a given point

@item Region queries that search for all objects that overlap a given region

@end itemize

MySQL uses @strong{R-Trees with quadratic splitting} to index
spatial columns. A spatial index is built using the MBR of a geometry.
For most geometries, the MBR is a minimum rectangle that
surrounds the geometries. For a horizontal or a vertical
linestring, the MBR is a rectangle degenerated into the linestring.
For a point, the MBR is a rectangle degenerated into the point.


@menu
* Creating spatial indexes::    Creating Spatial Indexes
* Using a spatial index::       Using a Spatial Index
@end menu

@node Creating spatial indexes, Using a spatial index, Optimizing spatial analysis, Optimizing spatial analysis
@subsection Creating Spatial Indexes

@c help_category Geographic features
@c description_for_help_topic SPATIAL  INDEX TABLE ALTER CREATE ADD KEY
MySQL can create spatial indexes using syntax similar to that for creating
regular indexes, but extended with the @code{SPATIAL} keyword.
Spatial columns that are indexed currently must be declared @code{NOT NULL}.
The following examples demonstrate how to create spatial indexes.

@itemize @bullet

@item With @code{CREATE TABLE}:

@example
mysql> CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g));
@end example

@item With @code{ALTER TABLE}:

@example
mysql> ALTER TABLE geom ADD SPATIAL INDEX(g);
@end example

@item With @code{CREATE INDEX}:

@example
mysql> CREATE SPATIAL INDEX sp_index ON geom (g);
@end example

@end itemize

To drop spatial indexes, use @code{ALTER TABLE} or @code{DROP INDEX}:

@itemize @bullet

@item With @code{ALTER TABLE}:

@example
mysql> ALTER TABLE geom DROP INDEX g;
@end example

@item With @code{DROP INDEX}:

@example
mysql> DROP INDEX sp_index ON geom;
@end example

@end itemize

Example: Suppose that a table @code{geom} contains more than 32,000 geometries,
which are stored in the column @code{g} of type @code{GEOMETRY}.
The table also has an @code{AUTO_INCREMENT} column @code{fid} for storing
object ID values.
@c end_description_for_help_topic

@example
mysql> DESCRIBE geom;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| fid   | int(11)  |      | PRI | NULL    | auto_increment |
| g     | geometry |      |     |         |                |
+-------+----------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> SELECT COUNT(*) FROM geom;
+----------+
| count(*) |
+----------+
|    32376 |
+----------+
1 row in set (0.00 sec)
@end example


To add a spatial index on the column @code{g}, use this statement:
@example
mysql> ALTER TABLE geom ADD SPATIAL INDEX(g);
Query OK, 32376 rows affected (4.05 sec)
Records: 32376  Duplicates: 0  Warnings: 0
@end example


@node Using a spatial index,  , Creating spatial indexes, Optimizing spatial analysis
@subsection Using a Spatial Index

The optimizer investigates whether available spatial indexes can
be involved in the search for queries that use a function such as
@code{MBRContains()} or @code{MBRWithin()} in the @code{WHERE} clause.
For example, let's say we want to find all objects that are in the
given rectangle:

@example
mysql> SELECT fid,AsText(g) FROM geom WHERE
mysql> MBRContains(GeomFromText('Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))'),g);
+-----+-----------------------------------------------------------------------------+
| fid | AsText(g)                                                                   |
+-----+-----------------------------------------------------------------------------+
|  21 | LINESTRING(30350.4 15828.8,30350.6 15845,30333.8 15845,30333.8 15828.8)     |
|  22 | LINESTRING(30350.6 15871.4,30350.6 15887.8,30334 15887.8,30334 15871.4)     |
|  23 | LINESTRING(30350.6 15914.2,30350.6 15930.4,30334 15930.4,30334 15914.2)     |
|  24 | LINESTRING(30290.2 15823,30290.2 15839.4,30273.4 15839.4,30273.4 15823)     |
|  25 | LINESTRING(30291.4 15866.2,30291.6 15882.4,30274.8 15882.4,30274.8 15866.2) |
|  26 | LINESTRING(30291.6 15918.2,30291.6 15934.4,30275 15934.4,30275 15918.2)     |
| 249 | LINESTRING(30337.8 15938.6,30337.8 15946.8,30320.4 15946.8,30320.4 15938.4) |
|   1 | LINESTRING(30250.4 15129.2,30248.8 15138.4,30238.2 15136.4,30240 15127.2)   |
|   2 | LINESTRING(30220.2 15122.8,30217.2 15137.8,30207.6 15136,30210.4 15121)     |
|   3 | LINESTRING(30179 15114.4,30176.6 15129.4,30167 15128,30169 15113)           |
|   4 | LINESTRING(30155.2 15121.4,30140.4 15118.6,30142 15109,30157 15111.6)       |
|   5 | LINESTRING(30192.4 15085,30177.6 15082.2,30179.2 15072.4,30194.2 15075.2)   |
|   6 | LINESTRING(30244 15087,30229 15086.2,30229.4 15076.4,30244.6 15077)         |
|   7 | LINESTRING(30200.6 15059.4,30185.6 15058.6,30186 15048.8,30201.2 15049.4)   |
|  10 | LINESTRING(30179.6 15017.8,30181 15002.8,30190.8 15003.6,30189.6 15019)     |
|  11 | LINESTRING(30154.2 15000.4,30168.6 15004.8,30166 15014.2,30151.2 15009.8)   |
|  13 | LINESTRING(30105 15065.8,30108.4 15050.8,30118 15053,30114.6 15067.8)       |
| 154 | LINESTRING(30276.2 15143.8,30261.4 15141,30263 15131.4,30278 15134)         |
| 155 | LINESTRING(30269.8 15084,30269.4 15093.4,30258.6 15093,30259 15083.4)       |
| 157 | LINESTRING(30128.2 15011,30113.2 15010.2,30113.6 15000.4,30128.8 15001)     |
+-----+-----------------------------------------------------------------------------+
20 rows in set (0.00 sec)
@end example


Now let's use @code{EXPLAIN} to check the way this query is executed (the
@code{id} column has been removed so the output better fits the page):
@example
mysql> EXPLAIN SELECT fid,AsText(g) FROM geom WHERE
mysql> MBRContains(GeomFromText('Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))'),g);
+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| SIMPLE      | geom  | range | g             | g    |      32 | NULL |   50 | Using where |
+-------------+-------+-------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
@end example


Now let's check what would happen without a spatial index:
@example
mysql> EXPLAIN SELECT fid,AsText(g) FROM g IGNORE INDEX (g) WHERE
mysql> MBRContains(GeomFromText('Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))'),g);
+-------------+-------+------+---------------+------+---------+------+-------+-------------+
| select_type | table | type | possible_keys | key  | key_len | ref  | rows  | Extra       |
+-------------+-------+------+---------------+------+---------+------+-------+-------------+
| SIMPLE      | geom  | ALL  | NULL          | NULL |    NULL | NULL | 32376 | Using where |
+-------------+-------+------+---------------+------+---------+------+-------+-------------+
1 row in set (0.00 sec)
@end example


Let's execute the @code{SELECT} statement, ignoring the spatial key we have:

@example
mysql> SELECT fid,AsText(g) FROM geom IGNORE INDEX (g) WHERE
mysql> MBRContains(GeomFromText('Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))'),g);
+-----+-----------------------------------------------------------------------------+
| fid | AsText(g)                                                                   |
+-----+-----------------------------------------------------------------------------+
|   1 | LINESTRING(30250.4 15129.2,30248.8 15138.4,30238.2 15136.4,30240 15127.2)   |
|   2 | LINESTRING(30220.2 15122.8,30217.2 15137.8,30207.6 15136,30210.4 15121)     |
|   3 | LINESTRING(30179 15114.4,30176.6 15129.4,30167 15128,30169 15113)           |
|   4 | LINESTRING(30155.2 15121.4,30140.4 15118.6,30142 15109,30157 15111.6)       |
|   5 | LINESTRING(30192.4 15085,30177.6 15082.2,30179.2 15072.4,30194.2 15075.2)   |
|   6 | LINESTRING(30244 15087,30229 15086.2,30229.4 15076.4,30244.6 15077)         |
|   7 | LINESTRING(30200.6 15059.4,30185.6 15058.6,30186 15048.8,30201.2 15049.4)   |
|  10 | LINESTRING(30179.6 15017.8,30181 15002.8,30190.8 15003.6,30189.6 15019)     |
|  11 | LINESTRING(30154.2 15000.4,30168.6 15004.8,30166 15014.2,30151.2 15009.8)   |
|  13 | LINESTRING(30105 15065.8,30108.4 15050.8,30118 15053,30114.6 15067.8)       |
|  21 | LINESTRING(30350.4 15828.8,30350.6 15845,30333.8 15845,30333.8 15828.8)     |
|  22 | LINESTRING(30350.6 15871.4,30350.6 15887.8,30334 15887.8,30334 15871.4)     |
|  23 | LINESTRING(30350.6 15914.2,30350.6 15930.4,30334 15930.4,30334 15914.2)     |
|  24 | LINESTRING(30290.2 15823,30290.2 15839.4,30273.4 15839.4,30273.4 15823)     |
|  25 | LINESTRING(30291.4 15866.2,30291.6 15882.4,30274.8 15882.4,30274.8 15866.2) |
|  26 | LINESTRING(30291.6 15918.2,30291.6 15934.4,30275 15934.4,30275 15918.2)     |
| 154 | LINESTRING(30276.2 15143.8,30261.4 15141,30263 15131.4,30278 15134)         |
| 155 | LINESTRING(30269.8 15084,30269.4 15093.4,30258.6 15093,30259 15083.4)       |
| 157 | LINESTRING(30128.2 15011,30113.2 15010.2,30113.6 15000.4,30128.8 15001)     |
| 249 | LINESTRING(30337.8 15938.6,30337.8 15946.8,30320.4 15946.8,30320.4 15938.4) |
+-----+-----------------------------------------------------------------------------+
20 rows in set (0.46 sec)
@end example

When the index is not used, the execution time for this query rises from
0.00 seconds to 0.46 seconds.

In future releases, spatial indexes may also be used for optimizing
other functions.
@xref{Functions for testing spatial relations between geometric objects}.


@node MySQL GIS conformance and compatibility,  , Optimizing spatial analysis, Spatial extensions in MySQL
@section MySQL Conformance and Compatibility

@c TODO: Add introductory descriptive sentence.

@menu
* GIS features that are not yet implemented::  GIS Features That Are Not Yet Implemented
@end menu

@node GIS features that are not yet implemented,  , MySQL GIS conformance and compatibility, MySQL GIS conformance and compatibility
@subsection GIS Features That Are Not Yet Implemented

@table @asis

@item Additional Metadata Views
OpenGIS specifications propose several additional metadata views.
For example, a system view named @code{GEOMETRY_COLUMNS} contains a
description of geometry columns, one row for each geometry column
in the database.

@c @item Functions to add/drop spatial columns
@c OpenGIS assumes that columns can be added or dropped using special
@c @code{AddGeometryColumn()} and @code{DropGeometryColumn()}
@c functions. In MySQL, this is done using the @code{ALTER TABLE},
@c @code{CREATE INDEX}, and @code{DROP INDEX} statements instead.

@c @item Factors related to Spatial Reference Systems and their IDs (SRIDs):

@c @itemize @bullet

@c @item
@c Functions like @code{Length()} and @code{Area()} assume a planar
@c coordinate system.

@c @item
@c All objects currently are considered to be in the same planar
@c coordinate system.

@c @end itemize

@item The OpenGIS function @code{Length()} on @code{LineString} and @code{MultiLineString} currently should be called in MySQL as @code{GLength()}
The problem is that there is an existing SQL function
@code{Length()} which calculates the length of string values,
and sometimes it is not possible to distinguish whether the function is
called in a textual or spatial context. We need either to solve this
somehow, or decide on another function name.
@end table


@c @node GIS writing a GIS application
@c @section Writing a GIS Application


@c @node GIS Java GIS Object Model
@c @section Java GIS Object Model
@c for Mark!


@node Stored Procedures, Triggers, Spatial extensions in MySQL, Top
@chapter Stored Procedures and Functions

@cindex stored procedures
@cindex procedures, stored

Stored procedures and functions are a new feature in MySQL version 5.0.
A stored procedure is a set of SQL statements that can be stored in the server.
Once this has been done, clients don't need to keep reissuing the individual
statements but can refer to the stored procedure instead.

Some situations where stored procedures can be particularly useful:
@itemize @bullet
@item
When multiple client applications are written in different languages or work
on different platforms, but need to perform the same database operations.
@item
When security is paramount. Banks, for example, use stored procedures for
all common operations. This provides a consistent and secure environment,
and procedures can ensure that each operation is properly logged.
In such a setup, applications and users would not get any access to the
database tables directly, but can only execute specific stored procedures.
@end itemize

Stored procedures can provide improved performance because less information
needs to be sent between the server and the client. The tradeoff is that
this does increase the load on the database server system because more of
the work is done on the server side and less is done on the client
(application) side. Consider this if many client machines (such as
Web servers) are serviced by only one or a few database servers.

Stored procedures also allow you to have libraries of functions in the
database server. This is a feature shared by modern application languages
that allow such design internally, for example, by using classes. Using
these client application language features is beneficial for the programmer
even outside the scope of database use.

MySQL follows the SQL:2003 syntax for stored procedures, which is also used
by IBM's DB2.

The MySQL implementation of stored procedures is still in progress. All
syntax described in this chapter is supported and any limitations and
extensions are documented where appropriate.

Stored procedures require the @code{proc} table in the @code{mysql} database.
This table is created during the MySQL 5.0 installation procedure.
If you are upgrading to MySQL 5.0 from an earlier version, be sure to update
your grant tables to make sure that the @code{proc} table exists.
@xref{Upgrading-grant-tables}.


@menu
* Stored Procedure Syntax::     Stored Procedure Syntax
@end menu

@node Stored Procedure Syntax,  , Stored Procedures, Stored Procedures
@section Stored Procedure Syntax

Stored procedures and functions are routines that are created with
@code{CREATE PROCEDURE} and @code{CREATE FUNCTION} statements.
A routine is either a procedure or a function.
A procedure is invoked using a @code{CALL} statement, and can only
pass back values using output variables.  A function can be called from
inside a statement just like any other function (that is, by invoking the
function's name), and can return a scalar value.
Stored routines may call other stored routines.

As of MySQL 5.0.1, a stored procedure or function is associated with a
particular database. This has several implications:

@itemize @bullet

@item
When the routine is invoked, an implicit @code{USE
@var{db_name}} is performed (and undone when the routine terminates).
@code{USE} statements within stored routines are disallowed.

@item
You can qualify routine names with the database name. This can be used
to refer to a routine that is not in the current database.
For example, to invoke a stored procedure @code{p} or function @code{f}
that is associated with the @code{test} database, you can say
@code{CALL test.p()} or @code{test.f()}.

@item
When a database is dropped, all stored routines associated with it are
dropped as well.

@end itemize

(In MySQL 5.0.0, stored routines are global and not associated with
a database. They inherit the default database from the caller.  If a
@code{USE @var{db_name}} is executed within the routine, the original default
database is restored upon routine exit.)

MySQL supports the very useful extension that allows the use of regular
@code{SELECT} statements (that is, without using cursors or local variables)
inside a stored procedure. The result set of such a query is simply sent
directly to the client.
Multiple @code{SELECT} statements generate multiple result sets, so the client
must use a MySQL client library that supports multiple result sets. This means
the client must use a client library from a version of MySQL at least as
recent as 4.1.

This following section describes the syntax used to create, alter, drop, and
query stored procedures and functions.

@menu
* Maintaining Stored Procedures::  Maintaining Stored Procedures
* SHOW PROCEDURE STATUS::       @code{SHOW PROCEDURE STATUS} and @code{SHOW FUNCTION STATUS}
* CALL::                        @code{CALL} Statement
* BEGIN END::                   @code{BEGIN ... END} Compound Statement
* DECLARE::                     @code{DECLARE} Statement
* Variables in Stored Procedures::  Variables in Stored Procedures
* Conditions and Handlers::     Conditions and Handlers
* Cursors::                     Cursors
* Flow Control Constructs::     Flow Control Constructs
@end menu

@node Maintaining Stored Procedures, SHOW PROCEDURE STATUS, Stored Procedure Syntax, Stored Procedure Syntax
@subsection Maintaining Stored Procedures



@menu
* CREATE PROCEDURE::            @code{CREATE PROCEDURE} and @code{CREATE FUNCTION}
* ALTER PROCEDURE::             @code{ALTER PROCEDURE} and @code{ALTER FUNCTION}
* DROP PROCEDURE::              @code{DROP PROCEDURE} and @code{DROP FUNCTION}
* SHOW CREATE PROCEDURE::       @code{SHOW CREATE PROCEDURE} and @code{SHOW CREATE FUNCTION}
@end menu

@node CREATE PROCEDURE, ALTER PROCEDURE, Maintaining Stored Procedures, Maintaining Stored Procedures
@subsubsection @code{CREATE PROCEDURE} and @code{CREATE FUNCTION}

@findex CREATE PROCEDURE
@findex CREATE FUNCTION

@example
CREATE PROCEDURE @var{sp_name} ([@var{parameter}[,...]])
    [@var{characteristic} ...] @var{routine_body}

CREATE FUNCTION @var{sp_name} ([@var{parameter}[,...]])
    RETURNS @var{type}
    [@var{characteristic} ...] @var{routine_body}

@var{parameter}:
    [ IN | OUT | INOUT ] @var{param_name} @var{type}

@var{type}:
    @var{Any valid MySQL data type}

@var{characteristic}:
    LANGUAGE SQL
  | [NOT] DETERMINISTIC
  | SQL SECURITY @{DEFINER | INVOKER@}
  | COMMENT '@var{string}'

@var{routine_body}:
    @var{Valid SQL procedure statements or statements}
@end example

By default, the routine is associated with the current database. To associate
the routine explicitly with a given database, specify the name as
@var{db_name.sp_name} when you create it.

If the routine name is the same as the name of a built-in SQL function, you
will need to use a space between the name and the following parenthesis when
defining the routine, or a syntax error will occur. This is also true when you
invoke the routine later.

The @code{RETURNS} clause may be specified only for a @code{FUNCTION},
for which it is mandatory.
It is used to indicate the return type of the function, and the function
body must contain a @code{RETURN value} statement.

The parameter list enclosed within parentheses must always be present.
If there are no parameters, an empty parameter list of @code{()} should
be used.  Each parameter is an @code{IN} parameter by default. To specify
otherwise for a parameter, use the keyword @code{OUT} or @code{INOUT} before
the parameter name. Specifying @code{IN}, @code{OUT}, or @code{INOUT} is only
valid for a @code{PROCEDURE}.

The @code{CREATE FUNCTION} statement is used in
earlier versions of MySQL to support UDFs (User Defined Functions).
@xref{Adding functions}.
UDFs continue to be supported, even with the existence of stored functions.
A UDF can be regarded as an external stored function.  However, do
note that stored functions share their namespace with UDFs.

A framework for external stored procedures will be introduced in the near
future. This will allow you to write stored procedures in languages other
than SQL.
Most likely, one of the first languages to be supported will be PHP because the
core PHP engine is small, thread-safe, and can easily be embedded. Because the
framework will be public, it is expected that many other languages will also
be supported.

A function is considered ``deterministic'' if it always returns the same
result for the same input parameters, and ``not deterministic'' otherwise.
Currently, the @code{DETERMINISTIC} characteristic is accepted, but not yet
used by the optimizer.

The @code{SQL SECURITY} characteristic can be used to specify whether the
routine should be executed using the permissions of the user who creates
the routine or the user who invokes it.
The default value is @code{DEFINER}.
This feature is new in SQL:2003.
The creator or invoker must have permission to access the database with which
the routine is associated.

MySQL does not yet use the @code{GRANT EXECUTE} privilege.

MySQL stores the @code{sql_mode} system variable setting that is in effect
at the time a routine is created, and will always execute the routine with
this setting in force.

The @code{COMMENT} clause is a MySQL extension, and may be used to describe
the stored procedure. This information is displayed by the
@code{SHOW CREATE PROCEDURE} and @code{SHOW CREATE FUNCTION} statements.

MySQL allows routines to contain DDL statements (such as @code{CREATE} and
 @code{DROP}) and SQL transaction statements (such as @code{COMMIT}). This is
not required by the standard and is therefore implementation-specific.

@strong{Note}:
Currently, stored functions created with @code{CREATE FUNCTION} may not
contain references to tables.  Please note that this includes some @code{SET}
statements, but excludes some @code{SELECT} statements.  This limitation
will be lifted as soon as possible.

The following is an example of a simple stored procedure that uses
an @code{OUT} parameter.
The example uses the @command{mysql} client @code{delimiter} command to change
the statement delimiter from @code{;} to @code{//} while the procedure is
being defined.
This allows the @code{;} delimiter used in the procedure body to be passed
through to the server rather than being interpreted by @command{mysql} itself.

@example
mysql> delimiter //

mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)
    -> BEGIN
    ->   SELECT COUNT(*) INTO param1 FROM t;
    -> END
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;

mysql> CALL simpleproc(@@a);
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@a;
+------+
| @@a   |
+------+
| 3    |
+------+
1 row in set (0.00 sec)
@end example


The following is an example of a function that takes a parameter,
performs an operation using an SQL function, and returns the result:

@example
mysql> delimiter //

mysql> CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50)
    -> RETURN CONCAT('Hello, ',s,'!');
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;

mysql> SELECT hello('world');
+----------------+
| hello('world') |
+----------------+
| Hello, world!  |
+----------------+
1 row in set (0.00 sec)
@end example


@node ALTER PROCEDURE, DROP PROCEDURE, CREATE PROCEDURE, Maintaining Stored Procedures
@subsubsection @code{ALTER PROCEDURE} and @code{ALTER FUNCTION}

@findex ALTER PROCEDURE
@findex ALTER FUNCTION

@example
ALTER @{PROCEDURE | FUNCTION@} @var{sp_name} [@var{characteristic} ...]

@var{characteristic}:
    SQL SECURITY @{DEFINER | INVOKER@}
  | COMMENT '@var{string}'
@end example

This statement can be used to rename a stored procedure or function, and to
change its characteristics. More than one change may be specified in an
@code{ALTER PROCEDURE} or @code{ALTER FUNCTION} statement.


@node DROP PROCEDURE, SHOW CREATE PROCEDURE, ALTER PROCEDURE, Maintaining Stored Procedures
@subsubsection @code{DROP PROCEDURE} and @code{DROP FUNCTION}

@findex DROP PROCEDURE
@findex DROP FUNCTION

@example
DROP @{PROCEDURE | FUNCTION@} [IF EXISTS] @var{sp_name}
@end example

This statement is used to drop a stored procedure or function. That is, the
specified routine is removed from the server.

The @code{IF EXISTS} clause is a MySQL extension.
It prevents an error from occurring if the procedure or function does not
exist. A warning is produced that can be viewed with @code{SHOW WARNINGS}.


@node SHOW CREATE PROCEDURE,  , DROP PROCEDURE, Maintaining Stored Procedures
@subsubsection @code{SHOW CREATE PROCEDURE} and @code{SHOW CREATE FUNCTION}

@findex SHOW CREATE PROCEDURE
@findex SHOW CREATE FUNCTION

@example
SHOW CREATE @{PROCEDURE | FUNCTION@} @var{sp_name}
@end example

This statement is a MySQL extension. Similar to @code{SHOW CREATE TABLE}, it
returns the exact string that can be used to re-create the named routine.

@example
mysql> SHOW CREATE FUNCTION test.hello\G
*************************** 1. row ***************************
       Function: hello
       sql_mode: 
Create Function: CREATE FUNCTION `test`.`hello`(s CHAR(20)) RETURNS CHAR(50)
RETURN CONCAT('Hello, ',s,'!')
@end example


@node SHOW PROCEDURE STATUS, CALL, Maintaining Stored Procedures, Stored Procedure Syntax
@subsection @code{SHOW PROCEDURE STATUS} and @code{SHOW FUNCTION STATUS}

@findex SHOW PROCEDURE STATUS
@findex SHOW FUNCTION STATUS

@example
SHOW @{PROCEDURE | FUNCTION@} STATUS [LIKE '@var{pattern}']
@end example

This statement is a MySQL extension. It returns characteristics of routines,
such as the database, name, type, creator, and creation and modification dates. If no
pattern is specified, the information for all stored procedures or all stored
functions is listed, depending on which statement you use.

@example
mysql> SHOW FUNCTION STATUS LIKE 'hello'\G
*************************** 1. row ***************************
           Db: test
         Name: hello
         Type: FUNCTION
      Definer: testuser@@localhost
     Modified: 2004-08-03 15:29:37
      Created: 2004-08-03 15:29:37
Security_type: DEFINER
      Comment: 
@end example


@node CALL, BEGIN END, SHOW PROCEDURE STATUS, Stored Procedure Syntax
@subsection @code{CALL} Statement

@findex CALL

@example
CALL @var{sp_name}([@var{parameter}[,...]])
@end example

The @code{CALL} statement is used to invoke a procedure that was defined
previously with @code{CREATE PROCEDURE}.

@code{CALL} can return values through its parameters. It also ``returns''
the number of rows affected, which a client program can obtain at the SQL
level by calling the @code{ROW_COUNT()} function and from C by calling the
@code{mysql_affected_rows()} C API function.


@node BEGIN END, DECLARE, CALL, Stored Procedure Syntax
@subsection @code{BEGIN ... END} Compound Statement

@findex BEGIN
@findex END

@example
[@var{begin_label}:] BEGIN
    [@var{statement_list}]
END [@var{end_label}]
@end example

Stored routines may contain multiple statements, using a
@code{BEGIN ... END} compound statement.

@var{begin_label} and @var{end_label} must be the same, if both are
specified.

Please note that the optional @code{[NOT] ATOMIC} clause is not yet
supported. This means that no transactional savepoint is set at the start of
the instruction block and the @code{BEGIN} clause used in this context has
no effect on the current transaction.

Using multiple statements requires that a client is able to send query
strings containing the @code{;} statement delimiter. This is handled in the
@command{mysql} command-line client with the @code{delimiter} command. Changing
the @code{;} end-of-query delimiter (for example, to @code{//}) allows
@code{;} to be used in a routine body.


@node DECLARE, Variables in Stored Procedures, BEGIN END, Stored Procedure Syntax
@subsection @code{DECLARE} Statement

@findex DECLARE

The @code{DECLARE} statement is used to define various items local to a
routine:
local variables (@pxref{Variables in Stored Procedures}),
conditions and handlers (@pxref{Conditions and Handlers}) and
cursors (@pxref{Cursors}).
@code{SIGNAL} and @code{RESIGNAL} statements are not currently supported.

@code{DECLARE} may be used only inside a @code{BEGIN ... END} compound
statement and must be at its start, before any other statements.

Cursors must be declared before declaring handlers, and variables must be
be declared before declaring either cursors or handlers.


@node Variables in Stored Procedures, Conditions and Handlers, DECLARE, Stored Procedure Syntax
@subsection Variables in Stored Procedures

You may declare and use variables within a routine.


@menu
* DECLARE Local Variables::     @code{DECLARE} Local Variables
* SET Statement::               Variable @code{SET} Statement
* SELECT INTO Statement::       @code{SELECT ... INTO} Statement
@end menu

@node DECLARE Local Variables, SET Statement, Variables in Stored Procedures, Variables in Stored Procedures
@subsubsection @code{DECLARE} Local Variables

@example
DECLARE @var{var_name}[,...] @var{type} [DEFAULT @var{value}]
@end example

This statement is used to declare local variables. The scope of a variable is
within the @code{BEGIN ... END} block.


@node SET Statement, SELECT INTO Statement, DECLARE Local Variables, Variables in Stored Procedures
@subsubsection Variable @code{SET} Statement

@findex SET

@example
SET @var{var_name} = @var{expr} [, @var{var_name} = @var{expr}] ...
@end example

The @code{SET} statement in stored procedures is an extended version of
the general @code{SET} statement. Referenced variables may be ones declared
inside a routine, or global server variables.

The @code{SET} statement in stored procedures is implemented as part of the
pre-existing @code{SET} syntax. This allows an extended syntax of
@code{SET a=x, b=y, ...} where different variable types (locally declared
variables, server variables, and global and session server variables) can be
mixed. This also allows combinations of local variables and some options
that make sense only for global/system variables; in that case, the options
are accepted but ignored.


@node SELECT INTO Statement,  , SET Statement, Variables in Stored Procedures
@subsubsection @code{SELECT ... INTO} Statement

@findex SELECT INTO

@example
SELECT @var{col_name}[,...] INTO @var{var_name}[,...] @var{table_expr}
@end example

This @code{SELECT} syntax stores selected columns directly into variables.
Therefore, only a single row may be retrieved. This statement is also
extremely useful when used in combination with cursors.

@example
SELECT id,data INTO x,y FROM test.t1 LIMIT 1;
@end example


@node Conditions and Handlers, Cursors, Variables in Stored Procedures, Stored Procedure Syntax
@subsection Conditions and Handlers

Certain conditions may require specific handling. These conditions can relate
to errors, as well as general flow control inside a routine.


@menu
* DECLARE Conditions::          @code{DECLARE} Conditions
* DECLARE Handlers::            @code{DECLARE} Handlers
@end menu

@node DECLARE Conditions, DECLARE Handlers, Conditions and Handlers, Conditions and Handlers
@subsubsection @code{DECLARE} Conditions

@cindex Conditions

@example
DECLARE @var{condition_name} CONDITION FOR @var{condition_value}

@var{condition_value}:
    SQLSTATE [VALUE] @var{sqlstate_value}
  | @var{mysql_error_code}
@end example

This statement specifies conditions that will need
specific handling. It associates a name with a specified error
condition. The name can subsequently be used in a
@code{DECLARE HANDLER} statement.
@xref{DECLARE Handlers,  , @code{DECLARE} Handlers}.

In addition to SQLSTATE values, MySQL error codes are also supported.


@node DECLARE Handlers,  , DECLARE Conditions, Conditions and Handlers
@subsubsection @code{DECLARE} Handlers

@cindex Handlers

@example
DECLARE @var{handler_type} HANDLER FOR @var{condition_value}[,...] @var{sp_statement}

@var{handler_type}:
    CONTINUE
  | EXIT
  | UNDO

@var{condition_value}:
    SQLSTATE [VALUE] @var{sqlstate_value}
  | @var{condition_name}
  | SQLWARNING
  | NOT FOUND
  | SQLEXCEPTION
  | @var{mysql_error_code}
@end example

This statement specifies handlers that each may deal with
one or more conditions. If one of these conditions occurs, the specified
statement is executed.

For a @code{CONTINUE} handler, execution of the current routine continues
after execution of the handler statement.
For an @code{EXIT} handler, execution of the current @code{BEGIN...END}
compound statement is terminated.
The @code{UNDO} handler type statement is not yet supported.

@itemize @bullet
@item
@code{SQLWARNING} is shorthand for all SQLSTATE codes that begin with @code{01}.
@item
@code{NOT FOUND} is shorthand for all SQLSTATE codes that begin with @code{02}.
@item
@code{SQLEXCEPTION} is shorthand for all SQLSTATE codes not caught by
@code{SQLWARNING} or @code{NOT FOUND}.
@end itemize

In addition to SQLSTATE values, MySQL error codes are also supported.


For example:

@example
mysql> CREATE TABLE test.t (s1 int,primary key (s1));
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter //

mysql> CREATE PROCEDURE handlerdemo ()
    -> BEGIN
    ->   DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @@x2 = 1;
    ->   SET @@x = 1;
    ->   INSERT INTO test.t VALUES (1);
    ->   SET @@x = 2;
    ->   INSERT INTO test.t VALUES (1);
    ->   SET @@x = 3;
    -> END;
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> CALL handlerdemo()//
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@x//
    +------+
    | @@x   |
    +------+
    | 3    |
    +------+
    1 row in set (0.00 sec)
@end example

Notice that @code{@@x} is @code{3}, which shows that MySQL executed to the end of
the procedure. If the line
@code{DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @@x2 = 1;}
had not been present, MySQL would have taken the default (@code{EXIT}) path
after the second @code{INSERT} failed due to the @code{PRIMARY KEY}
constraint, and @code{SELECT @@x} would have returned @code{2}.


@node Cursors, Flow Control Constructs, Conditions and Handlers, Stored Procedure Syntax
@subsection Cursors

@cindex Cursors

Simple cursors are supported inside stored procedures and functions.
The syntax is as in embedded SQL.
Cursors are currently asensitive, read-only, and non-scrolling.
Asensitive means that the server may or may not make a copy of its result
table.

Cursors must be declared before declaring handlers, and variables must be
be declared before declaring either cursors or handlers.

For example:

@example
CREATE PROCEDURE curdemo()
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE a CHAR(16);
  DECLARE b,c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

  OPEN cur1;
  OPEN cur2;

  REPEAT
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF NOT done THEN
       IF b < c THEN
          INSERT INTO test.t3 VALUES (a,b);
       ELSE
          INSERT INTO test.t3 VALUES (a,c);
       END IF;
    END IF;
  UNTIL done END REPEAT;

  CLOSE cur1;
  CLOSE cur2;
END
@end example


@menu
* DECLARE Cursors::             Declaring Cursors
* OPEN::                        Cursor @code{OPEN} Statement
* FETCH::                       Cursor @code{FETCH} Statement
* CLOSE::                       Cursor @code{CLOSE} Statement
@end menu

@node DECLARE Cursors, OPEN, Cursors, Cursors
@subsubsection Declaring Cursors

@example
DECLARE @var{cursor_name} CURSOR FOR @var{select_statement}
@end example

This statement declares a cursor.
Multiple cursors may be defined in a routine, but each must have a unique
name.

The @code{SELECT} statement cannot have an @code{INTO} clause.


@node OPEN, FETCH, DECLARE Cursors, Cursors
@subsubsection Cursor @code{OPEN} Statement

@findex OPEN

@example
OPEN @var{cursor_name}
@end example

This statement opens a previously declared cursor.


@node FETCH, CLOSE, OPEN, Cursors
@subsubsection Cursor @code{FETCH} Statement

@findex FETCH

@example
FETCH @var{cursor_name} INTO @var{var_name} [, @var{var_name}] ...
@end example

This statement fetches the next row (if a row exists) using the specified
open cursor, and advances the cursor pointer.


@node CLOSE,  , FETCH, Cursors
@subsubsection Cursor @code{CLOSE} Statement

@findex CLOSE

@example
CLOSE @var{cursor_name}
@end example

This statement closes a previously opened cursor.

If not closed explicitly, a cursor is closed at the end of the compound
statement in which it was declared.


@node Flow Control Constructs,  , Cursors, Stored Procedure Syntax
@subsection Flow Control Constructs

The @code{IF}, @code{CASE}, @code{LOOP}, @code{WHILE}, @code{ITERATE}, and
@code{LEAVE} constructs are fully implemented.

These constructs may each contain either a single statement, or a block of
statements using the @code{BEGIN ... END} compound statement. Constructs
may be nested.

@code{FOR} loops are not currently supported.


@menu
* IF Statement::                @code{IF} Statement
* CASE Statement::              @code{CASE} Statement
* LOOP Statement::              @code{LOOP} Statement
* LEAVE Statement::             @code{LEAVE} Statement
* ITERATE Statement::           @code{ITERATE} Statement
* REPEAT Statement::            @code{REPEAT} Statement
* WHILE Statement::             @code{WHILE} Statement
@end menu

@node IF Statement, CASE Statement, Flow Control Constructs, Flow Control Constructs
@subsubsection @code{IF} Statement

@findex IF

@example
IF @var{search_condition} THEN @var{statement_list}
    [ELSEIF @var{search_condition} THEN @var{statement_list}]
    ...
    [ELSE @var{statement_list}]
END IF
@end example

@code{IF} implements a basic conditional construct. If the
@var{search_condition} evaluates to true, the corresponding SQL statement list
is executed. If no @var{search_condition} matches, the statement list in the
@code{ELSE} clause is executed. @var{statement_list} can consist of one or
more statements.

Please note that there is also an @code{IF()} function.
@xref{Control flow functions}.


@node CASE Statement, LOOP Statement, IF Statement, Flow Control Constructs
@subsubsection @code{CASE} Statement

@findex CASE

@example
CASE @var{case_value}
    WHEN @var{when_value} THEN @var{statement_list}
    [WHEN @var{when_value} THEN @var{statement_list} ...]
    [ELSE @var{statement_list}]
END CASE
@end example

Or:

@example
CASE
    WHEN @var{search_condition} THEN @var{statement_list}
    [WHEN @var{search_condition} THEN @var{statement_list} ...]
    [ELSE @var{statement_list}]
END CASE
@end example

The
@code{CASE} statement for stored procedures implements a complex conditional
construct. If a
@var{search_condition} evaluates to true, the corresponding SQL statement is executed. If no search condition matches, the statement in the @code{ELSE} clause is executed.

@strong{Note}: The syntax of a @code{CASE} @emph{statement} shown here
for use inside a stored procedure differs slightly from that of the SQL
@code{CASE} @emph{expression} described in @ref{Control flow functions}.
The @code{CASE} statement cannot have an @code{ELSE NULL} clause, and it
is terminated with @code{END CASE} instead of @code{END}.


@node LOOP Statement, LEAVE Statement, CASE Statement, Flow Control Constructs
@subsubsection @code{LOOP} Statement

@findex LOOP

@example
[@var{begin_label}:] LOOP
    @var{statement_list}
END LOOP [@var{end_label}]
@end example

@code{LOOP} implements a simple loop construct, enabling repeated execution
of a particular statement or statements. The statements within the
loop are repeated until the loop is exited; usually this is accomplished
with a @code{LEAVE} statement.

@var{begin_label} and @var{end_label} must be the same, if both are
specified.


@node LEAVE Statement, ITERATE Statement, LOOP Statement, Flow Control Constructs
@subsubsection @code{LEAVE} Statement

@findex LEAVE

@example
LEAVE @var{label}
@end example

This statement is used to exit any flow control construct.


@node ITERATE Statement, REPEAT Statement, LEAVE Statement, Flow Control Constructs
@subsubsection @code{ITERATE} Statement

@findex ITERATE

@example
ITERATE @var{label}
@end example

@code{ITERATE} can only appear within @code{LOOP}, @code{REPEAT}, and
@code{WHILE} statements. @code{ITERATE} means ``do the loop iteration again.''

For example:

@example
CREATE PROCEDURE doiterate(p1 INT)
BEGIN
  label1: LOOP
    SET p1 = p1 + 1;
    IF p1 < 10 THEN ITERATE label1; END IF;
    LEAVE label1;
  END LOOP label1;
  SET @@x = p1;
END
@end example


@node REPEAT Statement, WHILE Statement, ITERATE Statement, Flow Control Constructs
@subsubsection @code{REPEAT} Statement

@findex REPEAT
@findex UNTIL

@example
[@var{begin_label}:] REPEAT
    @var{statement_list}
UNTIL @var{search_condition}
END REPEAT [@var{end_label}]
@end example

The statement or statements within a @code{REPEAT} statement are repeated
until the @var{search_condition} is true.

@var{begin_label} and @var{end_label} must be the same, if both are
specified.

For example:

@example
mysql> delimiter //

mysql> CREATE PROCEDURE dorepeat(p1 INT)
    -> BEGIN
    ->   SET @@x = 0;
    ->   REPEAT SET @@x = @@x + 1; UNTIL @@x > p1 END REPEAT;
    -> END
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> CALL dorepeat(1000)//
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@x//
+------+
| @@x   |
+------+
| 1001 |
+------+
1 row in set (0.00 sec)
@end example


@node WHILE Statement,  , REPEAT Statement, Flow Control Constructs
@subsubsection @code{WHILE} Statement

@findex WHILE

@example
[@var{begin_label}:] WHILE @var{search_condition} DO
    @var{statement_list}
END WHILE [@var{end_label}]
@end example

The statement or statements within a @code{WHILE} statement are repeated as
long as the @var{search_condition} is true.

@var{begin_label} and @var{end_label} must be the same, if both are
specified.

For example:

@example
CREATE PROCEDURE dowhile()
BEGIN
  DECLARE v1 INT DEFAULT 5;

  WHILE v1 > 0 DO
    ...
    SET v1 = v1 - 1;
  END WHILE;
END
@end example


@node Triggers, MySQL APIs, Stored Procedures, Top
@chapter Triggers

Rudimentary support for triggers is included beginning with MySQL 5.0.2.
A trigger is a named database object that is associated with a table, and
that activates when a particular event occurs for the table.  For example,
the following statements set up a table, as well as a trigger for @code{INSERT}
statements into the table. The trigger sums the values inserted into one of
the table's columns:

@example
mysql> CREATE TABLE account (acct_num INT, amount DECIMAL(10,2));
mysql> CREATE TRIGGER ins_sum BEFORE INSERT ON account
    -> FOR EACH ROW SET @@sum = @@sum + NEW.amount;
@end example

This chapter describes the syntax for creating and dropping triggers,
and show some examples of how to use them.

@menu
* CREATE TRIGGER::              @code{CREATE TRIGGER} Syntax
* DROP TRIGGER::                @code{DROP TRIGGER} Syntax
* Using triggers::              Using Triggers
@end menu

@node CREATE TRIGGER, DROP TRIGGER, Triggers, Triggers
@section @code{CREATE TRIGGER} Syntax

@example
CREATE TRIGGER @var{trigger_name} @var{trigger_time} @var{trigger_event}
    ON @var{tbl_name} FOR EACH ROW @var{trigger_stmt}
@end example

A trigger is a named database object that is associated with a table, and
that activates when a particular event occurs for the table.

The trigger becomes associated with the table named @var{tbl_name}.
@var{tbl_name} must refer to a permanent table. You cannot associate a
trigger with a @code{TEMPORARY} table or a view.

@var{trigger_time} is the trigger action time.  It can be @code{BEFORE} or
@code{AFTER} to indicate that the trigger activates before or after the
statement that activated it.

@var{trigger_event} indicates the kind of statement that activates the
trigger.  It can be @code{INSERT}, @code{UPDATE}, or @code{DELETE}.
For example, a @code{BEFORE} trigger for @code{INSERT} statements could be
used to check the values to be inserted into new rows.

There cannot be two triggers for a given table that have the same trigger
action time and event. For example, you cannot have two @code{BEFORE
UPDATE} triggers for a table. But you can have a @code{BEFORE UPDATE}
and a @code{BEFORE INSERT} trigger, or a @code{BEFORE UPDATE} and an
@code{AFTER UPDATE} trigger.

@var{trigger_stmt} is the statement to execute when the trigger activates.
If you want to execute multiple statements, use the @code{BEGIN ... END}
compound statement construct.  This also enables you to use the same
statements that are allowable within stored routines.
@xref{BEGIN END,  , @code{BEGIN END}}.

@strong{Note}:
Currently, triggers have the same limitation as stored functions that they
may not contain direct references to tables by name.  This limitation will
be lifted as soon as possible.

However, in the triggered statement, you can refer to columns in the table
associated with the trigger by using the names @code{OLD} and @code{NEW}.
@code{OLD.@var{col_name}} refers to a column of a an existing row before
it is updated or deleted.  @code{NEW.@var{col_name}} refers to the column
of a new row to be inserted or an existing row after it is updated.

Use of @code{SET NEW.@var{col_name} = @var{value}} requires the @code{UPDATE}
privilege on the column.  Use of @code{SET @var{value} = NEW.@var{col_name}}
requires the @code{SELECT} privilege on the column.

The @code{CREATE TRIGGER} statement requires the @code{SUPER} privilege.
It was added in MySQL 5.0.2.

@c TODO: Should need CREATE TRIGGER privilege, but there is no such thing yet.


@node DROP TRIGGER, Using triggers, CREATE TRIGGER, Triggers
@section @code{DROP TRIGGER} Syntax

@c There is no IF EXISTS clause, apparently.

@example
DROP TRIGGER @var{tbl_name}.@var{trigger_name}
@end example

Drops a trigger.  The name of the trigger to drop must include the table
name because each trigger is associated with a particular table.

The @code{DROP TRIGGER} statement requires the @code{SUPER} privilege.
It was added in MySQL 5.0.2.


@node Using triggers,  , DROP TRIGGER, Triggers
@section Using Triggers

Support for triggers is included beginning with MySQL 5.0.2.  Currently,
trigger support is rudimentary, so there are certain limitations on what you
can do with them.  This section discusses how to use triggers and what the
current limitations are.

A trigger is a named database object that is associated with a table, and
that activates when a particular event occurs for the table.  Some uses
for triggers are to perform checks of values to be inserted into a table
or to perform calculations on values involved in an update.

A trigger is associated with a table and is defined to activate when an
@code{INSERT}, @code{DELETE}, or @code{UPDATE} statement for the table
executes.  A trigger can be set to activate either before or after the
triggering statement.  For example, you can have a trigger activate before
each row that is deleted from a table or after each row that is updated.

To create a trigger or drop a trigger, use the @code{CREATE TRIGGER} or
@code{DROP TRIGGER} statement.  The syntax for these statements is described
in @ref{CREATE TRIGGER,  , @code{CREATE TRIGGER}} and
@ref{DROP TRIGGER,  , @code{DROP TRIGGER}}.

Here is a simple example that associates a trigger with a table for
@code{INSERT} statements.  It acts as an accumulator to sum the values
inserted into one of the columns of the table.

The following statements create a table and a trigger for it:

@example
mysql> CREATE TABLE account (acct_num INT, amount DECIMAL(10,2));
mysql> CREATE TRIGGER ins_sum BEFORE INSERT ON account
    -> FOR EACH ROW SET @@sum = @@sum + NEW.amount;
@end example

The @code{CREATE TRIGGER} statement creates a trigger named @code{ins_sum}
that is associated with the @code{account} table.  It also includes clauses
that specify the trigger activation time, the triggering event, and what to
do with the trigger activates:

@itemize @bullet

@item
The keyword @code{BEFORE} indicates the trigger action time.  In this case,
the trigger should activate before each row inserted into the table.  The
other allowable keyword here is @code{AFTER}.

@item
The keyword @code{INSERT} indicates the event that activates the trigger.
In the example, @code{INSERT} statements cause trigger activation.  You can
also create triggers for @code{DELETE} and @code{UPDATE} statements.

@item
The statement following @code{FOR EACH ROW} defines the statement to execute
each time the trigger activates, which occurs once for each row affected by
the triggering statement  In the example, the triggered statement is a
simple @code{SET} that accumulates the values inserted into the
@code{amount} column.  The statement refers to the column as
@code{NEW.amount} which means ``the value of the @code{amount} column to be
inserted into the new row.''

@end itemize

To use the trigger, set the accumlator variable to zero, execute an
@code{INSERT} statement, and then see what value the variable has afterward:

@example
mysql> SET @@sum = 0;
mysql> INSERT INTO account VALUES(137,14.98),(141,1937.50),(97,-100.00);
mysql> SELECT @@sum AS 'Total amount inserted';
+-----------------------+
| Total amount inserted |
+-----------------------+
| 1852.48               |
+-----------------------+
@end example

In this case, the value of @code{@@sum} after the @code{INSERT} statement
has executed is @code{14.98 + 1937.50 - 100} or @code{1852.48}.

To destroy the trigger, use a @code{DROP TRIGGER} statement.  The
trigger name must include the table name:

@example
mysql> DROP TRIGGER account.ins_sum;
@end example

Because a trigger is associated with a particular table, you cannot have
multiple triggers for a table that have the same name.  You should also be
aware that the namespace for triggers might change in the future from table
to database.  That is, the requirement that trigger names be unique for a
given table might be strengthened to the requirement that they be unique
within the database.  For better forward compatibility with future
development, try to use trigger names that do not overlap within a database.

In addition to the requirement that trigger names be unique for a table,
there are other limitations on the types of triggers you can create.
In particular, you cannot have two triggers for a table that have the same
activate time and activation event.  For example, you cannot define two
@code{BEFORE INSERT} triggers or two @code{AFTER UPDATE} triggers for a table.
This should rarely be a significant limitation, because it is possible to
define a trigger that executes multiple statements by using the @code{BEGIN
@dots{} END} compound statement construct after @code{FOR EACH ROW}. (An example
appears later in this section.)

There are also limitations on what can appear in the statement that the
trigger executes when activated:

@itemize @bullet

@item
The trigger cannot refer directly to tables by name, including the table
with which the table is associated.  You can, however, use the keywords
@code{OLD} and @code{NEW}.  @code{OLD} refers to an existing row to be
deleted or a row to be updated before the update occurs.  @code{NEW} refers
to a new row to be inserted or an updated row after the update occurs.

@item
The trigger cannot invoke stored procedures using the @code{CALL} statement.
(This means, for example, that you cannot get around the prohibition on
referring to tables by name by invoking a stored procedure that refers to
the tables.)

@item
The trigger cannot use statements that begin or end a transaction such as
@code{START TRANSACTION}, @code{COMMIT}, or @code{ROLLBACK}.

@end itemize

The @code{OLD} and @code{NEW} keywords enable you to access columns in
the rows affected by a trigger.  (@code{OLD} and @code{NEW} are not case
sensitive.)  In an @code{INSERT} trigger, only @code{NEW.@var{col_name}}
can be used; there is no old row. In a @code{DELETE} trigger, only
@code{OLD.@var{col_name}} can be used; there is no new row.  In an
@code{UPDATE} trigger, you can use @code{OLD.@var{col_name}} to refer to
the columns of a row before it is updated and @code{NEW.@var{col_name}}
to refer to the columns of the row after it is updated.

A column named with @code{OLD} is read-only. You can refer to it but not
modify it.  A column named with @code{NEW} can be referred to if you have
the @code{SELECT} privilege for it. In a @code{BEFORE} trigger, you can also
change its value with @code{SET NEW.@var{col_name} = @var{value}} if you
have the @code{UPDATE} privilege for it.  This means you can use a trigger to
modify the values to be inserted into a new row or that are used to update a
row.

@code{OLD} and @code{NEW} are MySQL extensions to triggers.

By using the @code{BEGIN @dots{} END} construct, you can define a trigger
that executes multiple statements. Within the @code{BEGIN} block, you also
can use other syntax that is allowed within stored routines such as
conditionals and loops. However, just as for stored routines, when you
define a trigger that executes multiple statements, it becomes necessary to
redefine the statement delimiter if you are entering the trigger with the
@command{mysql} program so that you can use the @samp{;} character within
the trigger definition.  The following example illustrates these points. It
defines an @code{UPDATE} trigger that checks the new value to be used for
updating each row, and modifies the value to be within the range
from 0 to 100.  This must be a @code{BEFORE} trigger because the value needs
to be checked before it is used to update the row:

@example
mysql> delimiter //
mysql> CREATE TRIGGER upd_check BEFORE UPDATE ON account
    -> FOR EACH ROW
    -> BEGIN
    ->     IF NEW.amount < 0 THEN
    ->         SET NEW.amount = 0;
    ->     ELSEIF NEW.amount > 100 THEN
    ->         SET NEW.amount = 100;
    ->     END IF;
    -> END//
mysql> delimiter ;
@end example

It might occur to you that it would be easier to define a stored procedure
separately and then invoke it from the trigger using a simple @code{CALL}
statement.  That would also be advantageous if you wanted to invoke the same
routine from within several triggers. However, a limitation on triggers
currently is that @code{CALL} cannot be used. So for now you have to write
out the compound statement in each @code{CREATE TRIGGER} statement where you
want to use it.


@node MySQL APIs, MySQL Connectors, Triggers, Top
@chapter MySQL APIs

@cindex client tools
@cindex APIs
@cindex @code{mysqlclient} library
@cindex buffer sizes, client
@cindex library, @code{mysqlclient}

@menu
* Programming utilities::       MySQL Program Development Utilities
* C::                           MySQL C API
* PHP::                         MySQL PHP API
* Perl::                        MySQL Perl API
* Cplusplus::                   MySQL C++ API
* Python::                      MySQL Python API
* Tcl::                         MySQL Tcl API
* Eiffel::                      MySQL Eiffel Wrapper
@end menu

This chapter describes the APIs available for MySQL, where to get
them, and how to use them.  The C API is the most extensively covered,
because it was developed by the MySQL team, and is the basis for most of the
other APIs.


@node Programming utilities, C, MySQL APIs, MySQL APIs
@section MySQL Program Development Utilities

@c TODO: my_print_defaults

This section describes some utilities that you may find useful when
developing MySQL programs.

@table @code

@item msql2mysql
@cindex @command{msql2mysql}
A shell script that converts @code{mSQL} programs to MySQL. It doesn't
handle every case, but it gives a good start when converting.

@item mysql_config
@cindex @command{mysql_config}
A shell script that produces the option values needed when compiling MySQL
programs.

@end table

@menu
* msql2mysql::                  @command{msql2mysql}, Convert mSQL Programs for Use with MySQL
* mysql_config::                @command{mysql_config}, Get compile options for compiling clients
@end menu


@node msql2mysql, mysql_config, Programming utilities, Programming utilities
@subsection @command{msql2mysql}, Convert mSQL Programs for Use with MySQL

Initially, the MySQL C API was developed to be very similar to that for the
mSQL database system. Because of this, mSQL programs often can be converted
relatively easily for use with MySQL by changing the names of the C API
functions.

The @command{msql2mysql} utility performs the conversion of mSQL C API function
calls to their MySQL equivalents.
@command{msql2mysql} converts the input file in place, so make a copy of the
original before converting it.  For example, use @command{msql2mysql} like
this:


@example
shell> cp client-prog.c client-prog.c.orig
shell> msql2mysql client-prog.c
client-prog.c converted
@end example

Then examine @file{client-prog.c} and make any post-conversion revisions
that may be necessary.

@command{msql2mysql} uses the @command{replace} utility to make the function name
substitutions.
@xref{replace utility}.

@node mysql_config,  , msql2mysql, Programming utilities
@subsection @command{mysql_config}, Get compile options for compiling clients

@c TODO: move this to C API section (along with msql2mysql)? They're both
@c of more interest to developers, not to end users.

@command{mysql_config} provides you with useful information for compiling
your MySQL client and connecting it to MySQL.

@command{mysql_config} supports the following options:

@table @code

@item --cflags
Compiler flags to find include files and critical compiler flags and
defines used when compiling the @code{libmysqlclient} library.

@item --include
Compiler options to find MySQL include files. (Note that normally you would use
@code{--cflags} instead of this option.)

@item --libmysqld-libs, --embedded
Libraries and options required to link with the MySQL embedded server.

@item --libs
Libraries and options required to link with the MySQL client library.

@item --libs_r
Libraries and options required to link with the thread-safe MySQL client library.

@item --port
The default TCP/IP port number, defined when configuring MySQL.

@item --socket
The default Unix socket file, defined when configuring MySQL.

@item --version
Version number and version for the MySQL distribution.

@end table

If you invoke @command{mysql_config} with no options, it displays a list of all
options that it supports, and their values:

@example
shell> mysql_config
Usage: /usr/local/mysql/bin/mysql_config [options]
Options:
  --cflags         [-I/usr/local/mysql/include/mysql -mcpu=pentiumpro]
  --include        [-I/usr/local/mysql/include/mysql]
  --libs           [-L/usr/local/mysql/lib/mysql -lmysqlclient -lz
                    -lcrypt -lnsl -lm -L/usr/lib -lssl -lcrypto]
  --libs_r         [-L/usr/local/mysql/lib/mysql -lmysqlclient_r
                    -lpthread -lz -lcrypt -lnsl -lm -lpthread]
  --socket         [/tmp/mysql.sock]
  --port           [3306]
  --version        [4.0.16]
  --libmysqld-libs [-L/usr/local/mysql/lib/mysql -lmysqld -lpthread -lz
                    -lcrypt -lnsl -lm -lpthread -lrt]
@end example

You can use @command{mysql_config} within a command line to include the value
that it displays for a particular option. For example, to compile a MySQL
client program, use @command{mysql_config} as follows:

@example
CFG=/usr/local/mysql/bin/mysql_config
sh -c "gcc -o progname `$CFG --cflags` progname.c `$CFG --libs`"
@end example

When you use @command{mysql_config} this way, be sure to invoke it within
backtick (@samp{`}) characters.  That tells the shell to execute it and
subsitute its output into the surrounding command.


@node C, PHP, Programming utilities, MySQL APIs
@section MySQL C API

@cindex C API, data types
@cindex data types, C API

@menu
* C API datatypes::             C API Data types
* C API function overview::     C API Function Overview
* C API functions::             C API Function Descriptions
* C API Prepared statements::   C API Prepared Statements
* C API Prepared statement datatypes::  C API Prepared Statement Data types
* C API Prepared statement function overview::  C API Prepared Statement Function Overview
* C API Prepared statement functions::  C API Prepared Statement Function Descriptions
* C API Prepared statement problems::  C API Prepared statement problems
* C API multiple queries::      C API Handling of Multiple Query Execution
* C API date handling::         C API Handling of Date and Time Values
* C Thread functions::          C API Threaded Function Descriptions
* C Embedded Server func::      C API Embedded Server Function Descriptions
* C API problems::              Common questions and problems when using the C API
* Building clients::            Building Client Programs
* Threaded clients::            How to Make a Threaded Client
* libmysqld::                   libmysqld, the Embedded MySQL Server Library
@end menu

The C API code is distributed with MySQL. It is included in the
@code{mysqlclient} library and allows C programs to access a database.

Many of the clients in the MySQL source distribution are
written in C.  If you are looking for examples that demonstrate how to
use the C API, take a look at these clients. You can find these in the
@code{clients} directory in the MySQL source distribution.

Most of the other client APIs (all except Connector/J) use the @code{mysqlclient}
library to communicate with the MySQL server. This means that, for
example, you can take advantage of many of the same environment variables
that are used by other client programs, because they are referenced from the
library.  See @ref{Client-Side Scripts}, for a list of these variables.

The client has a maximum communication buffer size. The size of the buffer
that is allocated initially (16KB) is automatically increased up to the
maximum size (the maximum is 16MB). Because buffer sizes are increased
only as demand warrants, simply increasing the default maximum limit does not
in itself cause more resources to be used. This size check is mostly a check
for erroneous queries and communication packets.

The communication buffer must be large enough to contain a single SQL
statement (for client-to-server traffic) and one row of returned data (for
server-to-client traffic).  Each thread's communication buffer is dynamically
enlarged to handle any query or row up to the maximum limit.  For example, if
you have @code{BLOB} values that contain up to 16MB of data, you must have a
communication buffer limit of at least 16MB (in both server and client).  The
client's default maximum is 16MB, but the default maximum in the server is
1MB.  You can increase this by changing the value of the
@code{max_allowed_packet} parameter when the server is started.  @xref{Server
parameters}.

The MySQL server shrinks each communication buffer to
@code{net_buffer_length} bytes after each query.  For clients, the size of
the buffer associated with a connection is not decreased until the connection
is closed, at which time client memory is reclaimed.

For programming with threads, see @ref{Threaded clients}.
For creating a standalone application which includes the
"server" and "client" in the same program (and does not
communicate with an external MySQL server), see @ref{libmysqld}.


@node C API datatypes, C API function overview, C, C
@subsection C API Data types

@table @code
@item MYSQL
@tindex MYSQL C type
This structure represents a handle to one database connection. It is
used for almost all MySQL functions.

@item MYSQL_RES
@tindex MYSQL_RES C type
This structure represents the result of a query that returns rows
(@code{SELECT}, @code{SHOW}, @code{DESCRIBE}, @code{EXPLAIN}).  The
information returned from a query is called the @emph{result set} in the
remainder of this section.

@item MYSQL_ROW
@tindex MYSQL_ROW C type
This is a type-safe representation of one row of data. It is currently
implemented as an array of counted byte strings.  (You cannot treat these as
null-terminated strings if field values may contain binary data, because such
values may contain null bytes internally.)  Rows are obtained by calling
@code{mysql_fetch_row()}.

@item MYSQL_FIELD
@tindex MYSQL_FIELD C type
This structure contains information about a field, such as the field's
name, type, and size. Its members are described in more detail here.
You may obtain the @code{MYSQL_FIELD} structures for each field by
calling @code{mysql_fetch_field()} repeatedly.  Field values are not part of
this structure; they are contained in a @code{MYSQL_ROW} structure.


@item MYSQL_FIELD_OFFSET
@tindex MYSQL_FIELD_OFFSET C type
This is a type-safe representation of an offset into a MySQL field
list.  (Used by @code{mysql_field_seek()}.)  Offsets are field numbers
within a row, beginning at zero.

@item my_ulonglong
@tindex my_ulonglong C type
@tindex my_ulonglong values, printing
The type used for the number of rows and for @code{mysql_affected_rows()},
@code{mysql_num_rows()}, and @code{mysql_insert_id()}. This type provides a
range of @code{0} to @code{1.84e19}.

On some systems, attempting to print a value of type @code{my_ulonglong}
will not work.  To print such a value, convert it to @code{unsigned long}
and use a @code{%lu} print format.  Example:
@example
printf ("Number of rows: %lu\n", (unsigned long) mysql_num_rows(result));
@end example
@end table

@noindent
The @code{MYSQL_FIELD} structure contains the members listed here:

@table @code
@item char * name
The name of the field, as a null-terminated string.

@item char * table
The name of the table containing this field, if it isn't a calculated field.
For calculated fields, the @code{table} value is an empty string.

@item char * def
The default value of this field, as a null-terminated string.  This is set
only if you use @code{mysql_list_fields()}.

@item enum enum_field_types type
The type of the field.
The @code{type} value may be one of the following:

@multitable @columnfractions .35 .55
@item @strong{Type Value}                @tab @strong{Type Description}
@item @code{FIELD_TYPE_TINY}            @tab @code{TINYINT} field
@item @code{FIELD_TYPE_SHORT}           @tab @code{SMALLINT} field
@item @code{FIELD_TYPE_LONG}            @tab @code{INTEGER} field
@item @code{FIELD_TYPE_INT24}           @tab @code{MEDIUMINT} field
@item @code{FIELD_TYPE_LONGLONG}        @tab @code{BIGINT} field
@item @code{FIELD_TYPE_DECIMAL}         @tab @code{DECIMAL} or @code{NUMERIC} field
@item @code{FIELD_TYPE_FLOAT}           @tab @code{FLOAT} field
@item @code{FIELD_TYPE_DOUBLE}          @tab @code{DOUBLE} or @code{REAL} field
@item @code{FIELD_TYPE_TIMESTAMP}       @tab @code{TIMESTAMP} field
@item @code{FIELD_TYPE_DATE}            @tab @code{DATE} field
@item @code{FIELD_TYPE_TIME}            @tab @code{TIME} field
@item @code{FIELD_TYPE_DATETIME}        @tab @code{DATETIME} field
@item @code{FIELD_TYPE_YEAR}            @tab @code{YEAR} field
@item @code{FIELD_TYPE_STRING}          @tab @code{CHAR} field
@item @code{FIELD_TYPE_VAR_STRING}      @tab @code{VARCHAR} field
@item @code{FIELD_TYPE_BLOB}            @tab @code{BLOB} or @code{TEXT} field (use @code{max_length} to determine the maximum length)
@item @code{FIELD_TYPE_SET}             @tab @code{SET} field
@item @code{FIELD_TYPE_ENUM}            @tab @code{ENUM} field
@item @code{FIELD_TYPE_NULL}            @tab @code{NULL}-type field
@item @code{FIELD_TYPE_CHAR}            @tab Deprecated; use @code{FIELD_TYPE_TINY} instead
@end multitable

You can use the @code{IS_NUM()} macro to test whether a field has a
numeric type.  Pass the @code{type} value to @code{IS_NUM()} and it
will evaluate to TRUE if the field is numeric:

@example
if (IS_NUM(field->type))
    printf("Field is numeric\n");
@end example

@item unsigned int length
The width of the field, as specified in the table definition.

@item unsigned int max_length
The maximum width of the field for the result set (the length of the longest
field value for the rows actually in the result set). If you use
@code{mysql_store_result()} or @code{mysql_list_fields()}, this contains the
maximum length for the field.  If you use @code{mysql_use_result()}, the
value of this variable is zero.

@item unsigned int flags
Different bit-flags for the field.  The @code{flags} value may have zero
or more of the following bits set:

@multitable @columnfractions .35 .55
@item @strong{Flag Value}         @tab @strong{Flag Description}
@item @code{NOT_NULL_FLAG}       @tab Field can't be @code{NULL}
@item @code{PRI_KEY_FLAG}        @tab Field is part of a primary key
@item @code{UNIQUE_KEY_FLAG}     @tab Field is part of a unique key
@item @code{MULTIPLE_KEY_FLAG}   @tab Field is part of a non-unique key
@item @code{UNSIGNED_FLAG}       @tab Field has the @code{UNSIGNED} attribute
@item @code{ZEROFILL_FLAG}       @tab Field has the @code{ZEROFILL} attribute
@item @code{BINARY_FLAG}         @tab Field has the @code{BINARY} attribute
@item @code{AUTO_INCREMENT_FLAG} @tab Field has the @code{AUTO_INCREMENT}
attribute
@item @code{ENUM_FLAG}           @tab Field is an @code{ENUM} (deprecated)
@item @code{SET_FLAG}            @tab Field is a @code{SET} (deprecated)
@item @code{BLOB_FLAG}           @tab Field is a @code{BLOB} or @code{TEXT} (deprecated)
@item @code{TIMESTAMP_FLAG}      @tab Field is a @code{TIMESTAMP} (deprecated)
@end multitable

Use of the @code{BLOB_FLAG}, @code{ENUM_FLAG}, @code{SET_FLAG}, and
@code{TIMESTAMP_FLAG} flags is deprecated because they indicate the type of
a field rather than an attribute of its type.  It is preferable to test
@code{field->type} against @code{FIELD_TYPE_BLOB}, @code{FIELD_TYPE_ENUM},
@code{FIELD_TYPE_SET}, or @code{FIELD_TYPE_TIMESTAMP} instead.

@noindent
The following example illustrates a typical use of the @code{flags} value:

@example
if (field->flags & NOT_NULL_FLAG)
    printf("Field can't be null\n");
@end example

You may use the following convenience macros to determine the boolean
status of the @code{flags} value:

@multitable @columnfractions .25 .55
@item @strong{Flag Status} @tab @strong{Description}
@item @code{IS_NOT_NULL(flags)} @tab True if this field is defined as @code{NOT NULL}
@item @code{IS_PRI_KEY(flags)}  @tab True if this field is a primary key
@item @code{IS_BLOB(flags)}     @tab True if this field is a @code{BLOB} or @code{TEXT} (deprecated; test @code{field->type} instead)
@end multitable

@item unsigned int decimals
The number of decimals for numeric fields.
@end table


@node C API function overview, C API functions, C API datatypes, C
@subsection C API Function Overview

@cindex C API, functions
@cindex functions, C API

The functions available in the C API are summarized here and described in
greater detail in a later section.
@xref{C API functions}.

@multitable @columnfractions .32 .68
@item @strong{Function} @tab @strong{Description}

@item @strong{mysql_affected_rows()} @tab
Returns the number of rows changed/deleted/inserted by the last @code{UPDATE},
@code{DELETE}, or @code{INSERT} query.

@item @strong{mysql_change_user()} @tab
Changes user and database on an open connection.

@item @strong{mysql_charset_name()} @tab
Returns the name of the default character set for the connection.

@item @strong{mysql_close()} @tab
Closes a server connection.

@item @strong{mysql_connect()} @tab
Connects to a MySQL server. This function is deprecated; use
@code{mysql_real_connect()} instead.

@item @strong{mysql_create_db()} @tab
Creates a database. This function is deprecated; use the SQL statement
@code{CREATE DATABASE} instead.

@item @strong{mysql_data_seek()} @tab
Seeks to an arbitrary row number in a query result set.

@item @strong{mysql_debug()} @tab
Does a @code{DBUG_PUSH} with the given string.

@item @strong{mysql_drop_db()} @tab
Drops a database. This function is deprecated; use the SQL statement
@code{DROP DATABASE} instead.

@item @strong{mysql_dump_debug_info()} @tab
Makes the server write debug information to the log.

@item @strong{mysql_eof()} @tab
Determines whether the last row of a result set has been read.
This function is deprecated; @code{mysql_errno()} or @code{mysql_error()}
may be used instead.

@item @strong{mysql_errno()} @tab
Returns the error number for the most recently invoked MySQL function.

@item @strong{mysql_error()} @tab
Returns the error message for the most recently invoked MySQL function.

@item @strong{mysql_escape_string()} @tab
Escapes special characters in a string for use in an SQL statement.

@item @strong{mysql_fetch_field()} @tab
Returns the type of the next table field.

@item @strong{mysql_fetch_field_direct()} @tab
Returns the type of a table field, given a field number.

@item @strong{mysql_fetch_fields()} @tab
Returns an array of all field structures.

@item @strong{mysql_fetch_lengths()} @tab
Returns the lengths of all columns in the current row.

@item @strong{mysql_fetch_row()} @tab
Fetches the next row from the result set.

@item @strong{mysql_field_seek()} @tab
Puts the column cursor on a specified column.

@item @strong{mysql_field_count()} @tab
Returns the number of result columns for the most recent statement.

@item @strong{mysql_field_tell()} @tab
Returns the position of the field cursor used for the last
@code{mysql_fetch_field()}.

@item @strong{mysql_free_result()} @tab
Frees memory used by a result set.

@item @strong{mysql_get_client_info()} @tab
Returns client version information as a string.

@item @strong{mysql_get_client_version()} @tab
Returns client version information as an integer.

@item @strong{mysql_get_host_info()} @tab
Returns a string describing the connection.

@item @strong{mysql_get_server_version()} @tab
Returns version number of server as an integer (new in 4.1).

@item @strong{mysql_get_proto_info()} @tab
Returns the protocol version used by the connection.

@item @strong{mysql_get_server_info()} @tab
Returns the server version number.

@item @strong{mysql_info()} @tab
Returns information about the most recently executed query.

@item @strong{mysql_init()} @tab
Gets or initializes a @code{MYSQL} structure.

@item @strong{mysql_insert_id()} @tab
Returns the ID generated for an @code{AUTO_INCREMENT} column by the previous
query.

@item @strong{mysql_kill()} @tab
Kills a given thread.

@item @strong{mysql_list_dbs()} @tab
Returns database names matching a simple regular expression.

@item @strong{mysql_list_fields()} @tab
Returns field names matching a simple regular expression.

@item @strong{mysql_list_processes()} @tab
Returns a list of the current server threads.

@item @strong{mysql_list_tables()} @tab
Returns table names matching a simple regular expression.

@item @strong{mysql_num_fields()} @tab
Returns the number of columns in a result set.

@item @strong{mysql_num_rows()} @tab
Returns the number of rows in a result set.

@item @strong{mysql_options()} @tab
Sets connect options for @code{mysql_connect()}.

@item @strong{mysql_ping()} @tab
Checks whether the connection to the server is working, reconnecting
as necessary.

@item @strong{mysql_query()} @tab
Executes an SQL query specified as a null-terminated string.

@item @strong{mysql_real_connect()} @tab
Connects to a MySQL server.

@item @strong{mysql_real_escape_string()} @tab
Escapes special characters in a string for use in an SQL statement, taking
into account the current charset of the connection.

@item @strong{mysql_real_query()} @tab
Executes an SQL query specified as a counted string.

@item @strong{mysql_reload()} @tab
Tells the server to reload the grant tables.

@item @strong{mysql_row_seek()} @tab
Seeks to a row offset in a result set, using value returned from
@code{mysql_row_tell()}.

@item @strong{mysql_row_tell()} @tab
Returns the row cursor position.

@item @strong{mysql_select_db()} @tab
Selects a database.

@item @strong{mysql_set_server_option()} @tab
Sets an option for the connection (like @code{multi-statements}).

@item @strong{mysql_sqlstate()} @tab
Returns the SQLSTATE error code for the last error.

@item @strong{mysql_shutdown()} @tab
Shuts down the database server.

@item @strong{mysql_stat()} @tab
Returns the server status as a string.

@item @strong{mysql_store_result()} @tab
Retrieves a complete result set to the client.

@item @strong{mysql_thread_id()} @tab
Returns the current thread ID.

@item @strong{mysql_thread_safe()} @tab
Returns 1 if the clients are compiled as thread-safe.

@item @strong{mysql_use_result()} @tab
Initiates a row-by-row result set retrieval.

@item @strong{mysql_warning_count()} @tab
Returns the warning count for the previous SQL statement.

@item @strong{mysql_commit()} @tab
Commits the transaction.

@item @strong{mysql_rollback()} @tab
Rolls back the transaction.

@item @strong{mysql_autocommit()} @tab
Toggles autocommit mode on/off.

@item @strong{mysql_more_results()} @tab
Checks whether any more results exist.

@item @strong{mysql_next_result()} @tab
Returns/Initiates the next result in multi-query executions.
@end multitable

To connect to the server, call @code{mysql_init()} to initialize a
connection handler, then call @code{mysql_real_connect()} with that
handler (along with other information such as the hostname, username,
and password).  Upon connection, @code{mysql_real_connect()} sets the
@code{reconnect} flag (part of the @code{MYSQL} structure) to a value of
@code{1} in versions of the API strictly older than 5.0.3, of @code{0} in newer
versions. A value of @code{1} for this flag indicates, in the event that a
query cannot be performed because of a lost connection, to try reconnecting to
the server before giving up.  When you are done with the connection, call
@code{mysql_close()} to terminate it.

While a connection is active, the client may send SQL queries to the server
using @code{mysql_query()} or @code{mysql_real_query()}.  The difference
between the two is that @code{mysql_query()} expects the query to be
specified as a null-terminated string whereas @code{mysql_real_query()}
expects a counted string.  If the string contains binary data (which may
include null bytes), you must use @code{mysql_real_query()}.

For each non-@code{SELECT} query (for example, @code{INSERT}, @code{UPDATE},
@code{DELETE}), you can find out how many rows were changed (affected)
by calling @code{mysql_affected_rows()}.

For @code{SELECT} queries, you retrieve the selected rows as a result set.
(Note that some statements are @code{SELECT}-like in that they return rows.
These include @code{SHOW}, @code{DESCRIBE}, and @code{EXPLAIN}.  They should
be treated the same way as @code{SELECT} statements.)

There are two ways for a client to process result sets.  One way is to
retrieve the entire result set all at once by calling
@code{mysql_store_result()}.  This function acquires from the server all the
rows returned by the query and stores them in the client.  The second way is
for the client to initiate a row-by-row result set retrieval by calling
@code{mysql_use_result()}.  This function initializes the retrieval, but does
not actually get any rows from the server.

In both cases, you access rows by calling @code{mysql_fetch_row()}.  With
@code{mysql_store_result()}, @code{mysql_fetch_row()} accesses rows that have
already been fetched from the server.  With @code{mysql_use_result()},
@code{mysql_fetch_row()} actually retrieves the row from the server.
Information about the size of the data in each row is available by
calling @code{mysql_fetch_lengths()}.

After you are done with a result set, call @code{mysql_free_result()}
to free the memory used for it.

The two retrieval mechanisms are complementary.  Client programs should
choose the approach that is most appropriate for their requirements.
In practice, clients tend to use @code{mysql_store_result()} more
commonly.

An advantage of @code{mysql_store_result()} is that because the rows have all
been fetched to the client, you not only can access rows sequentially, you
can move back and forth in the result set using @code{mysql_data_seek()} or
@code{mysql_row_seek()} to change the current row position within the result
set.  You can also find out how many rows there are by calling
@code{mysql_num_rows()}.  On the other hand, the memory requirements for
@code{mysql_store_result()} may be very high for large result sets and you
are more likely to encounter out-of-memory conditions.

An advantage of @code{mysql_use_result()} is that the client requires less
memory for the result set because it maintains only one row at a time (and
because there is less allocation overhead, @code{mysql_use_result()} can be
faster).  Disadvantages are that you must process each row quickly to avoid
tying up the server, you don't have random access to rows within the result
set (you can only access rows sequentially), and you don't know how many rows
are in the result set until you have retrieved them all.  Furthermore, you
@strong{must} retrieve all the rows even if you determine in mid-retrieval that
you've found the information you were looking for.

The API makes it possible for clients to respond appropriately to
queries (retrieving rows only as necessary) without knowing whether or
not the query is a @code{SELECT}.  You can do this by calling
@code{mysql_store_result()} after each @code{mysql_query()} (or
@code{mysql_real_query()}).  If the result set call succeeds, the query
was a @code{SELECT} and you can read the rows.  If the result set call
fails, call @code{mysql_field_count()} to determine whether a
result was actually to be expected.  If @code{mysql_field_count()}
returns zero, the query returned no data (indicating that it was an
@code{INSERT}, @code{UPDATE}, @code{DELETE}, etc.), and was not
expected to return rows.  If @code{mysql_field_count()} is non-zero, the
query should have returned rows, but didn't.  This indicates that the
query was a @code{SELECT} that failed.  See the description for
@code{mysql_field_count()} for an example of how this can be done.

Both @code{mysql_store_result()} and @code{mysql_use_result()} allow you to
obtain information about the fields that make up the result set (the number
of fields, their names and types, etc.).  You can access field information
sequentially within the row by calling @code{mysql_fetch_field()} repeatedly,
or by field number within the row by calling
@code{mysql_fetch_field_direct()}.  The current field cursor position may be
changed by calling @code{mysql_field_seek()}.  Setting the field cursor
affects subsequent calls to @code{mysql_fetch_field()}.  You can also get
information for fields all at once by calling @code{mysql_fetch_fields()}.

For detecting and reporting errors, MySQL provides access to error
information by means of the @code{mysql_errno()} and @code{mysql_error()}
functions.  These return the error code or error message for the most
recently invoked function that can succeed or fail, allowing you to determine
when an error occurred and what it was.


@node C API functions, C API Prepared statements, C API function overview, C
@subsection C API Function Descriptions

@menu
* mysql_affected_rows::         @code{mysql_affected_rows()}
* mysql_change_user::           @code{mysql_change_user()}
* mysql_character_set_name::    @code{mysql_character_set_name()}
* mysql_close::                 @code{mysql_close()}
* mysql_connect::               @code{mysql_connect()}
* mysql_create_db::             @code{mysql_create_db()}
* mysql_data_seek::             @code{mysql_data_seek()}
* mysql_debug::                 @code{mysql_debug()}
* mysql_drop_db::               @code{mysql_drop_db()}
* mysql_dump_debug_info::       @code{mysql_dump_debug_info()}
* mysql_eof::                   @code{mysql_eof()}
* mysql_errno::                 @code{mysql_errno()}
* mysql_error::                 @code{mysql_error()}
* mysql_escape_string::         @code{mysql_escape_string()}
* mysql_fetch_field::           @code{mysql_fetch_field()}
* mysql_fetch_fields::          @code{mysql_fetch_fields()}
* mysql_fetch_field_direct::    @code{mysql_fetch_field_direct()}
* mysql_fetch_lengths::         @code{mysql_fetch_lengths()}
* mysql_fetch_row::             @code{mysql_fetch_row()}
* mysql_field_count::           @code{mysql_field_count()}
* mysql_field_seek::            @code{mysql_field_seek()}
* mysql_field_tell::            @code{mysql_field_tell()}
* mysql_free_result::           @code{mysql_free_result()}
* mysql_get_client_info::       @code{mysql_get_client_info()}
* mysql_get_client_version::    @code{mysql_get_client_version()}
* mysql_get_host_info::         @code{mysql_get_host_info()}
* mysql_get_proto_info::        @code{mysql_get_proto_info()}
* mysql_get_server_info::       @code{mysql_get_server_info()}
* mysql_get_server_version::    @code{mysql_get_server_version()}
* mysql_hex_string::            @code{mysql_hex_string()}
* mysql_info::                  @code{mysql_info()}
* mysql_init::                  @code{mysql_init()}
* mysql_insert_id::             @code{mysql_insert_id()}
* mysql_kill::                  @code{mysql_kill()}
* mysql_list_dbs::              @code{mysql_list_dbs()}
* mysql_list_fields::           @code{mysql_list_fields()}
* mysql_list_processes::        @code{mysql_list_processes()}
* mysql_list_tables::           @code{mysql_list_tables()}
* mysql_num_fields::            @code{mysql_num_fields()}
* mysql_num_rows::              @code{mysql_num_rows()}
* mysql_options::               @code{mysql_options()}
* mysql_ping::                  @code{mysql_ping()}
* mysql_query::                 @code{mysql_query()}
* mysql_real_connect::          @code{mysql_real_connect()}
* mysql_real_escape_string::    @code{mysql_real_escape_string()}
* mysql_real_query::            @code{mysql_real_query()}
* mysql_reload::                @code{mysql_reload()}
* mysql_row_seek::              @code{mysql_row_seek()}
* mysql_row_tell::              @code{mysql_row_tell()}
* mysql_select_db::             @code{mysql_select_db()}
* mysql_set_server_option::     @code{mysql_set_server_option()}
* mysql_shutdown::              @code{mysql_shutdown()}
* mysql_sqlstate::              @code{mysql_sqlstate()}
* mysql_ssl_set::               @code{mysql_ssl_set()}
* mysql_stat::                  @code{mysql_stat()}
* mysql_store_result::          @code{mysql_store_result()}
* mysql_thread_id::             @code{mysql_thread_id()}
* mysql_use_result::            @code{mysql_use_result()}
* mysql_warning_count::         @code{mysql_warning_count()}
* mysql_commit::                @code{mysql_commit()}
* mysql_rollback::              @code{mysql_rollback()}
* mysql_autocommit::            @code{mysql_autocommit()}
* mysql_more_results::          @code{mysql_more_results()}
* mysql_next_result::           @code{mysql_next_result()}
@end menu

In the descriptions here, a parameter or return value of @code{NULL} means
@code{NULL} in the sense of the C programming language, not a
MySQL @code{NULL} value.

Functions that return a value generally return a pointer or an integer.
Unless specified otherwise, functions returning a pointer return a
non-@code{NULL} value to indicate success or a @code{NULL} value to indicate
an error, and functions returning an integer return zero to indicate success
or non-zero to indicate an error.  Note that ``non-zero'' means just that.
Unless the function description says otherwise, do not test against a value
other than zero:

@example
if (result)                   /* correct */
    ... error ...

if (result < 0)               /* incorrect */
    ... error ...

if (result == -1)             /* incorrect */
    ... error ...
@end example

When a function returns an error, the @strong{Errors} subsection of the
function description lists the possible types of errors.  You can
find out which of these occurred by calling @code{mysql_errno()}.
A string representation of the error may be obtained by calling
@code{mysql_error()}.


@node mysql_affected_rows, mysql_change_user, C API functions, C API functions
@subsubsection @code{mysql_affected_rows()}

@findex @code{mysql_affected_rows()}

@code{my_ulonglong mysql_affected_rows(MYSQL *mysql)}

@subsubheading Description

Returns the number of rows changed by the last @code{UPDATE}, deleted by
the last @code{DELETE} or inserted by the last @code{INSERT}
statement. May be called immediately after @code{mysql_query()} for
@code{UPDATE}, @code{DELETE}, or @code{INSERT} statements.  For
@code{SELECT} statements, @code{mysql_affected_rows()} works like
@code{mysql_num_rows()}.

@subsubheading Return Values

An integer greater than zero indicates the number of rows affected or
retrieved.  Zero indicates that no records were updated for an
@code{UPDATE} statement, no rows matched the @code{WHERE} clause in the
query or that no query has yet been executed.  @minus{}1 indicates that the
query returned an error or that, for a @code{SELECT} query,
@code{mysql_affected_rows()} was called prior to calling
@code{mysql_store_result()}. Because @code{mysql_affected_rows()}
returns an unsigned value, you can check for @minus{}1 by comparing the
return value to @code{(my_ulonglong)-1} (or to @code{(my_ulonglong)~0},
which is equivalent).

@subsubheading Errors

None.

@subsubheading Example

@example
mysql_query(&mysql,"UPDATE products SET cost=cost*1.25 WHERE group=10");
printf("%ld products updated",(long) mysql_affected_rows(&mysql));
@end example

If you specify the flag @code{CLIENT_FOUND_ROWS} when connecting to
@command{mysqld}, @code{mysql_affected_rows()} will return the number of
rows matched by the @code{WHERE} statement for @code{UPDATE} statements.

Note that when you use a @code{REPLACE} command,
@code{mysql_affected_rows()} returns 2 if the new row replaced an
old row.  This is because in this case one row was inserted after the
duplicate was deleted.

If you use @code{INSERT ... ON DUPLICATE KEY UPDATE} to insert a row,
@code{mysql_affected_rows()} returns 1 if the row is inserted as a new row and
2 if an existing row is updated.


@node mysql_change_user, mysql_character_set_name, mysql_affected_rows, C API functions
@subsubsection @code{mysql_change_user()}

@findex @code{mysql_change_user()}

@code{my_bool mysql_change_user(MYSQL *mysql, const char *user, const
char *password, const char *db)}

@subsubheading Description

Changes the user and causes the database specified by @code{db} to
become the default (current) database on the connection specified by
@code{mysql}.  In subsequent queries, this database is the default for
table references that do not include an explicit database specifier.

This function was introduced in MySQL 3.23.3.

@code{mysql_change_user()} fails if the connected user cannot be
authenticated or doesn't have permission to use the database.  In
this case the user and database are not changed

The @code{db} parameter may be set to @code{NULL} if you don't want to have a
default database.

Starting from MySQL 4.0.6 this command will always @code{ROLLBACK} any
active transactions, close all temporary tables, unlock all locked
tables and reset the state as if one had done a new connect.
This will happen even if the user didn't change.

@subsubheading Return Values

Zero for success.  Non-zero if an error occurred.

@subsubheading Errors

The same that you can get from @code{mysql_real_connect()}.

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@item ER_UNKNOWN_COM_ERROR
The MySQL server doesn't implement this command (probably an old server).
@item ER_ACCESS_DENIED_ERROR
The user or password was wrong.
@item ER_BAD_DB_ERROR
The database didn't exist.
@item ER_DBACCESS_DENIED_ERROR
The user did not have access rights to the database.
@item ER_WRONG_DB_NAME
The database name was too long.
@end table

@subsubheading Example

@example
if (mysql_change_user(&mysql, "user", "password", "new_database"))
@{
   fprintf(stderr, "Failed to change user.  Error: %s\n",
           mysql_error(&mysql));
@}
@end example


@node mysql_character_set_name, mysql_close, mysql_change_user, C API functions
@subsubsection @code{mysql_character_set_name()}

@findex @code{mysql_character_set_name()}

@code{const char *mysql_character_set_name(MYSQL *mysql)}

@subsubheading Description

Returns the default character set for the current connection.

@subsubheading Return Values

The default character set

@subsubheading Errors
None.


@node mysql_close, mysql_connect, mysql_character_set_name, C API functions
@subsubsection @code{mysql_close()}

@findex @code{mysql_close()}

@code{void mysql_close(MYSQL *mysql)}

@subsubheading Description
Closes a previously opened connection.  @code{mysql_close()} also deallocates
the connection handle pointed to by @code{mysql} if the handle was allocated
automatically by @code{mysql_init()} or @code{mysql_connect()}.

@subsubheading Return Values

None.

@subsubheading Errors

None.


@node mysql_connect, mysql_create_db, mysql_close, C API functions
@subsubsection @code{mysql_connect()}

@findex @code{mysql_connect()}

@code{MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)}

@subsubheading Description

This function is deprecated.  It is preferable to use
@code{mysql_real_connect()} instead.

@code{mysql_connect()} attempts to establish a connection to a MySQL
database engine running on @code{host}.  @code{mysql_connect()} must complete
successfully before you can execute any of the other API functions, with the
exception of @code{mysql_get_client_info()}.

The meanings of the parameters are the same as for the corresponding
parameters for @code{mysql_real_connect()} with the difference that the
connection parameter may be @code{NULL}. In this case the C API
allocates memory for the connection structure automatically and frees it
when you call @code{mysql_close()}. The disadvantage of this approach is
that you can't retrieve an error message if the connection fails.  (To
get error information from @code{mysql_errno()} or @code{mysql_error()},
you must provide a valid @code{MYSQL} pointer.)

@subsubheading Return Values

Same as for @code{mysql_real_connect()}.

@subsubheading Errors

Same as for @code{mysql_real_connect()}.


@node mysql_create_db, mysql_data_seek, mysql_connect, C API functions
@subsubsection @code{mysql_create_db()}

@findex @code{mysql_create_db()}

@code{int mysql_create_db(MYSQL *mysql, const char *db)}

@subsubheading Description
Creates the database named by the @code{db} parameter.

This function is deprecated.  It is preferable to use @code{mysql_query()}
to issue an SQL @code{CREATE DATABASE} statement instead.

@subsubheading Return Values

Zero if the database was created successfully. Non-zero if an error
occurred.

@subsubheading Errors
@table @code

@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.

@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.

@item CR_SERVER_LOST
The connection to the server was lost during the query.

@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table

@subsubheading Example

@example
if(mysql_create_db(&mysql, "my_database"))
@{
   fprintf(stderr, "Failed to create new database.  Error: %s\n",
           mysql_error(&mysql));
@}
@end example


@node mysql_data_seek, mysql_debug, mysql_create_db, C API functions
@subsubsection @code{mysql_data_seek()}

@findex @code{mysql_data_seek()}

@code{void mysql_data_seek(MYSQL_RES *result, my_ulonglong offset)}

@subsubheading Description
Seeks to an arbitrary row in a query result set.  The @code{offset}
value is a row number and should be in the range from @code{0} to
@code{mysql_num_rows(result)-1}.

This function requires that the result set structure contains the
entire result of the query, so @code{mysql_data_seek()} may be
used only in conjunction with @code{mysql_store_result()}, not with
@code{mysql_use_result()}.

@subsubheading Return Values

None.

@subsubheading Errors
None.


@node mysql_debug, mysql_drop_db, mysql_data_seek, C API functions
@subsubsection @code{mysql_debug()}

@findex @code{mysql_debug()}

@code{void mysql_debug(const char *debug)}

@subsubheading Description
Does a @code{DBUG_PUSH} with the given string. @code{mysql_debug()} uses the
Fred Fish debug library. To use this function, you must compile the client
library to support debugging.
@xref{Debugging server}. @xref{Debugging client}.

@subsubheading Return Values

None.

@subsubheading Errors
None.

@subsubheading Example

The call shown here causes the client library to generate a trace file in
@file{/tmp/client.trace} on the client machine:

@example
mysql_debug("d:t:O,/tmp/client.trace");
@end example


@node mysql_drop_db, mysql_dump_debug_info, mysql_debug, C API functions
@subsubsection @code{mysql_drop_db()}

@findex @code{mysql_drop_db()}

@code{int mysql_drop_db(MYSQL *mysql, const char *db)}

@subsubheading Description
Drops the database named by the @code{db} parameter.

This function is deprecated.  It is preferable to use @code{mysql_query()}
to issue an SQL @code{DROP DATABASE} statement instead.

@subsubheading Return Values

Zero if the database was dropped successfully. Non-zero if an error
occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table

@subsubheading Example

@example
if(mysql_drop_db(&mysql, "my_database"))
  fprintf(stderr, "Failed to drop the database: Error: %s\n",
          mysql_error(&mysql));
@end example


@node mysql_dump_debug_info, mysql_eof, mysql_drop_db, C API functions
@subsubsection @code{mysql_dump_debug_info()}

@findex @code{mysql_dump_debug_info()}

@code{int mysql_dump_debug_info(MYSQL *mysql)}

@subsubheading Description

Instructs the server to write some debug information to the log. For
this to work, the connected user must have the @code{SUPER} privilege.

@subsubheading Return Values

Zero if the command was successful. Non-zero if an error occurred.

@subsubheading Errors
@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table


@node mysql_eof, mysql_errno, mysql_dump_debug_info, C API functions
@subsubsection @code{mysql_eof()}

@findex @code{mysql_eof()}

@code{my_bool mysql_eof(MYSQL_RES *result)}

@subsubheading Description

This function is deprecated.  @code{mysql_errno()} or @code{mysql_error()}
may be used instead.

@code{mysql_eof()} determines whether the last row of a result
set has been read.

If you acquire a result set from a successful call to
@code{mysql_store_result()}, the client receives the entire set in one
operation.  In this case, a @code{NULL} return from
@code{mysql_fetch_row()} always means the end of the result set has been
reached and it is unnecessary to call @code{mysql_eof()}.  When used
with @code{mysql_store_result()}, @code{mysql_eof()} will always return
true.

On the other hand, if you use @code{mysql_use_result()} to initiate a result
set retrieval, the rows of the set are obtained from the server one by one as
you call @code{mysql_fetch_row()} repeatedly.  Because an error may occur on
the connection during this process, a @code{NULL} return value from
@code{mysql_fetch_row()} does not necessarily mean the end of the result set
was reached normally.  In this case, you can use @code{mysql_eof()} to
determine what happened.  @code{mysql_eof()} returns a non-zero value if the
end of the result set was reached and zero if an error occurred.

Historically, @code{mysql_eof()} predates the standard MySQL error
functions @code{mysql_errno()} and @code{mysql_error()}.  Because those error
functions provide the same information, their use is preferred over
@code{mysql_eof()}, which is now deprecated.  (In fact, they provide more
information, because @code{mysql_eof()} returns only a boolean value whereas
the error functions indicate a reason for the error when one occurs.)

@subsubheading Return Values

Zero if no error occurred. Non-zero if the end of the result set has been
reached.

@subsubheading Errors
None.

@subsubheading Example

The following example shows how you might use @code{mysql_eof()}:

@example
mysql_query(&mysql,"SELECT * FROM some_table");
result = mysql_use_result(&mysql);
while((row = mysql_fetch_row(result)))
@{
    // do something with data
@}
if(!mysql_eof(result))  // mysql_fetch_row() failed due to an error
@{
    fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
@}
@end example

However, you can achieve the same effect with the standard MySQL
error functions:

@example
mysql_query(&mysql,"SELECT * FROM some_table");
result = mysql_use_result(&mysql);
while((row = mysql_fetch_row(result)))
@{
    // do something with data
@}
if(mysql_errno(&mysql))  // mysql_fetch_row() failed due to an error
@{
    fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
@}
@end example


@node mysql_errno, mysql_error, mysql_eof, C API functions
@subsubsection @code{mysql_errno()}

@findex @code{mysql_errno()}

@code{unsigned int mysql_errno(MYSQL *mysql)}

@subsubheading Description

For the connection specified by @code{mysql}, @code{mysql_errno()} returns
the error code for the most recently invoked API function that can succeed
or fail.  A return value of zero means that no error occurred. Client error
message numbers are listed in the MySQL @file{errmsg.h} header file.
Server error message numbers are listed in @file{mysqld_error.h}. In the
MySQL source distribution you can find a complete list of
error messages and error numbers in the file @file{Docs/mysqld_error.txt}.
The server error codes also are listed at @ref{Error-handling}.

Note that some functions like @code{mysql_fetch_row()} don't set
@code{mysql_errno()} if they succeed.

A rule of thumb is that all functions that have to ask the server for
information will reset @code{mysql_errno()} if they succeed.

@subsubheading Return Values

An error code value for the last @code{mysql_@var{xxx}()} call, if it failed.
zero means no error occurred.

@subsubheading Errors
None.


@node mysql_error, mysql_escape_string, mysql_errno, C API functions
@subsubsection @code{mysql_error()}

@findex @code{mysql_error()}

@code{const char *mysql_error(MYSQL *mysql)}

@subsubheading Description

For the connection specified by @code{mysql}, @code{mysql_error()}
returns a null-terminated string containing the error message for the
most recently invoked API function that failed. If a function didn't
fail, the return value of @code{mysql_error()} may be the previous error
or an empty string to indicate no error.

A rule of thumb is that all functions that have to ask the server for
information will reset @code{mysql_error()} if they succeed.

For functions that reset @code{mysql_errno()}, the following two tests
are equivalent:

@example
if(mysql_errno(&mysql))
@{
    // an error occurred
@}

if(mysql_error(&mysql)[0] != '\0')
@{
    // an error occurred
@}
@end example

The language of the client error messages may be changed by
recompiling the MySQL client library. Currently you can choose
error messages in several different languages.
@xref{Languages}.

@subsubheading Return Values

A null-terminated character string that describes the error.  An empty string
if no error occurred.

@subsubheading Errors
None.


@node mysql_escape_string, mysql_fetch_field, mysql_error, C API functions
@subsubsection @code{mysql_escape_string()}

@findex @code{mysql_escape_string()}

You should use @code{mysql_real_escape_string()} instead!

This function is identical to @code{mysql_real_escape_string()} except
that @code{mysql_real_escape_string()} takes a connection handler as
its first argument and escapes the string according to the current
character set.  @code{mysql_escape_string()} does not take a connection
argument and does not respect the current charset setting.


@node mysql_fetch_field, mysql_fetch_fields, mysql_escape_string, C API functions
@subsubsection @code{mysql_fetch_field()}

@findex @code{mysql_fetch_field()}

@code{MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)}

@subsubheading Description

Returns the definition of one column of a result set as a @code{MYSQL_FIELD}
structure. Call this function repeatedly to retrieve information about all
columns in the result set.  @code{mysql_fetch_field()} returns @code{NULL}
when no more fields are left.

@code{mysql_fetch_field()} is reset to return information about the first
field each time you execute a new @code{SELECT} query.  The field returned by
@code{mysql_fetch_field()} is also affected by calls to
@code{mysql_field_seek()}.

If you've called @code{mysql_query()} to perform a @code{SELECT} on a table
but have not called @code{mysql_store_result()}, MySQL returns the
default blob length (8KB) if you call @code{mysql_fetch_field()} to ask
for the length of a @code{BLOB} field.  (The 8KB size is chosen because
MySQL doesn't know the maximum length for the @code{BLOB}. This
should be made configurable sometime.) Once you've retrieved the result set,
@code{field->max_length} contains the length of the largest value for this
column in the specific query.

@subsubheading Return Values

The @code{MYSQL_FIELD} structure for the current column. @code{NULL}
if no columns are left.

@subsubheading Errors
None.

@subsubheading Example

@example
MYSQL_FIELD *field;

while((field = mysql_fetch_field(result)))
@{
    printf("field name %s\n", field->name);
@}
@end example


@node mysql_fetch_fields, mysql_fetch_field_direct, mysql_fetch_field, C API functions
@subsubsection @code{mysql_fetch_fields()}

@findex @code{mysql_fetch_fields()}

@code{MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)}

@subsubheading Description

Returns an array of all @code{MYSQL_FIELD} structures for a result set.
Each structure provides the field definition for one column of the result
set.

@subsubheading Return Values

An array of @code{MYSQL_FIELD} structures for all columns of a result set.

@subsubheading Errors
None.

@subsubheading Example

@example
unsigned int num_fields;
unsigned int i;
MYSQL_FIELD *fields;

num_fields = mysql_num_fields(result);
fields = mysql_fetch_fields(result);
for(i = 0; i < num_fields; i++)
@{
   printf("Field %u is %s\n", i, fields[i].name);
@}
@end example


@node mysql_fetch_field_direct, mysql_fetch_lengths, mysql_fetch_fields, C API functions
@subsubsection @code{mysql_fetch_field_direct()}

@findex @code{mysql_fetch_field_direct()}

@code{MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int fieldnr)}

@subsubheading Description

Given a field number @code{fieldnr} for a column within a result set, returns
that column's field definition as a @code{MYSQL_FIELD} structure. You may use
this function to retrieve the definition for an arbitrary column.  The value
of @code{fieldnr} should be in the range from 0 to
@code{mysql_num_fields(result)-1}.

@subsubheading Return Values

The @code{MYSQL_FIELD} structure for the specified column.

@subsubheading Errors
None.

@subsubheading Example

@example
unsigned int num_fields;
unsigned int i;
MYSQL_FIELD *field;

num_fields = mysql_num_fields(result);
for(i = 0; i < num_fields; i++)
@{
    field = mysql_fetch_field_direct(result, i);
    printf("Field %u is %s\n", i, field->name);
@}
@end example


@node mysql_fetch_lengths, mysql_fetch_row, mysql_fetch_field_direct, C API functions
@subsubsection @code{mysql_fetch_lengths()}

@findex @code{mysql_fetch_lengths()}

@code{unsigned long *mysql_fetch_lengths(MYSQL_RES *result)}

@subsubheading Description

Returns the lengths of the columns of the current row within a result set.
If you plan to copy field values, this length information is also useful for
optimization, because you can avoid calling @code{strlen()}.  In addition, if
the result set contains binary data, you @strong{must} use this function to
determine the size of the data, because @code{strlen()} returns incorrect
results for any field containing null characters.

The length for empty columns and for columns containing @code{NULL} values is
zero.  To see how to distinguish these two cases, see the description for
@code{mysql_fetch_row()}.

@subsubheading Return Values

An array of unsigned long integers representing the size of each column (not
including any terminating null characters).
@code{NULL} if an error occurred.

@subsubheading Errors
@code{mysql_fetch_lengths()} is valid only for the current row of the result
set.  It returns @code{NULL} if you call it before calling
@code{mysql_fetch_row()} or after retrieving all rows in the result.

@subsubheading Example

@example
MYSQL_ROW row;
unsigned long *lengths;
unsigned int num_fields;
unsigned int i;

row = mysql_fetch_row(result);
if (row)
@{
    num_fields = mysql_num_fields(result);
    lengths = mysql_fetch_lengths(result);
    for(i = 0; i < num_fields; i++)
    @{
         printf("Column %u is %lu bytes in length.\n", i, lengths[i]);
    @}
@}
@end example


@node mysql_fetch_row, mysql_field_count, mysql_fetch_lengths, C API functions
@subsubsection @code{mysql_fetch_row()}

@findex @code{mysql_fetch_row()}

@code{MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)}

@subsubheading Description

Retrieves the next row of a result set. When used after
@code{mysql_store_result()}, @code{mysql_fetch_row()} returns @code{NULL}
when there are no more rows to retrieve.  When used after
@code{mysql_use_result()}, @code{mysql_fetch_row()} returns @code{NULL} when
there are no more rows to retrieve or if an error occurred.

The number of values in the row is given by @code{mysql_num_fields(result)}.
If @code{row} holds the return value from a call to @code{mysql_fetch_row()},
pointers to the values are accessed as @code{row[0]} to
@code{row[mysql_num_fields(result)-1]}.  @code{NULL} values in the row are
indicated by @code{NULL} pointers.

The lengths of the field values in the row may be obtained by calling
@code{mysql_fetch_lengths()}.  Empty fields and fields containing
@code{NULL} both have length 0; you can distinguish these by checking
the pointer for the field value.  If the pointer is @code{NULL}, the field
is @code{NULL}; otherwise, the field is empty.

@subsubheading Return Values

A @code{MYSQL_ROW} structure for the next row.  @code{NULL} if
there are no more rows to retrieve or if an error occurred.

@subsubheading Errors

Note that error is not reset between calls to @code{mysql_fetch_row()}

@table @code
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table

@subsubheading Example

@example
MYSQL_ROW row;
unsigned int num_fields;
unsigned int i;

num_fields = mysql_num_fields(result);
while ((row = mysql_fetch_row(result)))
@{
   unsigned long *lengths;
   lengths = mysql_fetch_lengths(result);
   for(i = 0; i < num_fields; i++)
   @{
       printf("[%.*s] ", (int) lengths[i], row[i] ? row[i] : "NULL");
   @}
   printf("\n");
@}
@end example


@node mysql_field_count, mysql_field_seek, mysql_fetch_row, C API functions
@subsubsection @code{mysql_field_count()}

@findex @code{mysql_field_count()}

@code{unsigned int mysql_field_count(MYSQL *mysql)}

If you are using a version of MySQL earlier than Version 3.22.24, you
should use @code{unsigned int mysql_num_fields(MYSQL *mysql)} instead.

@subsubheading Description

Returns the number of columns for the most recent query on the connection.

The normal use of this function is when @code{mysql_store_result()}
returned @code{NULL} (and thus you have no result set pointer).
In this case, you can call @code{mysql_field_count()} to
determine whether @code{mysql_store_result()} should have produced a
non-empty result.  This allows the client program to take proper action
without knowing whether the query was a @code{SELECT} (or
@code{SELECT}-like) statement.  The example shown here illustrates how this
may be done.

@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}.

@subsubheading Return Values

An unsigned integer representing the number of columns in a result set.

@subsubheading Errors
None.

@subsubheading Example

@example
MYSQL_RES *result;
unsigned int num_fields;
unsigned int num_rows;

if (mysql_query(&mysql,query_string))
@{
    // error
@}
else // query succeeded, process any data returned by it
@{
    result = mysql_store_result(&mysql);
    if (result)  // there are rows
    @{
        num_fields = mysql_num_fields(result);
        // retrieve rows, then call mysql_free_result(result)
    @}
    else  // mysql_store_result() returned nothing; should it have?
    @{
        if(mysql_field_count(&mysql) == 0)
        @{
            // query does not return data
            // (it was not a SELECT)
            num_rows = mysql_affected_rows(&mysql);
        @}
        else // mysql_store_result() should have returned data
        @{
            fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
        @}
    @}
@}
@end example

An alternative is to replace the @code{mysql_field_count(&mysql)} call with
@code{mysql_errno(&mysql)}.  In this case, you are checking directly for an
error from @code{mysql_store_result()} rather than inferring from the value
of @code{mysql_field_count()} whether the statement was a
@code{SELECT}.


@node mysql_field_seek, mysql_field_tell, mysql_field_count, C API functions
@subsubsection @code{mysql_field_seek()}

@findex @code{mysql_field_seek()}

@code{MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)}

@subsubheading Description

Sets the field cursor to the given offset.   The next call to
@code{mysql_fetch_field()} will retrieve the field definition of the column
associated with that offset.

To seek to the beginning of a row, pass an @code{offset} value of zero.

@subsubheading Return Values

The previous value of the field cursor.

@subsubheading Errors
None.


@node mysql_field_tell, mysql_free_result, mysql_field_seek, C API functions
@subsubsection @code{mysql_field_tell()}

@findex @code{mysql_field_tell()}

@code{MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)}

@subsubheading Description

Returns the position of the field cursor used for the last
@code{mysql_fetch_field()}. This value can be used as an argument to
@code{mysql_field_seek()}.

@subsubheading Return Values

The current offset of the field cursor.

@subsubheading Errors
None.


@node mysql_free_result, mysql_get_client_info, mysql_field_tell, C API functions
@subsubsection @code{mysql_free_result()}

@findex @code{mysql_free_result()}

@code{void mysql_free_result(MYSQL_RES *result)}

@subsubheading Description

Frees the memory allocated for a result set by @code{mysql_store_result()},
@code{mysql_use_result()}, @code{mysql_list_dbs()}, etc.  When you are done
with a result set, you must free the memory it uses by calling
@code{mysql_free_result()}.

Do not attempt to access a result set after freeing it.

@subsubheading Return Values

None.

@subsubheading Errors
None.


@node mysql_get_client_info, mysql_get_client_version, mysql_free_result, C API functions
@subsubsection @code{mysql_get_client_info()}

@findex @code{mysql_get_client_info()}

@code{char *mysql_get_client_info(void)}

@subsubheading Description

Returns a string that represents the client library version.

@subsubheading Return Values

A character string that represents the MySQL client library version.

@subsubheading Errors
None.


@node mysql_get_client_version, mysql_get_host_info, mysql_get_client_info, C API functions
@subsubsection @code{mysql_get_client_version()}

@findex @code{mysql_get_client_version()}

@code{unsigned long mysql_get_client_version(void)}

@subsubheading Description

Returns an integer that represents the client library version.
The value has the format @code{XYYZZ} where @code{X} is the major
version, @code{YY} is the release level, and @code{ZZ} is the version
number within the release level. For example, a value of @code{40102}
represents a client library version of @code{4.1.2}.

This function was added in MySQL 4.0.16.

@subsubheading Return Values

An integer that represents the MySQL client library version.

@subsubheading Errors
None.

@node mysql_get_host_info, mysql_get_proto_info, mysql_get_client_version, C API functions
@subsubsection @code{mysql_get_host_info()}

@findex @code{mysql_get_host_info()}

@code{char *mysql_get_host_info(MYSQL *mysql)}

@subsubheading Description

Returns a string describing the type of connection in use, including the
server hostname.

@subsubheading Return Values

A character string representing the server hostname and the connection type.

@subsubheading Errors
None.


@node mysql_get_proto_info, mysql_get_server_info, mysql_get_host_info, C API functions
@subsubsection @code{mysql_get_proto_info()}

@findex @code{mysql_get_proto_info()}

@code{unsigned int mysql_get_proto_info(MYSQL *mysql)}

@subsubheading Description

Returns the protocol version used by current connection.

@subsubheading Return Values

An unsigned integer representing the protocol version used by the current
connection.

@subsubheading Errors
None.


@node mysql_get_server_info, mysql_get_server_version, mysql_get_proto_info, C API functions
@subsubsection @code{mysql_get_server_info()}

@findex @code{mysql_get_server_info()}

@code{char *mysql_get_server_info(MYSQL *mysql)}

@subsubheading Description

Returns a string that represents the server version number.

@subsubheading Return Values

A character string that represents the server version number.

@subsubheading Errors
None.


@node mysql_get_server_version, mysql_hex_string, mysql_get_server_info, C API functions
@subsubsection @code{mysql_get_server_version()}

@findex @code{mysql_get_server_version()}

@code{unsigned long mysql_get_server_version(MYSQL *mysql)}

@subsubheading Description

Returns the version number of the server as an integer.

This function was added in MySQL 4.1.0.

@subsubheading Return Values

A number that represents the MySQL server version in this format:

@example
major_version*10000 + minor_version *100 + sub_version
@end example

For example, 4.1.2 is returned as 40102.

This function is useful in client programs for quickly determining
whether some version-specific server capability exists.

@subsubheading Errors
None.


@node mysql_hex_string, mysql_info, mysql_get_server_version, C API functions
@subsubsection @code{mysql_hex_string()}

@findex @code{mysql_hex_string()}

@code{unsigned long mysql_hex_string(char *to, const char *from, unsigned long length)}

@subsubheading Description

This function is used to create a legal SQL string that you can use in a
SQL statement. @xref{String syntax}.

The string in @code{from} is encoded to hexadecimal format, with each
character encoded as two hexadecimal digits.  The result is placed in
@code{to} and a terminating null byte is appended.

The string pointed to by @code{from} must be @code{length} bytes long.
You must allocate the @code{to} buffer to be at least @code{length*2+1}
bytes long.  When @code{mysql_hex_string()} returns, the contents of
@code{to} will be a null-terminated string.  The return value is the length
of the encoded string, not including the terminating null character.

The return value can be placed into an SQL statement using either
@code{0x@var{value}} or @code{X'@var{value}'} format.  However, the
return value does not include the @code{0x} or @code{X'...'}. The caller
must supply whichever of those is desired.

@code{mysql_hex_string()} was added in MySQL 4.0.23 and 4.1.8.

@subsubheading Example

@example
char query[1000],*end;

end = strmov(query,"INSERT INTO test_table values(");
end = strmov(end,"0x");
end += mysql_hex_string(end,"What's this",11);
end = strmov(end,",0x");
end += mysql_hex_string(end,"binary data: \0\r\n",16);
*end++ = ')';

if (mysql_real_query(&mysql,query,(unsigned int) (end - query)))
@{
   fprintf(stderr, "Failed to insert row, Error: %s\n",
           mysql_error(&mysql));
@}
@end example

The @code{strmov()} function used in the example is included in the
@code{mysqlclient} library and works like @code{strcpy()} but returns a
pointer to the terminating null of the first parameter.

@subsubheading Return Values

The length of the value placed into @code{to}, not including the
terminating null character.

@subsubheading Errors
None.


@node mysql_info, mysql_init, mysql_hex_string, C API functions
@subsubsection @code{mysql_info()}

@findex @code{mysql_info()}

@code{char *mysql_info(MYSQL *mysql)}

@subsubheading Description

Retrieves a string providing information about the most recently executed
query, but only for the statements listed here.  For other statements,
@code{mysql_info()} returns @code{NULL}.  The format of the string varies
depending on the type of query, as described here.  The numbers are
illustrative only; the string will contain values appropriate for the query.

@table @code
@item INSERT INTO ... SELECT ...
String format: @code{Records: 100 Duplicates: 0 Warnings: 0}
@item INSERT INTO ... VALUES (...),(...),(...)...
String format: @code{Records: 3  Duplicates: 0  Warnings: 0}
@item LOAD DATA INFILE ...
String format: @code{Records: 1 Deleted: 0 Skipped: 0 Warnings: 0}
@item ALTER TABLE
String format: @code{Records: 3 Duplicates: 0 Warnings: 0}
@item UPDATE
String format: @code{Rows matched: 40 Changed: 40 Warnings: 0}
@end table

Note that @code{mysql_info()} returns a non-@code{NULL} value for
@code{INSERT ... VALUES} only for the multiple-row form
of the statement (that is, only if multiple value lists are
specified).

@subsubheading Return Values

A character string representing additional information about the most
recently executed query.  @code{NULL} if no information is available for the
query.

@subsubheading Errors
None.


@node mysql_init, mysql_insert_id, mysql_info, C API functions
@subsubsection @code{mysql_init()}

@findex @code{mysql_init()}

@code{MYSQL *mysql_init(MYSQL *mysql)}

@subsubheading Description

Allocates or initializes a @code{MYSQL} object suitable for
@code{mysql_real_connect()}.  If @code{mysql} is a @code{NULL} pointer, the
function allocates, initializes, and returns a new object.  Otherwise, the
object is initialized and the address of the object is returned.  If
@code{mysql_init()} allocates a new object, it will be freed when
@code{mysql_close()} is called to close the connection.

@subsubheading Return Values

An initialized @code{MYSQL*} handle.  @code{NULL} if there was
insufficient memory to allocate a new object.

@subsubheading Errors
In case of insufficient memory, @code{NULL} is returned.


@node mysql_insert_id, mysql_kill, mysql_init, C API functions
@subsubsection @code{mysql_insert_id()}

@findex @code{mysql_insert_id()}

@code{my_ulonglong mysql_insert_id(MYSQL *mysql)}

@subsubheading Description

Returns the value generated for an @code{AUTO_INCREMENT} column by the
previous @code{INSERT} or @code{UPDATE} statement.  Use this function after
you have performed an @code{INSERT} statement into a table that contains an
@code{AUTO_INCREMENT} field.

More precisely, @code{mysql_insert_id()} is updated under these conditions:

@itemize @bullet
@item
@code{INSERT} statements that store a value into an @code{AUTO_INCREMENT}
column. This is true whether the value is automatically generated by
storing the special values @code{NULL} or @code{0} into the column, or is
an explicit non-special value.

@item
In the case of a multiple-row @code{INSERT} statement, @code{mysql_insert_id()}
returns the @strong{first} automatically generated @code{AUTO_INCREMENT}
value; if no such value is generated, it returns the last @strong{last}
explicit value inserted into the @code{AUTO_INCREMENT} column.

@item
@code{INSERT} statements that generate an @code{AUTO_INCREMENT} value by
inserting @code{LAST_INSERT_ID(@var{expr})} into any column.

@item
@code{INSERT} statements that generate an @code{AUTO_INCREMENT} value by
updating any column to @code{LAST_INSERT_ID(@var{expr})}.

@item
The value of @code{mysql_insert_id()} is not affected by statements such as
@code{SELECT} that return a result set.

@item
If the previous statement returned an error,
the value of @code{mysql_insert_id()} is undefined.
@end itemize

Note that @code{mysql_insert_id()} returns @code{0} if the previous statement
does not use an @code{AUTO_INCREMENT} value.  If you need to save
the value for later, be sure to call @code{mysql_insert_id()} immediately
after the statement that generates the value.

The value of @code{mysql_insert_id()} is affected only by statements issued
within the current client connection. It is not affected by statements issued
by other clients.

@xref{Information functions}.

Also note that the value of the SQL @code{LAST_INSERT_ID()} function always
contains the most recently generated @code{AUTO_INCREMENT} value, and is
not reset between statements because the value of that function is maintained
in the server.  Another difference is that @code{LAST_INSERT_ID()} is not
updated if you set an @code{AUTO_INCREMENT} column to a specific non-special
value.

The reason for the difference between @code{LAST_INSERT_ID()} and
@code{mysql_insert_id()} is that @code{LAST_INSERT_ID()} is made easy to
use in scripts while @code{mysql_insert_id()} tries to provide a little
more exact information of what happens to the @code{AUTO_INCREMENT} column.

@subsubheading Return Values

Described in the preceding discussion.

@subsubheading Errors
None.


@node mysql_kill, mysql_list_dbs, mysql_insert_id, C API functions
@subsubsection @code{mysql_kill()}

@findex @code{mysql_kill()}

@code{int mysql_kill(MYSQL *mysql, unsigned long pid)}

@subsubheading Description

Asks the server to kill the thread specified by @code{pid}.

@subsubheading Return Values

Zero for success.  Non-zero if an error occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table


@node mysql_list_dbs, mysql_list_fields, mysql_kill, C API functions
@subsubsection @code{mysql_list_dbs()}

@findex @code{mysql_list_dbs()}

@code{MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)}

@subsubheading Description

Returns a result set consisting of database names on the server that match
the simple regular expression specified by the @code{wild} parameter.
@code{wild} may contain the wildcard characters @samp{%} or @samp{_}, or may
be a @code{NULL} pointer to match all databases.  Calling
@code{mysql_list_dbs()} is similar to executing the query @code{SHOW
databases [LIKE wild]}.

You must free the result set with @code{mysql_free_result()}.

@subsubheading Return Values

A @code{MYSQL_RES} result set for success.  @code{NULL} if an error occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_OUT_OF_MEMORY
Out of memory.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table


@node mysql_list_fields, mysql_list_processes, mysql_list_dbs, C API functions
@subsubsection @code{mysql_list_fields()}

@findex @code{mysql_list_fields()}

@code{MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)}

@subsubheading Description

Returns a result set consisting of field names in the given table that match
the simple regular expression specified by the @code{wild} parameter.
@code{wild} may contain the wildcard characters @samp{%} or @samp{_}, or may
be a @code{NULL} pointer to match all fields.  Calling
@code{mysql_list_fields()} is similar to executing the query @code{SHOW
COLUMNS FROM @var{tbl_name} [LIKE @var{wild}]}.

Note that it's recommended that you use @code{SHOW COLUMNS FROM @var{tbl_name}}
instead of @code{mysql_list_fields()}.

You must free the result set with @code{mysql_free_result()}.

@subsubheading Return Values

A @code{MYSQL_RES} result set for success.  @code{NULL} if an error occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table


@node mysql_list_processes, mysql_list_tables, mysql_list_fields, C API functions
@subsubsection @code{mysql_list_processes()}

@findex @code{mysql_list_processes()}

@code{MYSQL_RES *mysql_list_processes(MYSQL *mysql)}

@subsubheading Description

Returns a result set describing the current server threads.  This is the same
kind of information as that reported by @command{mysqladmin processlist} or
a @code{SHOW PROCESSLIST} query.

You must free the result set with @code{mysql_free_result()}.

@subsubheading Return Values

A @code{MYSQL_RES} result set for success.  @code{NULL} if an error occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table


@node mysql_list_tables, mysql_num_fields, mysql_list_processes, C API functions
@subsubsection @code{mysql_list_tables()}

@findex @code{mysql_list_tables()}

@code{MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)}

@subsubheading Description

Returns a result set consisting of table names in the current database that
match the simple regular expression specified by the @code{wild} parameter.
@code{wild} may contain the wildcard characters @samp{%} or @samp{_}, or may
be a @code{NULL} pointer to match all tables.  Calling
@code{mysql_list_tables()} is similar to executing the query @code{SHOW
tables [LIKE wild]}.

You must free the result set with @code{mysql_free_result()}.

@subsubheading Return Values

A @code{MYSQL_RES} result set for success.  @code{NULL} if an error occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table


@node mysql_num_fields, mysql_num_rows, mysql_list_tables, C API functions
@subsubsection @code{mysql_num_fields()}

@findex @code{mysql_num_fields()}
@findex @code{mysql_field_count()}

@code{unsigned int mysql_num_fields(MYSQL_RES *result)}

Or:

@code{unsigned int mysql_num_fields(MYSQL *mysql)}

The second form doesn't work on MySQL 3.22.24 or newer.  To pass a
@code{MYSQL*} argument, you must use
@code{unsigned int mysql_field_count(MYSQL *mysql)} instead.

@subsubheading Description

Returns the number of columns in a result set.

Note that you can get the number of columns either from a pointer to a result
set or to a connection handle.  You would use the connection handle if
@code{mysql_store_result()} or @code{mysql_use_result()} returned
@code{NULL} (and thus you have no result set pointer).  In this case, you can
call @code{mysql_field_count()} to determine whether
@code{mysql_store_result()} should have produced a non-empty result.  This
allows the client program to take proper action without knowing whether or
not the query was a @code{SELECT} (or @code{SELECT}-like) statement.  The
example shown here illustrates how this may be done.

@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}.

@subsubheading Return Values

An unsigned integer representing the number of columns in a result set.

@subsubheading Errors
None.

@subsubheading Example

@example
MYSQL_RES *result;
unsigned int num_fields;
unsigned int num_rows;

if (mysql_query(&mysql,query_string))
@{
    // error
@}
else // query succeeded, process any data returned by it
@{
    result = mysql_store_result(&mysql);
    if (result)  // there are rows
    @{
        num_fields = mysql_num_fields(result);
        // retrieve rows, then call mysql_free_result(result)
    @}
    else  // mysql_store_result() returned nothing; should it have?
    @{
        if (mysql_errno(&mysql))
        @{
           fprintf(stderr, "Error: %s\n", mysql_error(&mysql));
        @}
        else if (mysql_field_count(&mysql) == 0)
        @{
            // query does not return data
            // (it was not a SELECT)
            num_rows = mysql_affected_rows(&mysql);
        @}
    @}
@}
@end example

An alternative (if you know that your query should have returned a result set)
is to replace the @code{mysql_errno(&mysql)} call with a check whether
@code{mysql_field_count(&mysql)} is = 0.  This will happen only if something
went wrong.


@node mysql_num_rows, mysql_options, mysql_num_fields, C API functions
@subsubsection @code{mysql_num_rows()}

@findex @code{mysql_num_rows()}

@code{my_ulonglong mysql_num_rows(MYSQL_RES *result)}

@subsubheading Description

Returns the number of rows in the result set.

The use of @code{mysql_num_rows()} depends on whether you use
@code{mysql_store_result()} or @code{mysql_use_result()} to return the result
set.  If you use @code{mysql_store_result()}, @code{mysql_num_rows()} may be
called immediately.  If you use @code{mysql_use_result()},
@code{mysql_num_rows()} will not return the correct value until all the rows
in the result set have been retrieved.

@subsubheading Return Values

The number of rows in the result set.

@subsubheading Errors
None.


@node mysql_options, mysql_ping, mysql_num_rows, C API functions
@subsubsection @code{mysql_options()}

@findex @code{mysql_options()}

@code{int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)}

@subsubheading Description

Can be used to set extra connect options and affect behavior for a connection.
This function may be called multiple times to set several options.

@code{mysql_options()} should be called after @code{mysql_init()} and before
@code{mysql_connect()} or @code{mysql_real_connect()}.

The @code{option} argument is the option that you want to set; the @code{arg}
argument is the value for the option. If the option is an integer, then
@code{arg} should point to the value of the integer.

Possible option values:

@c TODO: this is missing a bunch of option values; see mysql.h.

@multitable @columnfractions .42 .20 .38
@item @strong{Option} @tab @strong{Argument Type} @tab @strong{Function}
@item @code{MYSQL_OPT_CONNECT_TIMEOUT} @tab @code{unsigned int *} @tab Connect timeout in seconds.
@item @code{MYSQL_OPT_READ_TIMEOUT} @tab @code{unsigned int *} @tab Timeout for reads from server (works currently only on Windows on TCP/IP connections)
@item @code{MYSQL_OPT_WRITE_TIMEOUT} @tab @code{unsigned int *} @tab Timeout for writes to server (works currently only on Windows on TCP/IP connections)
@item @code{MYSQL_OPT_COMPRESS} @tab Not used @tab Use the compressed client/server protocol.
@item @code{MYSQL_OPT_LOCAL_INFILE} @tab optional pointer to uint @tab If no pointer is given or if pointer points to an @code{unsigned int != 0} the command @code{LOAD LOCAL INFILE} is enabled.
@item @code{MYSQL_OPT_NAMED_PIPE} @tab Not used @tab Use named pipes to connect to a MySQL server on NT.
@item @code{MYSQL_INIT_COMMAND} @tab @code{char *} @tab Command to execute when connecting to the MySQL server. Will automatically be re-executed when reconnecting.
@item @code{MYSQL_READ_DEFAULT_FILE} @tab @code{char *} @tab Read options from the named option file instead of from @file{my.cnf}.
@item @code{MYSQL_READ_DEFAULT_GROUP} @tab @code{char *} @tab Read options from the named group from @file{my.cnf} or the file specified with @code{MYSQL_READ_DEFAULT_FILE}.
@item @code{MYSQL_OPT_PROTOCOL} @tab @code{unsigned int *} @tab Type of protocol to use. Should be one of the enum values of @code{mysql_protocol_type} defined in @file{mysql.h}.
@item @code{MYSQL_SHARED_MEMORY_BASE_NAME} @tab @code{char*} @tab Named of shared memory object for communication to server. Should be same as the option @code{-shared-memory-base-name} used for the mysqld server you want's to connect to.
@end multitable

@code{MYSQL_OPT_READ_TIMEOUT} and @code{MYSQL_OPT_WRITE_TIMEOUT} were added
in MySQL 4.1.1.

Note that the group @code{client} is always read if you use
@code{MYSQL_READ_DEFAULT_FILE} or @code{MYSQL_READ_DEFAULT_GROUP}.

The specified group in the option file may contain the following options:

@multitable @columnfractions .25 .60
@item @strong{Option} @tab @strong{Description}
@item @code{connect-timeout} @tab Connect timeout in seconds. On Linux this timeout is also used for waiting for the first answer from the server.
@item @code{compress} @tab Use the compressed client/server protocol.
@item @code{database} @tab Connect to this database if no database was specified in the connect command.
@item @code{debug} @tab Debug options.
@item @code{disable-local-infile} @tab Disable use of @code{LOAD DATA LOCAL}.
@item @code{host} @tab Default hostname.
@item @code{init-command} @tab Command to execute when connecting to MySQL server. Will automatically be re-executed when reconnecting.
@item @code{interactive-timeout} @tab Same as specifying @code{CLIENT_INTERACTIVE} to @code{mysql_real_connect()}. @xref{mysql_real_connect}.
@item @code{local-infile[=(0|1)]} @tab If no argument or argument != 0 then enable use of @code{LOAD DATA LOCAL}.
@item @code{max_allowed_packet} @tab Max size of packet client can read from server.
@item @code{password} @tab Default password.
@item @code{pipe} @tab Use named pipes to connect to a MySQL server on NT.
@item @code{protocol=@{TCP | SOCKET | PIPE | MEMORY@}} @tab The protocol to use when connecting to server (New in 4.1)
@item @code{port} @tab Default port number.
@item @code{return-found-rows} @tab Tell @code{mysql_info()} to return found rows instead of updated rows when using @code{UPDATE}.
@item @code{shared-memory-base-name=@var{name}} @tab Shared memory name to use to connect to server (default is "MySQL"). New in MySQL 4.1.
@item @code{socket} @tab Default socket file.
@item @code{user} @tab Default user.
@end multitable

Note that @code{timeout} has been replaced by @code{connect-timeout}, but
@code{timeout} will still work for a while.

For more information about option files, see @ref{Option files}.

@subsubheading Return Values

Zero for success.  Non-zero if you used an unknown option.

@subsubheading Example

@example
MYSQL mysql;

mysql_init(&mysql);
mysql_options(&mysql,MYSQL_OPT_COMPRESS,0);
mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc");
if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0))
@{
    fprintf(stderr, "Failed to connect to database: Error: %s\n",
          mysql_error(&mysql));
@}
@end example

This code requests the client to use the compressed client/server protocol and
read the additional options from the @code{odbc} section in the @file{my.cnf}
file.


@node mysql_ping, mysql_query, mysql_options, C API functions
@subsubsection @code{mysql_ping()}

@findex @code{mysql_ping()}

@code{int mysql_ping(MYSQL *mysql)}

@subsubheading Description

Checks whether the connection to the server is working. If it has gone
down, an automatic reconnection is attempted.

This function can be used by clients that remain idle for a long while,
to check whether the server has closed the connection and reconnect
if necessary.

@subsubheading Return Values

Zero if the server is alive. Non-zero if an error occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table


@node mysql_query, mysql_real_connect, mysql_ping, C API functions
@subsubsection @code{mysql_query()}

@findex @code{mysql_query()}

@code{int mysql_query(MYSQL *mysql, const char *query)}

@subsubheading Description
Executes the SQL query pointed to by the null-terminated string @code{query}.
Normally, the string must consist of a single SQL statement and you should
not add a terminating semicolon (@samp{;}) or @code{\g} to the statement.
If multiple-statement execution has been enabled, the string can contain
several statements separated by semicolons.
@xref{C API multiple queries}.

@code{mysql_query()} cannot be used for queries that contain binary data; you
should use @code{mysql_real_query()} instead.  (Binary data may contain the
@samp{\0} character, which @code{mysql_query()} interprets as the end of the
query string.)

If you want to know whether the query should return a result set, you can
use @code{mysql_field_count()} to check for this.
@xref{mysql_field_count, , @code{mysql_field_count()}}.

@subsubheading Return Values

Zero if the query was successful. Non-zero if an error occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table


@node mysql_real_connect, mysql_real_escape_string, mysql_query, C API functions
@subsubsection @code{mysql_real_connect()}

@findex @code{mysql_real_connect()}

@code{MYSQL *mysql_real_connect(MYSQL *mysql, const char *host,
                 const char *user, const char *passwd, const char *db,
                 unsigned int port, const char *unix_socket,
                 unsigned long client_flag)}

@subsubheading Description

@code{mysql_real_connect()} attempts to establish a connection to a
MySQL database engine running on @code{host}.
@code{mysql_real_connect()} must complete successfully before you can execute
any of the other API functions, with the exception of
@code{mysql_get_client_info()}.

The parameters are specified as follows:

@itemize @bullet
@item
The first parameter should be the address of an existing @code{MYSQL}
structure.  Before calling @code{mysql_real_connect()} you must call
@code{mysql_init()} to initialize the @code{MYSQL} structure. You can
change a lot of connect options with the @code{mysql_options()}
call.  @xref{mysql_options, @code{mysql_options()}}.

@item
The value of @code{host} may be either a hostname or an IP address.  If
@code{host} is @code{NULL} or the string @code{"localhost"}, a connection to
the local host is assumed. If the OS supports sockets (Unix) or named pipes
(Windows), they are used instead of TCP/IP to connect to the server.

@item
The @code{user} parameter contains the user's MySQL login ID.  If
@code{user} is @code{NULL} or the empty string @code{""}, the current
user is assumed.  Under Unix, this is the current login name.  Under
Windows ODBC, the current username must be specified explicitly.
@xref{DSN on Windows}.

@item
The @code{passwd} parameter contains the password for @code{user}.  If
@code{passwd} is @code{NULL}, only entries in the @code{user} table for the
user that have a blank (empty) password field will be checked for a match. This
allows the database administrator to set up the MySQL privilege
system in such a way that users get different privileges depending on whether
or not they have specified a password.

Note: Do not attempt to encrypt the password before calling
@code{mysql_real_connect()}; password encryption is handled automatically by
the client API.

@item
@code{db} is the database name.
If @code{db} is not @code{NULL}, the connection will set the default
database to this value.

@item
If @code{port} is not 0, the value will be used as the port number
for the TCP/IP connection.  Note that the @code{host} parameter
determines the type of the connection.

@item
If @code{unix_socket} is not @code{NULL}, the string specifies the
socket or named pipe that should be used.  Note that the @code{host}
parameter determines the type of the connection.

@item
The value of @code{client_flag} is usually 0, but can be set to a combination
of the following flags in very special circumstances:

@multitable @columnfractions .30 .65
@item @strong{Flag Name}       @tab @strong{Flag Nescription}
@item @code{CLIENT_COMPRESS}   @tab Use compression protocol.
@item @code{CLIENT_FOUND_ROWS} @tab Return the number of found (matched) rows, not the number of affected rows.
@item @code{CLIENT_IGNORE_SPACE} @tab Allow spaces after function names. Makes all functions names reserved words.
@item @code{CLIENT_INTERACTIVE} @tab Allow @code{interactive_timeout} seconds (instead of @code{wait_timeout} seconds) of inactivity before closing the connection. The client's session @code{wait_timeout} variable will be set to the value of the session @code{interactive_timeout} variable.
@item @code{CLIENT_LOCAL_FILES} @tab Enable @code{LOAD DATA LOCAL} handling.
@item @code{CLIENT_MULTI_STATEMENTS} @tab Tell the server that the client may send multiple-row-queries (separated by @samp{;}). If this flag is not set, multiple-row-queries are disabled. New in 4.1.
@item @code{CLIENT_MULTI_RESULTS} @tab Tell the server that the client can handle multiple-result sets from multi-queries or stored procedures.  This is automatically set if @code{CLIENT_MULTI_STATEMENTS} is set. New in 4.1.
@item @code{CLIENT_NO_SCHEMA}  @tab Don't allow the @var{db_name.tbl_name.col_name} syntax.  This is for ODBC. It causes the parser to generate an error if you use that syntax, which is useful for trapping bugs in some ODBC programs.
@item @code{CLIENT_ODBC}       @tab The client is an ODBC client. This changes @command{mysqld} to be more ODBC-friendly.
@item @code{CLIENT_SSL}         @tab Use SSL (encrypted protocol). This option should not be set by application programs; it is set internally in the client library.
@end multitable
@end itemize

@subsubheading Return Values

A @code{MYSQL*} connection handle if the connection was successful,
@code{NULL} if the connection was unsuccessful.  For a successful connection,
the return value is the same as the value of the first parameter.

@subsubheading Errors

@table @code
@item CR_CONN_HOST_ERROR
Failed to connect to the MySQL server.

@item CR_CONNECTION_ERROR
Failed to connect to the local MySQL server.

@item CR_IPSOCK_ERROR
Failed to create an IP socket.

@item CR_OUT_OF_MEMORY
Out of memory.

@item CR_SOCKET_CREATE_ERROR
Failed to create a Unix socket.

@item CR_UNKNOWN_HOST
Failed to find the IP address for the hostname.

@item CR_VERSION_ERROR
A protocol mismatch resulted from attempting to connect to a server with a
client library that uses a different protocol version.  This can happen if you
use a very old client library to connect to a new server that wasn't started
with the @code{--old-protocol} option.

@item CR_NAMEDPIPEOPEN_ERROR
Failed to create a named pipe on Windows.

@item CR_NAMEDPIPEWAIT_ERROR
Failed to wait for a named pipe on Windows.

@item CR_NAMEDPIPESETSTATE_ERROR
Failed to get a pipe handler on Windows.

@item CR_SERVER_LOST
If @code{connect_timeout} > 0 and it took longer than @code{connect_timeout}
seconds to connect to the server or if the server died while executing the
@code{init-command}.

@end table

@subsubheading Example

@example
MYSQL mysql;

mysql_init(&mysql);
mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name");
if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0))
@{
    fprintf(stderr, "Failed to connect to database: Error: %s\n",
          mysql_error(&mysql));
@}
@end example

By using @code{mysql_options()} the MySQL library will read the
@code{[client]} and @code{[your_prog_name]} sections in the @file{my.cnf}
file which will ensure that your program will work, even if someone has
set up MySQL in some non-standard way.

Note that upon connection, @code{mysql_real_connect()} sets the
@code{reconnect} flag (part of the @code{MYSQL} structure) to a value of
@code{1} in versions of the API strictly older than 5.0.3, of @code{0} in newer
versions. A value of @code{1} for this flag indicates, in the event that a
query cannot be performed because of a lost connection, to try reconnecting to
the server before giving up.


@node mysql_real_escape_string, mysql_real_query, mysql_real_connect, C API functions
@subsubsection @code{mysql_real_escape_string()}

@findex @code{mysql_real_escape_string()}

@code{unsigned long mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned long length)}

Note that @code{mysql} must be a valid, open connection. This is needed
because the escaping depends on the character-set in use by the server.

@subsubheading Description

This function is used to create a legal SQL string that you can use in a
SQL statement. @xref{String syntax}.

The string in @code{from} is encoded to an escaped SQL string, taking
into account the current character set of the connection. The result is placed
in @code{to} and a terminating null byte is appended.  Characters
encoded are @code{NUL} (ASCII 0), @samp{\n}, @samp{\r}, @samp{\},
@samp{'}, @samp{"}, and Control-Z (@pxref{Literals}).
(Strictly speaking, MySQL requires only that backslash and the quote
character used to quote the string in the query be escaped.  This function
quotes the other characters to make them easier to read in log files.)

The string pointed to by @code{from} must be @code{length} bytes long.  You
must allocate the @code{to} buffer to be at least @code{length*2+1} bytes
long.  (In the worst case, each character may need to be encoded as using two
bytes, and you need room for the terminating null byte.)  When
@code{mysql_real_escape_string()} returns, the contents of @code{to} will be a
null-terminated string.  The return value is the length of the encoded
string, not including the terminating null character.

@subsubheading Example

@example
char query[1000],*end;

end = strmov(query,"INSERT INTO test_table values(");
*end++ = '\'';
end += mysql_real_escape_string(&mysql, end,"What's this",11);
*end++ = '\'';
*end++ = ',';
*end++ = '\'';
end += mysql_real_escape_string(&mysql, end,"binary data: \0\r\n",16);
*end++ = '\'';
*end++ = ')';

if (mysql_real_query(&mysql,query,(unsigned int) (end - query)))
@{
   fprintf(stderr, "Failed to insert row, Error: %s\n",
           mysql_error(&mysql));
@}
@end example

The @code{strmov()} function used in the example is included in the
@code{mysqlclient} library and works like @code{strcpy()} but returns a
pointer to the terminating null of the first parameter.

@subsubheading Return Values

The length of the value placed into @code{to}, not including the
terminating null character.

@subsubheading Errors
None.


@node mysql_real_query, mysql_reload, mysql_real_escape_string, C API functions
@subsubsection @code{mysql_real_query()}

@findex @code{mysql_real_query()}

@code{int mysql_real_query(MYSQL *mysql, const char *query, unsigned long length)}

@subsubheading Description

Executes the SQL query pointed to by @code{query}, which should be a string
@code{length} bytes long.
Normally, the string must consist of a single SQL statement and you should
not add a terminating semicolon (@samp{;}) or @code{\g} to the statement.
If multiple-statement execution has been enabled, the string can contain
several statements separated by semicolons.
@xref{C API multiple queries}.

You @strong{must} use @code{mysql_real_query()} rather than
@code{mysql_query()} for queries that contain binary data, because binary data
may contain the @samp{\0} character.  In addition, @code{mysql_real_query()}
is faster than @code{mysql_query()} because it does not call @code{strlen()} on
the query string.

If you want to know whether the query should return a result set, you can
use @code{mysql_field_count()} to check for this.
@xref{mysql_field_count, @code{mysql_field_count()}}.

@subsubheading Return Values

Zero if the query was successful. Non-zero if an error occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table


@node mysql_reload, mysql_row_seek, mysql_real_query, C API functions
@subsubsection @code{mysql_reload()}

@findex @code{mysql_reload()}

@code{int mysql_reload(MYSQL *mysql)}

@subsubheading Description

Asks the MySQL server to reload the grant tables. The
connected user must have the @code{RELOAD} privilege.

This function is deprecated.  It is preferable to use @code{mysql_query()}
to issue an SQL @code{FLUSH PRIVILEGES} statement instead.

@subsubheading Return Values

Zero for success.  Non-zero if an error occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table


@node mysql_row_seek, mysql_row_tell, mysql_reload, C API functions
@subsubsection @code{mysql_row_seek()}

@findex @code{mysql_row_seek()}

@code{MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset)}

@subsubheading Description
Sets the row cursor to an arbitrary row in a query result set.
The @code{offset} value is a row offset that should be a value returned
from @code{mysql_row_tell()} or from @code{mysql_row_seek()}.
This value is not a row number; if you want to seek to a row within a
result set by number, use @code{mysql_data_seek()} instead.

This function requires that the result set structure contains the
entire result of the query, so @code{mysql_row_seek()} may be used
only in conjunction with @code{mysql_store_result()}, not with
@code{mysql_use_result()}.

@subsubheading Return Values

The previous value of the row cursor.  This value may be passed to a
subsequent call to @code{mysql_row_seek()}.

@subsubheading Errors
None.


@node mysql_row_tell, mysql_select_db, mysql_row_seek, C API functions
@subsubsection @code{mysql_row_tell()}

@findex @code{mysql_row_tell()}

@code{MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)}

@subsubheading Description

Returns the current position of the row cursor for the last
@code{mysql_fetch_row()}. This value can be used as an argument to
@code{mysql_row_seek()}.

You should use @code{mysql_row_tell()} only after @code{mysql_store_result()},
not after @code{mysql_use_result()}.

@subsubheading Return Values

The current offset of the row cursor.

@subsubheading Errors
None.

@node mysql_select_db, mysql_set_server_option, mysql_row_tell, C API functions
@subsubsection @code{mysql_select_db()}

@findex @code{mysql_select_db()}

@code{int mysql_select_db(MYSQL *mysql, const char *db)}

@subsubheading Description

Causes the database specified by @code{db} to become the default (current)
database on the connection specified by @code{mysql}.  In subsequent queries,
this database is the default for table references that do not include an
explicit database specifier.

@code{mysql_select_db()} fails unless the connected user can be authenticated
as having permission to use the database.

@subsubheading Return Values

Zero for success.  Non-zero if an error occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table

@node mysql_set_server_option, mysql_shutdown, mysql_select_db, C API functions
@subsubsection @code{mysql_set_server_option()}

@findex @code{mysql_set_sever_option()}

@code{int mysql_set_server_option(MYSQL *mysql, enum enum_mysql_set_option option)}

@subsubheading Description

Enables or disables an option for the connection. @code{option} can have one
of the following values:

@multitable @columnfractions .30 .65
@item MYSQL_OPTION_MULTI_STATEMENTS_ON @tab Enable multi statement support.
@item MYSQL_OPTION_MULTI_STATEMENTS_OFF @tab Disable multi statement support.
@end multitable

This function was added in MySQL 4.1.1.

@subsubheading Return Values

Zero for success.  Non-zero if an error occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item ER_UNKNOWN_COM_ERROR
The server didn't support @code{mysql_set_server_option()} (which is the
case that the server is older than 4.1.1) or the server didn't support
the option one tried to set.
@end table


@node mysql_shutdown, mysql_sqlstate, mysql_set_server_option, C API functions
@subsubsection @code{mysql_shutdown()}

@findex @code{mysql_shutdown()}

@code{int mysql_shutdown(MYSQL *mysql, enum enum_shutdown_level shutdown_level)}

@subsubheading Description

Asks the database server to shut down. The connected user must have
@code{SHUTDOWN} privileges.
The @code{shutdown_level} argument was added in MySQL 4.1.3 (and 5.0.1). The
MySQL server currently supports only one type (level of gracefulness) of
shutdown; @code{shutdown_level} must be equal to
@code{SHUTDOWN_DEFAULT}. Later we will add more levels and then the
@code{shutdown_level} argument will enable to choose the desired level.
MySQL servers and MySQL clients before and after 4.1.3 are compatible; MySQL
servers newer than 4.1.3 accept the @code{mysql_shutdown(MYSQL *mysql)} call,
and MySQL servers older than 4.1.3 accept the new @code{mysql_shutdown()}
call. But dynamically linked executables which have been compiled with older
versions of @code{libmysqlclient} headers, and call @code{mysql_shutdown()},
need to be used with the old @code{libmysqlclient} dynamic library.

The shutdown process is described in @ref{Server Shutdown}.

@subsubheading Return Values

Zero for success.  Non-zero if an error occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table

@node mysql_sqlstate, mysql_ssl_set, mysql_shutdown, C API functions
@subsubsection @code{mysql_sqlstate()}

@findex @code{mysql_sqlstate()}

@code{const char *mysql_sqlstate(MYSQL *mysql)}

@subsubheading Description

Returns a null-terminated string containing the SQLSTATE error code for the
last error.  The error code consists of five characters.
@code{'00000'} means ``no error.''
The values are specified by ANSI SQL and ODBC.
For a list of possible values, see @ref{Error-handling}.

Note that not all MySQL errors are yet mapped to SQLSTATE's.
The value @code{'HY000'} (general error) is used
for unmapped errors.

This function was added to MySQL 4.1.1.

@subsubheading Return Values

A null-terminated character string containing the SQLSTATE error code.

@subsubheading See Also

@xref{mysql_errno, , @code{mysql_errno()}}.
@xref{mysql_error, , @code{mysql_error()}}.
@xref{mysql_stmt_sqlstate, , @code{mysql_stmt_sqlstate()}}.


@node mysql_ssl_set, mysql_stat, mysql_sqlstate, C API functions
@subsubsection @code{mysql_ssl_set()}

@findex @code{mysql_ssl_set()}

@code{int mysql_ssl_set(MYSQL *mysql, const char *key,
                 const char *cert, const char *ca,
                 const char *capath, const char *cipher)}

@subsubheading Description

@code{mysql_ssl_set()} is used for establishing secure connections using
SSL. It must be called before @code{mysql_real_connect()}.

@code{mysql_ssl_set()} does nothing unless OpenSSL support is enabled in
the client library.

@code{mysql} is the connection handler returned from @code{mysql_init()}.
The other parameters are specified as follows:

@itemize @bullet
@item
@code{key} is the pathname to the key file.

@item
@code{cert} is the pathname to the certificate file.

@item
@code{ca} is the pathname to the certificate authority file.

@item
@code{capath} is the pathname to a directory that contains trusted 
SSL CA certificates in pem format.

@item
@code{cipher} is a list of allowable ciphers to use for SSL encryption.

@end itemize

Any unused SSL parameters may be given as @code{NULL}.

@subsubheading Return Values

This function always returns @code{0}. If SSL setup is incorrect,
@code{mysql_real_connect()} will return an error when you attempt to connect.

@node mysql_stat, mysql_store_result, mysql_ssl_set, C API functions
@subsubsection @code{mysql_stat()}

@findex @code{mysql_stat()}

@code{char *mysql_stat(MYSQL *mysql)}

@subsubheading Description

Returns a character string containing information similar to that provided by
the @command{mysqladmin status} command.  This includes uptime in seconds and
the number of running threads, questions, reloads, and open tables.

@subsubheading Return Values

A character string describing the server status. @code{NULL} if an
error occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table


@node mysql_store_result, mysql_thread_id, mysql_stat, C API functions
@subsubsection @code{mysql_store_result()}

@findex @code{mysql_store_result()}

@code{MYSQL_RES *mysql_store_result(MYSQL *mysql)}

@subsubheading Description

You must call @code{mysql_store_result()} or @code{mysql_use_result()}
for every query that successfully retrieves data (@code{SELECT},
@code{SHOW}, @code{DESCRIBE}, @code{EXPLAIN}, @code{CHECK TABLE}, and so forth).

You don't have to call @code{mysql_store_result()} or
@code{mysql_use_result()} for other queries, but it will not do any
harm or cause any notable performance if you call @code{mysql_store_result()}
in all cases.  You can detect if the query didn't have a result set by
checking if @code{mysql_store_result()} returns 0 (more about this later on).

If you want to know whether the query should return a result set, you can
use @code{mysql_field_count()} to check for this.
@xref{mysql_field_count, @code{mysql_field_count()}}.

@code{mysql_store_result()} reads the entire result of a query to the client,
allocates a @code{MYSQL_RES} structure, and places the result into this
structure.

@code{mysql_store_result()} returns a null pointer if the query didn't return
a result set (if the query was, for example, an @code{INSERT} statement).

@code{mysql_store_result()} also returns a null pointer if reading of the
result set failed. You can check whether an error occurred by checking if
@code{mysql_error()} returns a non-empty string, if
@code{mysql_errno()} returns non-zero, or if @code{mysql_field_count()}
returns zero.

An empty result set is returned if there are no rows returned.  (An empty
result set differs from a null pointer as a return value.)

Once you have called @code{mysql_store_result()} and got a result back
that isn't a null pointer, you may call @code{mysql_num_rows()} to find
out how many rows are in the result set.

You can call @code{mysql_fetch_row()} to fetch rows from the result set,
or @code{mysql_row_seek()} and @code{mysql_row_tell()} to obtain or
set the current row position within the result set.

You must call @code{mysql_free_result()} once you are done with the result
set.

@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}.

@subsubheading Return Values

A @code{MYSQL_RES} result structure with the results. @code{NULL} if
an error occurred.

@subsubheading Errors

@code{mysql_store_result()} resets @code{mysql_error()} and
@code{mysql_errno()} if it succeeds.

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_OUT_OF_MEMORY
Out of memory.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table


@node mysql_thread_id, mysql_use_result, mysql_store_result, C API functions
@subsubsection @code{mysql_thread_id()}

@findex @code{mysql_thread_id()}

@code{unsigned long mysql_thread_id(MYSQL *mysql)}

@subsubheading Description

Returns the thread ID of the current connection.  This value can be used as
an argument to @code{mysql_kill()} to kill the thread.

If the connection is lost and you reconnect with @code{mysql_ping()}, the
thread ID will change.  This means you should not get the thread ID and store
it for later. You should get it when you need it.

@subsubheading Return Values

The thread ID of the current connection.

@subsubheading Errors
None.


@node mysql_use_result, mysql_warning_count, mysql_thread_id, C API functions
@subsubsection @code{mysql_use_result()}

@findex @code{mysql_use_result()}

@code{MYSQL_RES *mysql_use_result(MYSQL *mysql)}

@subsubheading Description

You must call @code{mysql_store_result()} or @code{mysql_use_result()} for
every query that successfully retrieves data (@code{SELECT}, @code{SHOW},
@code{DESCRIBE}, @code{EXPLAIN}).

@code{mysql_use_result()} initiates a result set retrieval but does not
actually read the result set into the client like @code{mysql_store_result()}
does.  Instead, each row must be retrieved individually by making calls to
@code{mysql_fetch_row()}.  This reads the result of a query directly from the
server without storing it in a temporary table or local buffer, which is
somewhat faster and uses much less memory than @code{mysql_store_result()}.
The client will allocate memory only for the current row and a communication
buffer that may grow up to @code{max_allowed_packet} bytes.

On the other hand, you shouldn't use @code{mysql_use_result()} if you are
doing a lot of processing for each row on the client side, or if the output
is sent to a screen on which the user may type a @code{^S} (stop scroll).
This will tie up the server and prevent other threads from updating any
tables from which the data is being fetched.

When using @code{mysql_use_result()}, you must execute
@code{mysql_fetch_row()} until a @code{NULL} value is returned, otherwise, the
unfetched rows will be returned as part of the result set for your next
query. The C API will give the error @code{Commands out of sync; you can't
run this command now} if you forget to do this!

You may not use @code{mysql_data_seek()}, @code{mysql_row_seek()},
@code{mysql_row_tell()}, @code{mysql_num_rows()}, or
@code{mysql_affected_rows()} with a result returned from
@code{mysql_use_result()}, nor may you issue other queries until the
@code{mysql_use_result()} has finished.  (However, after you have fetched all
the rows, @code{mysql_num_rows()} will accurately return the number of rows
fetched.)

You must call @code{mysql_free_result()} once you are done with the result
set.

@subsubheading Return Values

A @code{MYSQL_RES} result structure. @code{NULL} if an error occurred.

@subsubheading Errors

@code{mysql_use_result()} resets @code{mysql_error()} and
@code{mysql_errno()} if it succeeds.

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_OUT_OF_MEMORY
Out of memory.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table


@node mysql_warning_count, mysql_commit, mysql_use_result, C API functions
@subsubsection @code{mysql_warning_count()}

@findex @code{mysql_warning_count()}.

@code{unsigned int mysql_warning_count(MYSQL *mysql)}

@subsubheading Description

Returns the number of warnings generated during execution of the previous
SQL statement.

This function was added in MySQL 4.1.0.

@subsubheading Return Values

The warning count.

@subsubheading Errors

None.


@node mysql_commit, mysql_rollback, mysql_warning_count, C API functions
@subsubsection @code{mysql_commit()}

@findex @code{mysql_commit()}.

@code{my_bool mysql_commit(MYSQL *mysql)}

@subsubheading Description

Commits the current transaction.

This function was added in MySQL 4.1.0.

@subsubheading Return Values

Zero if successful. Non-zero if an error occurred.

@subsubheading Errors

None.


@node mysql_rollback, mysql_autocommit, mysql_commit, C API functions
@subsubsection @code{mysql_rollback()}

@findex @code{mysql_rollback()}.

@code{my_bool mysql_rollback(MYSQL *mysql)}

@subsubheading Description

Rolls back the current transaction.

This function was added in MySQL 4.1.0.

@subsubheading Return Values

Zero if successful. Non-zero if an error occurred.

@subsubheading Errors

None.


@node mysql_autocommit, mysql_more_results, mysql_rollback, C API functions
@subsubsection @code{mysql_autocommit()}

@findex @code{mysql_autocommit()}.

@code{my_bool mysql_autocommit(MYSQL *mysql, my_bool mode)}

@subsubheading Description

Sets autocommit mode on if @code{mode} is 1, off if @code{mode} is 0.

This function was added in MySQL 4.1.0.

@subsubheading Return Values

Zero if successful. Non-zero if an error occurred.

@subsubheading Errors

None.


@node mysql_more_results, mysql_next_result, mysql_autocommit, C API functions
@subsubsection @code{mysql_more_results()}

@findex @code{mysql_more_results()}.

@code{my_bool mysql_more_results(MYSQL *mysql)}

@subsubheading Description

Returns true if more results exist from the currently executed query,
and the application must call @code{mysql_next_result()} to fetch the
results.

This function was added in MySQL 4.1.0.

@subsubheading Return Values

@code{TRUE} (1) if more results exist. @code{FALSE} (0) if no more results
exist.

In most cases, you can call @code{mysql_next_result()} instead to
test whether more results exist and initiate retrieval if so.

@xref{C API multiple queries}.
@xref{mysql_next_result}.

@subsubheading Errors

None.


@node mysql_next_result,  , mysql_more_results, C API functions
@subsubsection @code{mysql_next_result()}

@findex @code{mysql_next_result()}.

@code{int mysql_next_result(MYSQL *mysql)}

@subsubheading Description

If more query results exist, @code{mysql_next_result()} reads the
next query results and returns the status back to application.

You must call @code{mysql_free_result()} for the preceding
query if it returned a result set.

After calling @code{mysql_next_result()} the state of the connection
is as if you had called @code{mysql_real_query()} or @code{mysql_query()}
for the next query.
This means that you can now call @code{mysql_store_result()},
@code{mysql_warning_count()}, @code{mysql_affected_rows()}, and so forth.

If @code{mysql_next_result()} returns an error, no other statements will
be executed and there are no more results to fetch.

@xref{C API multiple queries}.

This function was added in MySQL 4.1.0.

@subsubheading Return Values

@multitable @columnfractions .30 .65
@item @strong{Return Value}         @tab @strong{Description}
@item 0  @tab Successful and there are more results
@item @minus{}1 @tab Successful and there are no more results
@item >0 @tab An error occurred
@end multitable

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order. For example if you didn't call
@code{mysql_use_result()} for a previous result set.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table


@node C API Prepared statements, C API Prepared statement datatypes, C API functions, C
@subsection C API Prepared Statements

As of MySQL 4.1, the client/server protocol provides for the use of
prepared statements. This capability uses the
@code{MYSQL_STMT} statement handler data structure returned by the
@code{mysql_stmt_init()} initialization function.
Prepared execution is an efficient way to execute a statement more than
once. The statement is first parsed to prepare it for execution. Then
it is executed one or more times at a later time, using the statement
handle returned by the initialization function.

Prepared execution is faster than direct execution for statements
executed more than once, primarly because the query is parsed only
once. In the case of direct execution, the query is parsed every
time it is executed. Prepared execution also can provide a reduction of network
traffic because for each execution of the prepared statement,
it is necessary only to send the data for the parameters.

Another advantage of prepared statements is that it uses a binary protocol
that makes data transfer between client and server more efficient.

The following statements can be used as prepared statements:
@code{CREATE TABLE},
@code{DELETE},
@code{DO},
@code{INSERT},
@code{REPLACE},
@code{SELECT},
@code{SET},
@code{UPDATE},
and most
@code{SHOW},
statements.
Other statements are not yet supported.


@node C API Prepared statement datatypes, C API Prepared statement function overview, C API Prepared statements, C
@subsection C API Prepared Statement Data types

@strong{Note}:
Some incompatible changes were made in MySQL 4.1.2.
See @ref{C API Prepared statement functions} for details.

Prepared statements mainly use the @code{MYSQL_STMT} and
@code{MYSQL_BIND} data structures. A third structure, @code{MYSQL_TIME},
is used to transfer temporal data.

@table @code

@item MYSQL_STMT
@tindex MYSQL_STMT C type
This structure represents a prepared statement.
A statement is created by calling @code{mysql_stmt_init()},
which returns a statement handle, that is, a pointer to a
@code{MYSQL_STMT}.
The handle is used for all subsequent statement-related functions until you
close it with @code{mysql_stmt_close()}.

The @code{MYSQL_STMT} structure has no members that are for application
use.

Multiple statement handles can be associated with a single connection.
The limit on the number of handles depends on the available system resources.

@item MYSQL_BIND
@tindex MYSQL_BIND C type
This structure is used both for statement input (data values sent to the server)
and output (result values returned from the server). For input, it is used with
@code{mysql_stmt_bind_param()} to bind parameter data values to
buffers for use by @code{mysql_stmt_execute()}. For output, it is
used with @code{mysql_stmt_bind_result()} to bind result set
buffers for use in fetching rows with @code{mysql_stmt_fetch()}.

@noindent
The @code{MYSQL_BIND} structure contains the following members for
use by application programs.
Each is used both for input and for output, although sometimes for different
purposes depending on the direction of data transfer.

@table @code
@item enum enum_field_types buffer_type
The type of the buffer. The allowable @code{buffer_type} values are listed
later in this section. For input, @code{buffer_type} indicates what type of
value you are binding to a statement parameter. For output, it indicates what
type of value you expect to receive in a result buffer.

@item void *buffer
For input, this is a pointer to the buffer in which a statement parameter's data
value is stored. For output, it is
a pointer to the buffer in which to return a result set column value.
For numeric column types, @code{buffer} should point to a variable of the proper
C type.  (If you are associating the variable with a column that has the
@code{UNSIGNED} attribute, the variable should be an @code{unsigned} C type.
Indicate whether the variable is signed or unsigned by using the
@code{is_unsigned} member, described later in this list.)
For date and time column types, @code{buffer} should point to a
@code{MYSQL_TIME} structure.  For character and binary string column types,
@code{buffer} should point to a character buffer.

@item unsigned long buffer_length
The actual size of @code{*buffer} in bytes. This indicates the maximum amount
of data that can be stored in the buffer. For character and binary C data,
the @code{buffer_length} value specifies the length of @code{*buffer}
when used with @code{mysql_stmt_bind_param()},
or the maximum number of data bytes that can be fetched into the buffer
when used with @code{mysql_stmt_bind_result()}.

@item unsigned long *length
A pointer to an @code{unsigned long} variable that indicates the actual number
of bytes of data stored in @code{*buffer}.
@code{length} is used for character or binary C data.
For input parameter data binding, @code{length}
points to an @code{unsigned long} variable that indicates the
length of the parameter value stored in @code{*buffer}; this is used by
@code{mysql_stmt_execute()}.
@c commented out next two lines; apparently they're not true
@c If @code{length} is a null pointer, the protocol assumes
@c that all character and binary data are null-terminated.
For output value binding, @code{mysql_stmt_fetch()} places
the length of the column value that is returned
into the variable that @code{length} points to.

@code{length}
is ignored for numeric and temporal data types because the length
of the data value is determined by the @code{buffer_type} value.

@item my_bool *is_null
This member points to a @code{my_bool} variable that is true if a value is
@code{NULL}, false if it is not @code{NULL}. For input, set @code{*is_null}
to true to
indicate that you are passing a @code{NULL} value as a statement parameter. For
output, this value will be set to true after you fetch a row if the result
set column value returned from the statement is @code{NULL}.

@item my_bool is_unsigned
This member is used for integer types.
(These correspond to the @code{MYSQL_TYPE_TINY}, @code{MYSQL_TYPE_SHORT},
@code{MYSQL_TYPE_LONG}, and @code{MYSQL_TYPE_LONGLONG} type codes.)
@code{is_unsigned}
should be set to true for unsigned types and false for signed types.
@end table

To use a @code{MYSQL_BIND} structure, you should zero its contents
to initialize it, and then set the members just described appropriately.
For example, to declare and initialize an array of three @code{MYSQL_BIND}
structures, use this code:

@example
MYSQL_BIND    bind[3];
memset(bind, 0, sizeof(bind));
@end example

@item MYSQL_TIME
@tindex MySQL C type
This structure is used to send and receive @code{DATE}, @code{TIME},
@code{DATETIME}, and @code{TIMESTAMP} data directly to and from the server.
This is done by setting the @code{buffer_type} member of a @code{MYSQL_BIND}
structure to one of the temporal types, and setting the @code{buffer} member
to point to a @code{MYSQL_TIME} structure.

@noindent
The @code{MYSQL_TIME} structure contains the following members:

@c TODO: rather than say TIME for the hour item (which doesn't make much
@c sense; don't minute/second apply, too), say for each temporal type
@c which structure members are used for it.

@table @code

@item unsigned int year
The year.

@item unsigned int month
The month of the year.

@item unsigned int day
The day of the month.

@item unsigned int hour
The hour of the day.

@item unsigned int minute
The minute of the hour.

@item unsigned int second
The second of the minute.

@item my_bool neg
A boolean flag to indicate whether the time is negative.

@c TODO: not quite true that it's unused; we need a good characterization
@c of when it's allowable/available.

@item unsigned long second_part
The fractional part of the second.
This member currently is unused.

@end table

@c TODO: does neg only to TIME/TIMESTAMP?
@c TODO: second_part probably applies only to TIMESTAMP?

Only those parts of a @code{MYSQL_TIME} structure that apply to a given
type of temporal value are used:
The @code{year}, @code{month}, and @code{day} elements are used for
@code{DATE}, @code{DATETIME}, and @code{TIMESTAMP} values.
The @code{hour}, @code{minute}, and @code{second} elements are used for
@code{TIME}, @code{DATETIME}, and @code{TIMESTAMP} values.
@xref{C API date handling}.

@end table

The following table shows the allowable values that may be specified in the
@code{buffer_type} member of @code{MYSQL_BIND} structures.
The table also shows those SQL types that correspond most closely to each
@code{buffer_type} value, and, for numeric and temporal types, the
corresponding C type.

@multitable @columnfractions .33 .33 .33
@item @code{buffer_type} @strong{Value} @tab @strong{SQL Type} @tab @strong{C Type}
@item @code{MYSQL_TYPE_TINY} @tab @code{TINYINT} @tab @code{char}
@item @code{MYSQL_TYPE_SHORT} @tab @code{SMALLINT} @tab @code{short int}
@item @code{MYSQL_TYPE_LONG}   @tab @code{INT} @tab @code{int}
@item @code{MYSQL_TYPE_LONGLONG} @tab @code{BIGINT} @tab @code{long long int}
@item @code{MYSQL_TYPE_FLOAT} @tab @code{FLOAT} @tab @code{float}
@item @code{MYSQL_TYPE_DOUBLE} @tab @code{DOUBLE} @tab @code{double}
@item @code{MYSQL_TYPE_TIME} @tab @code{TIME} @tab @code{MYSQL_TIME}
@item @code{MYSQL_TYPE_DATE} @tab @code{DATE} @tab @code{MYSQL_TIME}
@item @code{MYSQL_TYPE_DATETIME} @tab @code{DATETIME} @tab @code{MYSQL_TIME}
@item @code{MYSQL_TYPE_TIMESTAMP} @tab @code{TIMESTAMP} @tab @code{MYSQL_TIME}
@item @code{MYSQL_TYPE_STRING} @tab @code{CHAR} @tab
@item @code{MYSQL_TYPE_VAR_STRING} @tab @code{VARCHAR} @tab
@item @code{MYSQL_TYPE_TINY_BLOB} @tab @code{TINYBLOB/TINYTEXT} @tab
@item @code{MYSQL_TYPE_BLOB} @tab @code{BLOB/TEXT} @tab
@item @code{MYSQL_TYPE_MEDIUM_BLOB} @tab @code{MEDIUMBLOB/MEDIUMTEXT} @tab
@item @code{MYSQL_TYPE_LONG_BLOB} @tab @code{LONGBLOB/LONGTEXT} @tab
@end multitable

Implicit type conversion may be performed in both directions.

@c TODO: Explain what that means and give some examples. Need list of
@c allowable/supported conversions


@node C API Prepared statement function overview, C API Prepared statement functions, C API Prepared statement datatypes, C
@subsection C API Prepared Statement Function Overview

@cindex C Prepared statement API, functions
@cindex functions, C Prepared statement API

@strong{Note}:
Some incompatible changes were made in MySQL 4.1.2.
See @ref{C API Prepared statement functions} for details.


The functions available for prepared statement processing are summarized here and
described in greater detail in a later section.
@xref{C API Prepared statement functions}.

@c TODO: missing functions here (that are listed in mysql.h)
@c mysql_stmt_param_metadata() 4.1.2 [not implemented yet?]

@multitable @columnfractions .32 .68
@item @strong{Function} @tab @strong{Description}

@item @strong{mysql_stmt_affected_rows()} @tab
Returns the number of rows changes, deleted, or inserted by prepared
@code{UPDATE}, @code{DELETE}, or @code{INSERT} statement.

@item @strong{mysql_stmt_attr_get()} @tab
Get value of an attribute for a prepared statement.

@item @strong{mysql_stmt_attr_set()} @tab
Sets an attribute for a prepared statement.

@item @strong{mysql_stmt_bind_param()} @tab
Associates application data buffers with the parameter markers in a prepared
SQL statement.

@item @strong{mysql_stmt_bind_result()} @tab
Associates application data buffers with columns in the result set.

@item @strong{mysql_stmt_close()} @tab
Frees memory used by prepared statement.

@item @strong{mysql_stmt_data_seek()} @tab
Seeks to an arbitrary row number in a statement result set.

@item @strong{mysql_stmt_errno()} @tab
Returns the error number for the last statement execution.

@item @strong{mysql_stmt_error()} @tab
Returns the error message for the last statement execution.

@item @strong{mysql_stmt_execute()} @tab
Executes the prepared statement.

@item @strong{mysql_stmt_fetch()} @tab
Fetches the next row of data from the result set and returns data for all bound columns.

@item @strong{mysql_stmt_fetch_column()} @tab
Fetch data for one column of the current row of the result set.

@item @strong{mysql_stmt_field_count()} @tab
Returns the number of result columns for the most recent statement.

@item @strong{mysql_stmt_free_result()} @tab
Free the resources allocated to the statement handle.

@item @strong{mysql_stmt_init()} @tab
Allocates memory for @code{MYSQL_STMT} structure and initializes it.

@item @strong{mysql_stmt_insert_id()} @tab
Returns the ID generated for an @code{AUTO_INCREMENT} column by prepared
statement.

@item @strong{mysql_stmt_num_rows()} @tab
Returns total rows from the statement buffered result set.

@item @strong{mysql_stmt_param_count()} @tab
Returns the number of parameters in a prepared SQL statement.

@c 2004-03-03: mysql_stmt_param_metadata is not implemented yet,
@c only stub is present in the library
@item @strong{mysql_stmt_param_metadata()} @tab
Return parameter metadata in the form of a result set.

@item @strong{mysql_stmt_prepare()} @tab
Prepares an SQL string for execution.

@c TODO: this description is not helpful.
@item @strong{mysql_stmt_reset()} @tab
Reset the statement buffers in the server.

@item @strong{mysql_stmt_result_metadata()} @tab
Returns prepared statement metadata in the form of a result set.

@item @strong{mysql_stmt_row_seek()} @tab
Seeks to a row offset in a statement result set, using value returned from
@code{mysql_stmt_row_tell()}.

@item @strong{mysql_stmt_row_tell()} @tab
Returns the statement row cursor position.

@item @strong{mysql_stmt_send_long_data()} @tab
Sends long data in chunks to server.

@item @strong{mysql_stmt_sqlstate()} @tab
Returns the SQLSTATE error code for the last statement execution.

@item @strong{mysql_stmt_store_result()} @tab
Retrieves the complete result set to the client.

@end multitable

Call @code{mysql_stmt_init()} to create a statement
handle, then @code{mysql_stmt_prepare} to prepare it, 
@code{mysql_stmt_bind_param()} to supply the parameter
data, and @code{mysql_stmt_execute()} to execute the statement. You can
repeat the @code{mysql_stmt_execute()} by changing parameter values in the
respective buffers supplied through @code{mysql_stmt_bind_param()}.

If the statement is a @code{SELECT} or any other statement that produces
a result set, @code{mysql_stmt_prepare()} will also return the result
set metadata information in the form of a @code{MYSQL_RES} result set 
through @code{mysql_stmt_result_metadata()}.

You can supply the result buffers using @code{mysql_stmt_bind_result()}, so
that the @code{mysql_stmt_fetch()} will automatically return data to these
buffers. This is row-by-row fetching.

You can also send the text or binary data in chunks to server using
@code{mysql_stmt_send_long_data()}.
@xref{mysql_stmt_send_long_data,  , @code{mysql_stmt_long_data()}}.

When statement execution has been completed, the statement handle must be
closed using @code{mysql_stmt_close()} so that all resources associated
with it can be freed.

If you obtained a @code{SELECT} statement's result set metadata by calling
@code{mysql_stmt_result_metadata()}, you should also free the metadata using
@code{mysql_free_result()}.

@subsubheading Execution Steps

To prepare and execute a statement, an application follows these steps:

@enumerate
@item
Create a prepared statement handle with @code{msyql_stmt_init()}.
To prepare the statement on the server, call @code{mysql_stmt_prepare()} and
pass it a string containing the SQL statement.
@item
If the statement produces a result set, call @code{mysql_stmt_result_metadata()}
to obtain the result set metadata.  This metadata is itself in the form of
result set, albeit a separate one from the one that contains the rows returned
by the query. The metadata result set indicates how many columns are in the
result and contains information about each column.
@item
Set the values of any parameters using @code{mysql_stmt_bind_param()}. All
parameters must be set. Otherwise, statement execution will return an error or
produce unexpected results.
@item
Call @code{mysql_stmt_execute()} to execute the statement.
@item
If the statement produces a result set,
bind the data buffers to use for retrieving the row values by calling
@code{mysql_stmt_bind_result()}.
@item
Fetch the data into the buffers row by row by calling
@code{mysql_stmt_fetch()} repeatedly until no more rows are found.
@item
Repeat steps 3 through 6 as necessary, by changing the parameter values and
re-executing the statement.

@end enumerate

When @code{mysql_stmt_prepare()} is called, the MySQL client/server protocol
performs these actions:

@itemize @bullet
@item
The server parses the statement and sends the okay status back to the client by
assigning a statement ID. It also sends total number of parameters,
a column count, and its metadata if it is a result set oriented
statement. All syntax and semantics of the statement are checked by the server
during this call.
@item
The client uses this statement ID for the further operations, so that the server
can identify the statement from among its pool of statements.
@end itemize

When @code{mysql_stmt_execute()} is called, the MySQL
client/server protocol performs these actions:

@itemize @bullet
@item
The client uses the statement handle and sends the parameter data to the
server.
@item
The server identifies the statement using the ID provided by the client,
replaces the parameter markers with the newly supplied data, and executes
the statement. If the statement produces a result set, the server sends
the data back to the client. Otherwise, it sends an okay status and total
number of rows changed, deleted, or inserted.
@end itemize

When @code{mysql_stmt_fetch()} is called, the MySQL client/server protocol
performs these actions:

@itemize @bullet
@item
The client reads the data from the packet row by row and places it into the
application data buffers by doing the necessary conversions. If the
application buffer type is same as that of the field type returned from the
server, the conversions are straightforward.
@end itemize

If an error occurs,
you can get the statement error code, error message, and SQLSTATE value using
@code{mysql_stmt_errno()}, @code{mysql_stmt_error()}, and
@code{mysql_stmt_sqlstate()}, respectively.


@node C API Prepared statement functions, C API Prepared statement problems, C API Prepared statement function overview, C
@subsection C API Prepared Statement Function Descriptions

To prepare and execute queries, use the functions in the following sections.

In MySQL 4.1.2, the names of several prepared statement functions were
changed:

@multitable @columnfractions .30 .70
@item @strong{Old Name}           @tab @strong{New Name}
@item @code{mysql_bind_param()}     @tab @code{mysql_stmt_bind_param()}
@item @code{mysql_bind_result()}    @tab @code{mysql_stmt_bind_result()}
@item @code{mysql_prepare()}        @tab @code{mysql_stmt_prepare()}
@item @code{mysql_execute()}        @tab @code{mysql_stmt_execute()}
@item @code{mysql_fetch()}          @tab @code{mysql_stmt_fetch()}
@item @code{mysql_fetch_column()}   @tab @code{mysql_stmt_fetch_column()}
@item @code{mysql_param_count()}    @tab @code{mysql_stmt_param_count()}
@item @code{mysql_param_result()} @tab @code{mysql_stmt_param_metadata()}
@item @code{mysql_get_metadata()} @tab @code{mysql_stmt_result_metadata()}
@item @code{mysql_send_long_data()} @tab @code{mysql_stmt_send_long_data()}
@end multitable

All functions that operate with a @code{MYSQL_STMT} structure now begin with
the prefix @code{mysql_stmt_}.

Also in 4.1.2, the signature of the @code{mysql_stmt_prepare()} function was
changed to @code{int mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query,
unsigned long length)}.  To create a @code{MYSQL_STMT} handle, you should
use the @code{mysql_stmt_init()} function.

@menu
* mysql_stmt_affected_rows::    @code{mysql_stmt_affected_rows()}
* mysql_stmt_attr_get::         @code{mysql_stmt_attr_get()}
* mysql_stmt_attr_set::         @code{mysql_stmt_attr_set()}
* mysql_stmt_bind_param::       @code{mysql_stmt_bind_param()}
* mysql_stmt_bind_result::      @code{mysql_stmt_bind_result()}
* mysql_stmt_close::            @code{mysql_stmt_close()}
* mysql_stmt_data_seek::        @code{mysql_stmt_data_seek()}
* mysql_stmt_errno::            @code{mysql_stmt_errno()}
* mysql_stmt_error::            @code{mysql_stmt_error()}
* mysql_stmt_execute::          @code{mysql_stmt_execute()}
* mysql_stmt_free_result::      @code{mysql_stmt_free_result()}
* mysql_stmt_insert_id::        @code{mysql_stmt_insert_id()}
* mysql_stmt_fetch::            @code{mysql_stmt_fetch()}
* mysql_stmt_fetch_column::     @code{mysql_stmt_fetch_column()}
* mysql_stmt_field_count::      @code{mysql_stmt_field_count()}
* mysql_stmt_init::             @code{mysql_stmt_init()}
* mysql_stmt_num_rows::         @code{mysql_stmt_num_rows()}
* mysql_stmt_param_count::      @code{mysql_stmt_param_count()}
* mysql_stmt_param_metadata::   @code{mysql_stmt_param_metadata()}
* mysql_stmt_prepare::          @code{mysql_stmt_prepare()}
* mysql_stmt_reset::            @code{mysql_stmt_reset()}
* mysql_stmt_result_metadata::  @code{mysql_stmt_result_metadata()}
* mysql_stmt_row_seek::         @code{mysql_stmt_row_seek()}
* mysql_stmt_row_tell::         @code{mysql_stmt_row_tell()}
* mysql_stmt_send_long_data::   @code{mysql_stmt_send_long_data()}
* mysql_stmt_sqlstate::         @code{mysql_stmt_sqlstate()}
* mysql_stmt_store_result::     @code{mysql_stmt_store_result()}
@end menu


@node mysql_stmt_affected_rows, mysql_stmt_attr_get, C API Prepared statement functions, C API Prepared statement functions
@subsubsection @code{mysql_stmt_affected_rows()}

@findex @code{mysql_stmt_affected_rows()}

@code{my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT *stmt)}

@subsubheading Description

Returns the total number of rows changed, deleted, or inserted by the last
executed statement. May be called immediately after @code{mysql_stmt_execute()}
for @code{UPDATE}, @code{DELETE}, or @code{INSERT} statements. For
@code{SELECT} statements, @code{mysql_stmt_affected_rows()} works like
@code{mysql_num_rows()}.

@c TODO: For SELECT, are there any caveats on when you must wait to call
@c this function, such as after all the rows have been fetched or after
@c calling mysql_stmt_store_result()?

This function was added in MySQL 4.1.0.

@subsubheading Return Values

An integer greater than zero indicates the number of rows affected
or retrieved. Zero indicates that no records were updated for an
@code{UPDATE} statement, no rows matched the @code{WHERE} clause in
the query, or that no query has yet been executed. @minus{}1 indicates that
the query returned an error or that, for a @code{SELECT} query,
@code{mysql_stmt_affected_rows()} was called prior to calling
@code{mysql_stmt_store_result()}.
Because @code{mysql_stmt_affected_rows()}
returns an unsigned value, you can check for @minus{}1 by comparing the
return value to @code{(my_ulonglong)-1} (or to @code{(my_ulonglong)~0},
which is equivalent).

See @ref{mysql_affected_rows,  , @code{mysql_affected_rows()}} for additional
information on the return value.

@subsubheading Errors

None.

@subsubheading Example

For the usage of @code{mysql_stmt_affected_rows()}, refer to the Example
from @ref{mysql_stmt_execute, , @code{mysql_stmt_execute()}}.


@node mysql_stmt_attr_get, mysql_stmt_attr_set, mysql_stmt_affected_rows, C API Prepared statement functions
@subsubsection @code{mysql_stmt_attr_get()}

@findex @code{mysql_stmt_attr_get()}

@code{int mysql_stmt_attr_get(MYSQL_STMT *stmt, enum enum_stmt_attr_type option, void *arg)}

@subsubheading Description

Can be used to get the current value for a statement attribute.

The @code{option} argument is the option that you want to get; the
@code{arg} should point to a variable that should contain the option
value. If the option is an integer, then @code{arg} should point to the
value of the integer.

See @code{mysql_stmt_attr_set()} for a list of options and option
types. @xref{mysql_stmt_attr_set,  , @code{mysql_stmt_attr_set()}}.

This function was added in MySQL 4.1.2.

@subsubheading Return Values

@code{0} if okay.  Non-zero if @code{option} is unknown.

@subsubheading Errors

None.


@node mysql_stmt_attr_set, mysql_stmt_bind_param, mysql_stmt_attr_get, C API Prepared statement functions
@subsubsection @code{mysql_stmt_attr_set()}

@findex @code{mysql_stmt_attr_set()}

@code{int mysql_stmt_attr_set(MYSQL_STMT *stmt, enum enum_stmt_attr_type option, const void *arg)}

@subsubheading Description

Can be used to set affect behavior for a statement.
This function may be called multiple times to set several options.

The @code{option} argument is the option that you want to set; the @code{arg}
argument is the value for the option. If the option is an integer, then
@code{arg} should point to the value of the integer.

Possible options values:

@multitable @columnfractions .42 .20 .38
@item @strong{Option} @tab @strong{Argument Type} @tab @strong{Function}
@item @code{STMT_ATTR_UPDATE_MAX_LENGTH} @tab @code{my_bool *} @tab If set to 1: Update metadata @code{MYSQL_FIELD->max_length} in @code{mysql_stmt_store_result()}.
@end multitable

This function was added in MySQL 4.1.2.

@subsubheading Return Values

@code{0} if okay.  Non-zero if @code{option} is unknown.

@subsubheading Errors

None.


@node mysql_stmt_bind_param, mysql_stmt_bind_result, mysql_stmt_attr_set, C API Prepared statement functions
@subsubsection @code{mysql_stmt_bind_param()}

@findex @code{mysql_stmt_bind_param()}

@code{my_bool mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *bind)}

@subsubheading Description

@code{mysql_stmt_bind_param()} is used to bind data for the parameter markers
in the SQL statement that was passed to @code{mysql_stmt_prepare()}. It uses
@code{MYSQL_BIND} structures to supply the data. @code{bind} is the address
of an array of @code{MYSQL_BIND} structures.
The client library expects the array to contain an element for each
@samp{?} parameter marker that is present in the query.

Suppose that you prepare the following statement:

@example
INSERT INTO mytbl VALUES(?,?,?)
@end example

When you bind the parameters, the array of @code{MYSQL_BIND} structures must
contain three elements, and can be declared like this:

@example
MYSQL_BIND bind[3];
@end example

The members of each @code{MYSQL_BIND} element that should be set are described
in @ref{C API Prepared statement datatypes}.

This function was added in MySQL 4.1.2.

@subsubheading Return Values

Zero if the bind was successful. Non-zero if an error occurred.

@subsubheading Errors
@table @code
@item CR_INVALID_BUFFER_USE
Indicates if the bind is to supply the long data in chunks and if the
buffer type is non string or binary.
@item CR_UNSUPPORTED_PARAM_TYPE
The conversion is not supported. Possibly the @code{buffer_type} value is
illegal or is not one of the supported types.
@item CR_OUT_OF_MEMORY
Out of memory.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table

@subsubheading Example

For the usage of @code{mysql_stmt_bind_param()}, refer to the Example from
@ref{mysql_stmt_execute, , @code{mysql_stmt_execute()}}.


@node mysql_stmt_bind_result, mysql_stmt_close, mysql_stmt_bind_param, C API Prepared statement functions
@subsubsection @code{mysql_stmt_bind_result()}

@findex @code{mysql_stmt_bind_result()}

@code{my_bool mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)}

@subsubheading Description

@code{mysql_stmt_bind_result()} is used to associate (bind) columns in the
result set to data buffers and length buffers. When
@code{mysql_stmt_fetch()} is
called to fetch data, the MySQL client/server protocol places the data for the
bound columns into the specified buffers.

All columns must be bound to buffers prior to calling
@code{mysql_stmt_fetch()}.
@code{bind} is the address of an array of @code{MYSQL_BIND} structures.
The client library expects the array to contain
an element for each column of the result set.
If you do not bind columns to @code{MYSQL_BIND} structures,
@code{mysql_stmt_fetch()} simply ignores
the data fetch. The buffers should be large enough to hold the
data values, because the protocol doesn't return data values in chunks.

A column can be bound or rebound at any time, even after a result set has been
partially retrieved.  The new binding takes effect the next time
@code{mysql_stmt_fetch()} is called. Suppose that an application binds
the columns in a result set and calls @code{mysql_stmt_fetch()}.
The client/server
protocol returns data in the bound buffers. Then suppose the application
binds the columns to a different set of buffers. The protocol does
not place data into the newly bound
buffers until the next call to @code{mysql_stmt_fetch()} occurs.

To bind a column, an application calls @code{mysql_stmt_bind_result()} and
passes the type, address, and the address of the length buffer.
The members of each @code{MYSQL_BIND} element that should be set are described
in @ref{C API Prepared statement datatypes}.

This function was added in MySQL 4.1.2.

@subsubheading Return Values

Zero if the bind was successful. Non-zero if an error occurred.

@subsubheading Errors

@table @code
@item CR_UNSUPPORTED_PARAM_TYPE
The conversion is not supported. Possibly the @code{buffer_type} value is
illegal or is not one of the supported types.
@item CR_OUT_OF_MEMORY
Out of memory.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table

@subsubheading Example

For the usage of @code{mysql_stmt_bind_result()}, refer to the Example from
@ref{mysql_stmt_fetch, , @code{mysql_stmt_fetch()}}.


@node mysql_stmt_close, mysql_stmt_data_seek, mysql_stmt_bind_result, C API Prepared statement functions
@subsubsection @code{mysql_stmt_close()}

@findex @code{mysql_stmt_close()}

@code{my_bool mysql_stmt_close(MYSQL_STMT *)}

@subsubheading Description

Closes the prepared statement. @code{mysql_stmt_close()} also
deallocates the statement handle pointed to by @code{stmt}. 

If the current statement has pending or unread results, this function
cancels them so that the next query can be executed.

This function was added in MySQL 4.1.0.

@subsubheading Return Values

Zero if the statement was freed successfully. Non-zero if an error occurred.

@subsubheading Errors

@table @code
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table

@subsubheading Example

For the usage of @code{mysql_stmt_close()}, refer to the Example from
@ref{mysql_stmt_execute, , @code{mysql_stmt_execute()}}.


@node mysql_stmt_data_seek, mysql_stmt_errno, mysql_stmt_close, C API Prepared statement functions
@subsubsection @code{mysql_stmt_data_seek()}

@findex @code{mysql_stmt_data_seek()}

@code{void mysql_stmt_data_seek(MYSQL_STMT *stmt, my_ulonglong offset)}

@subsubheading Description
Seeks to an arbitrary row in a statement result set.  The @code{offset}
value is a row number and should be in the range from @code{0} to
@code{mysql_stmt_num_rows(stmt)-1}.

This function requires that the statement result set structure
contains the entire result of the last executed query, so
@code{mysql_stmt_data_seek()} may be used only in conjunction with
@code{mysql_stmt_store_result()}.

This function was added in MySQL 4.1.1.


@subsubheading Return Values

None.

@subsubheading Errors
None.


@node mysql_stmt_errno, mysql_stmt_error, mysql_stmt_data_seek, C API Prepared statement functions
@subsubsection @code{mysql_stmt_errno()}

@findex @code{mysql_stmt_errno()}

@code{unsigned int mysql_stmt_errno(MYSQL_STMT *stmt)}

@subsubheading Description

For the statement specified by @code{stmt}, @code{mysql_stmt_errno()}
returns the error code for the most recently invoked statement API
function that can succeed or fail. A return value of zero means that no
error occurred.  Client error
message numbers are listed in the MySQL @file{errmsg.h} header file.
Server error message numbers are listed in @file{mysqld_error.h}. In the
MySQL source distribution you can find a complete list of
error messages and error numbers in the file @file{Docs/mysqld_error.txt}.
The server error codes also are listed at @ref{Error-handling}.

This function was added in MySQL 4.1.0.

@subsubheading Return Values

An error code value. Zero if no error occurred.

@subsubheading Errors

None.


@node mysql_stmt_error, mysql_stmt_execute, mysql_stmt_errno, C API Prepared statement functions
@subsubsection @code{mysql_stmt_error()}

@findex @code{mysql_stmt_error()}.

@code{const char *mysql_stmt_error(MYSQL_STMT *stmt)}

@subsubheading Description

For the statement specified by @code{stmt}, @code{mysql_stmt_error()}
returns a null-terminated string containing the error message for the most recently invoked statement API
function that can succeed or fail. An empty string (@code{""}) is returned
if no error occurred. This means the following two tests are equivalent:

@example

if (mysql_stmt_errno(stmt))
@{
  // an error occurred
@}

if (mysql_stmt_error(stmt)[0])
@{
  // an error occurred
@}
@end example

The language of the client error messages may be changed by recompiling
the MySQL client library. Currently you can choose error messages in
several different languages.

This function was added in MySQL 4.1.0.

@subsubheading Return Values

A character string that describes the error. An empty string if no error
occurred.

@subsubheading Errors

None.


@node mysql_stmt_execute, mysql_stmt_free_result, mysql_stmt_error, C API Prepared statement functions
@subsubsection @code{mysql_stmt_execute()}

@findex @code{mysql_stmt_execute()}

@code{int mysql_stmt_execute(MYSQL_STMT *stmt)}

@subsubheading Description

@code{mysql_stmt_execute()} executes the prepared query associated with the
statement handle. The currently bound parameter marker values are sent
to server during this call, and the server replaces the markers with this newly
supplied data.

@c TODO: what about REPLACE?

If the statement is an @code{UPDATE}, @code{DELETE}, or @code{INSERT},
the total number of
changed, deleted, or inserted rows can be found by calling
@code{mysql_stmt_affected_rows()}. If this is a result set query such as
@code{SELECT}, you
must call @code{mysql_stmt_fetch()} to fetch the data prior to calling any
other functions that result in query processing. For more information on
how to fetch the results, refer to
@ref{mysql_stmt_fetch, , @code{mysql_stmt_fetch()}}.

This function was added in MySQL 4.1.2.

@subsubheading Return Values

Zero if execution was successful. Non-zero if an error occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC 
Commands were executed in an improper order. 
@item CR_OUT_OF_MEMORY 
Out of memory. 
@item CR_SERVER_GONE_ERROR 
The MySQL server has gone away. 
@item CR_SERVER_LOST 
The connection to the server was lost during the query. 
@item CR_UNKNOWN_ERROR 
An unknown error occurred. 
@end table

@subsubheading Example

The following example demonstrates how to create and populate a table using
@code{mysql_stmt_init()},
@code{mysql_stmt_prepare()},
@code{mysql_stmt_param_count()}, @code{mysql_stmt_bind_param()},
@code{mysql_stmt_execute()},
and @code{mysql_stmt_affected_rows()}. The @code{mysql} variable is assumed
to be a valid connection handle.

@example
#define STRING_SIZE 50

#define DROP_SAMPLE_TABLE "DROP TABLE IF EXISTS test_table"
#define CREATE_SAMPLE_TABLE "CREATE TABLE test_table(col1 INT,\
                                                 col2 VARCHAR(40),\
                                                 col3 SMALLINT,\
                                                 col4 TIMESTAMP)"
#define INSERT_SAMPLE "INSERT INTO test_table(col1,col2,col3) VALUES(?,?,?)"

MYSQL_STMT    *stmt;
MYSQL_BIND    bind[3];
my_ulonglong  affected_rows;
int           param_count;
short         small_data;
int           int_data;
char          str_data[STRING_SIZE];
unsigned long str_length;
my_bool       is_null;

if (mysql_query(mysql, DROP_SAMPLE_TABLE))
@{
  fprintf(stderr, " DROP TABLE failed\n");
  fprintf(stderr, " %s\n", mysql_error(mysql));
  exit(0);
@}

if (mysql_query(mysql, CREATE_SAMPLE_TABLE))
@{
  fprintf(stderr, " CREATE TABLE failed\n");
  fprintf(stderr, " %s\n", mysql_error(mysql));
  exit(0);
@}

/* Prepare an INSERT query with 3 parameters */
/* (the TIMESTAMP column is not named; the server */
/* will set it to the current date and time) */
stmt = mysql_stmt_init(mysql);
if (!stmt)
@{
  fprintf(stderr, " mysql_stmt_init(), out of memory\n");
  exit(0);
@}
if (mysql_stmt_prepare(stmt, INSERT_SAMPLE, strlen(INSERT_SAMPLE)))
@{
  fprintf(stderr, " mysql_stmt_prepare(), INSERT failed\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
@}
fprintf(stdout, " prepare, INSERT successful\n");

/* Get the parameter count from the statement */
param_count= mysql_stmt_param_count(stmt);
fprintf(stdout, " total parameters in INSERT: %d\n", param_count);

if (param_count != 3) /* validate parameter count */
@{
  fprintf(stderr, " invalid parameter count returned by MySQL\n");
  exit(0);
@}

/* Bind the data for all 3 parameters */

memset(bind, 0, sizeof(bind));

/* INTEGER PARAM */
/* This is a number type, so there is no need to specify buffer_length */
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= (char *)&int_data;
bind[0].is_null= 0;
bind[0].length= 0;

/* STRING PARAM */
bind[1].buffer_type= MYSQL_TYPE_STRING;
bind[1].buffer= (char *)str_data;
bind[1].buffer_length= STRING_SIZE;
bind[1].is_null= 0;
bind[1].length= &str_length;

/* SMALLINT PARAM */
bind[2].buffer_type= MYSQL_TYPE_SHORT;
bind[2].buffer= (char *)&small_data;       
bind[2].is_null= &is_null;
bind[2].length= 0;

/* Bind the buffers */
if (mysql_stmt_bind_param(stmt, bind))
@{
  fprintf(stderr, " mysql_stmt_bind_param() failed\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
@}

/* Specify the data values for the first row */
int_data= 10;             /* integer */
strncpy(str_data, "MySQL", STRING_SIZE); /* string  */
str_length= strlen(str_data);

/* INSERT SMALLINT data as NULL */
is_null= 1;

/* Execute the INSERT statement - 1*/
if (mysql_stmt_execute(stmt))
@{
  fprintf(stderr, " mysql_stmt_execute(), 1 failed\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
@}

/* Get the total number of affected rows */   
affected_rows= mysql_stmt_affected_rows(stmt);
fprintf(stdout, " total affected rows(insert 1): %lu\n",
                (unsigned long) affected_rows);

if (affected_rows != 1) /* validate affected rows */
@{
  fprintf(stderr, " invalid affected rows by MySQL\n");
  exit(0);
@}

/* Specify data values for second row, then re-execute the statement */
int_data= 1000;             
strncpy(str_data, "The most popular Open Source database", STRING_SIZE); 
str_length= strlen(str_data);
small_data= 1000;         /* smallint */
is_null= 0;               /* reset */

/* Execute the INSERT statement - 2*/
if (mysql_stmt_execute(stmt))
@{
  fprintf(stderr, " mysql_stmt_execute, 2 failed\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
@}

/* Get the total rows affected */   
affected_rows= mysql_stmt_affected_rows(stmt);
fprintf(stdout, " total affected rows(insert 2): %lu\n",
                (unsigned long) affected_rows);

if (affected_rows != 1) /* validate affected rows */
@{
  fprintf(stderr, " invalid affected rows by MySQL\n");
  exit(0);
@}

/* Close the statement */
if (mysql_stmt_close(stmt))
@{
  fprintf(stderr, " failed while closing the statement\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
@}
@end example

@strong{Note}: For complete examples on the use of prepared
statement functions, refer to the file @file{tests/client_test.c}.
This file can be obtained from a MySQL source distribution or from the
BitKeeper source repository.


@node mysql_stmt_free_result, mysql_stmt_insert_id, mysql_stmt_execute, C API Prepared statement functions
@subsubsection @code{mysql_stmt_free_result()}

@findex @code{mysql_stmt_free_result()}

@code{my_bool mysql_stmt_free_result(MYSQL_STMT *stmt)}

@subsubheading Description

Releases memory associated with the result set produced by execution of
the prepared statement.

This function was added in MySQL 4.1.1.

@subsubheading Return Values

Zero if the result set was freed successfully.  Non-zero if an error occurred.

@subsubheading Errors


@node mysql_stmt_insert_id, mysql_stmt_fetch, mysql_stmt_free_result, C API Prepared statement functions
@subsubsection @code{mysql_stmt_insert_id()}

@findex @code{mysql_stmt_insert_id()}

@code{my_ulonglong mysql_stmt_insert_id(MYSQL_STMT *stmt)}

@subsubheading Description

Returns the value generated for an @code{AUTO_INCREMENT} column by the
prepared @code{INSERT} or @code{UPDATE} statement. Use this function after
you have executed prepared @code{INSERT} statement into a table which 
contains an @code{AUTO_INCREMENT} field.

See @ref{mysql_insert_id,  , @code{mysql_insert_id()}} for more 
information.

This function was added in MySQL 4.1.2.

@subsubheading Return Values

Value for @code{AUTO_INCREMENT} column which was automatically generated or
explicitly set during execution of prepared statement, or value generated
by @code{LAST_INSERT_ID(@var{expr})} function. Return value is undefined if statement 
does not set @code{AUTO_INCREMENT} value.

@c The last sentence is here as temporary measure only. After fixing code
@c responsible for handling of last_insert_id for prepared statements we should 
@c replace it with more precise description.

@subsubheading Errors

None.


@node mysql_stmt_fetch, mysql_stmt_fetch_column, mysql_stmt_insert_id, C API Prepared statement functions
@subsubsection @code{mysql_stmt_fetch()}

@findex @code{mysql_stmt_fetch()}

@code{int mysql_stmt_fetch(MYSQL_STMT *stmt)}

@subsubheading Description

@code{mysql_stmt_fetch()} returns the next row in the result set. It can
be called only while the result set exists, that is, after a call to
@code{mysql_stmt_execute()} that creates a result set or after
@code{mysql_stmt_store_result()}, which is called after
@code{mysql_stmt_execute()} to buffer the entire result set.

@code{mysql_stmt_fetch()} returns row data using the buffers bound by
@code{mysql_stmt_bind_result()}. It returns
the data in those buffers for all the columns in the current row
set and the lengths are returned to the @code{length} pointer.

All columns must be bound by the application before calling
@code{mysql_stmt_fetch()}.

If a fetched data value is a @code{NULL} value, the @code{*is_null}
value of the corresponding @code{MYSQL_BIND} structure contains TRUE
(1). Otherwise, the data and its length are returned in the @code{*buffer}
and @code{*length} elements based on the buffer type specified by the
application. Each numeric and temporal type has a fixed length,
as listed in the following table.
The length of the string types depends on the length of the actual data value,
as indicated by @code{data_length}.


@multitable @columnfractions .40 .40
@item @strong{Type}                 @tab @strong{Length} 
@item @code{MYSQL_TYPE_TINY}        @tab 1
@item @code{MYSQL_TYPE_SHORT}       @tab 2
@item @code{MYSQL_TYPE_LONG}        @tab 4
@item @code{MYSQL_TYPE_LONGLONG}    @tab 8
@item @code{MYSQL_TYPE_FLOAT}       @tab 4
@item @code{MYSQL_TYPE_DOUBLE}      @tab 8
@item @code{MYSQL_TYPE_TIME}        @tab @code{sizeof(MYSQL_TIME)}
@item @code{MYSQL_TYPE_DATE}        @tab @code{sizeof(MYSQL_TIME)}
@item @code{MYSQL_TYPE_DATETIME}    @tab @code{sizeof(MYSQL_TIME)}
@item @code{MYSQL_TYPE_STRING}      @tab @code{data length}
@item @code{MYSQL_TYPE_BLOB}        @tab @code{data_length}
@end multitable

This function was added in MySQL 4.1.2.

@subsubheading Return Values

@multitable @columnfractions .30 .65
@item @strong{Return Value}         @tab @strong{Description}
@item 0            @tab Successful, the data has been
fetched to application data buffers.
@item 1            @tab Error occurred. Error code and
message can be obtained by calling @code{mysql_stmt_errno()} and
@code{mysql_stmt_error()}.
@item @code{MYSQL_NO_DATA}           @tab No more rows/data exists
@end multitable


@subsubheading Errors
@table @code
@item CR_COMMANDS_OUT_OF_SYNC 
Commands were executed in an improper order. 
@item CR_OUT_OF_MEMORY 
Out of memory. 
@item CR_SERVER_GONE_ERROR 
The MySQL server has gone away. 
@item CR_SERVER_LOST 
The connection to the server was lost during the query. 
@item CR_UNKNOWN_ERROR 
An unknown error occurred. 
@item CR_UNSUPPORTED_PARAM_TYPE
The buffer type is
@code{MYSQL_TYPE_DATE},
@code{MYSQL_TYPE_TIME},
@code{MYSQL_TYPE_DATETIME},
or
@code{MYSQL_TYPE_TIMESTAMP},
but the data type is not @code{DATE}, @code{TIME}, @code{DATETIME}, or
@code{TIMESTAMP}.
@item
All other unsupported conversion errors are returned from
@code{mysql_stmt_bind_result()}.
@end table

@c TODO: need to document allowed conversions in both directions

@subsubheading Example

The following example demonstrates how to fetch data from a table using
 @code{mysql_stmt_result_metadata()},
@code{mysql_stmt_bind_result()}, and @code{mysql_stmt_fetch()}.
(This example expects to retrieve the two rows inserted by the example shown
in @ref{mysql_stmt_execute, , @code{mysql_stmt_execute()}}.)
The @code{mysql} variable is assumed to be a valid connection handle.

@example
#define STRING_SIZE 50

#define SELECT_SAMPLE "SELECT col1, col2, col3, col4 FROM test_table"

MYSQL_STMT    *stmt;
MYSQL_BIND    bind[4];
MYSQL_RES     *prepare_meta_result;
MYSQL_TIME    ts;
unsigned long length[4];
int           param_count, column_count, row_count;
short         small_data;
int           int_data;
char          str_data[STRING_SIZE];
my_bool       is_null[4];

/* Prepare a SELECT query to fetch data from test_table */
stmt = mysql_stmt_init(mysql);
if (!stmt)
@{
  fprintf(stderr, " mysql_stmt_init(), out of memory\n");
  exit(0);
@}
if (mysql_stmt_prepare(stmt, SELECT_SAMPLE, strlen(SELECT_SAMPLE)))
@{
  fprintf(stderr, " mysql_stmt_prepare(), SELECT failed\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
@}
fprintf(stdout, " prepare, SELECT successful\n");

/* Get the parameter count from the statement */
param_count= mysql_stmt_param_count(stmt);
fprintf(stdout, " total parameters in SELECT: %d\n", param_count);

if (param_count != 0) /* validate parameter count */
@{
  fprintf(stderr, " invalid parameter count returned by MySQL\n");
  exit(0);
@}

/* Fetch result set meta information */
prepare_meta_result = mysql_stmt_result_metadata(stmt);
if (!prepare_meta_result)
@{
  fprintf(stderr,
         " mysql_stmt_result_metadata(), returned no meta information\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
@}

/* Get total columns in the query */
column_count= mysql_num_fields(prepare_meta_result);
fprintf(stdout, " total columns in SELECT statement: %d\n", column_count);

if (column_count != 4) /* validate column count */
@{
  fprintf(stderr, " invalid column count returned by MySQL\n");
  exit(0);
@}

/* Execute the SELECT query */
if (mysql_stmt_execute(stmt))
@{
  fprintf(stderr, " mysql_stmt_execute(), failed\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
@}

/* Bind the result buffers for all 4 columns before fetching them */

memset(bind, 0, sizeof(bind));

/* INTEGER COLUMN */
bind[0].buffer_type= MYSQL_TYPE_LONG;
bind[0].buffer= (char *)&int_data;
bind[0].is_null= &is_null[0];
bind[0].length= &length[0];

/* STRING COLUMN */
bind[1].buffer_type= MYSQL_TYPE_STRING;
bind[1].buffer= (char *)str_data;
bind[1].buffer_length= STRING_SIZE;
bind[1].is_null= &is_null[1];
bind[1].length= &length[1];

/* SMALLINT COLUMN */
bind[2].buffer_type= MYSQL_TYPE_SHORT;
bind[2].buffer= (char *)&small_data;       
bind[2].is_null= &is_null[2];
bind[2].length= &length[2];

/* TIMESTAMP COLUMN */
bind[3].buffer_type= MYSQL_TYPE_TIMESTAMP;
bind[3].buffer= (char *)&ts;       
bind[3].is_null= &is_null[3];
bind[3].length= &length[3];

/* Bind the result buffers */
if (mysql_stmt_bind_result(stmt, bind))
@{
  fprintf(stderr, " mysql_stmt_bind_result() failed\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
@}

/* Now buffer all results to client */
if (mysql_stmt_store_result(stmt))
@{
  fprintf(stderr, " mysql_stmt_store_result() failed\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
@}

/* Fetch all rows */
row_count= 0;
fprintf(stdout, "Fetching results ...\n");
while (!mysql_stmt_fetch(stmt))
@{
  row_count++;
  fprintf(stdout, "  row %d\n", row_count);

  /* column 1 */
  fprintf(stdout, "   column1 (integer)  : ");
  if (is_null[0])
    fprintf(stdout, " NULL\n");
  else
    fprintf(stdout, " %d(%ld)\n", int_data, length[0]);

  /* column 2 */
  fprintf(stdout, "   column2 (string)   : ");
  if (is_null[1])
    fprintf(stdout, " NULL\n");
  else
    fprintf(stdout, " %s(%ld)\n", str_data, length[1]);

  /* column 3 */
  fprintf(stdout, "   column3 (smallint) : ");
  if (is_null[2])
    fprintf(stdout, " NULL\n");
  else
    fprintf(stdout, " %d(%ld)\n", small_data, length[2]);

  /* column 4 */
  fprintf(stdout, "   column4 (timestamp): ");
  if (is_null[3])
    fprintf(stdout, " NULL\n");
  else
    fprintf(stdout, " %04d-%02d-%02d %02d:%02d:%02d (%ld)\n",
									   ts.year, ts.month, ts.day,
									   ts.hour, ts.minute, ts.second,
									   length[3]);
  fprintf(stdout, "\n");
@}

/* Validate rows fetched */
fprintf(stdout, " total rows fetched: %d\n", row_count);
if (row_count != 2)
@{
  fprintf(stderr, " MySQL failed to return all rows\n");
  exit(0);
@} 

/* Free the prepared result metadata */
mysql_free_result(prepare_meta_result);


/* Close the statement */
if (mysql_stmt_close(stmt))
@{
  fprintf(stderr, " failed while closing the statement\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
@}
@end example


@node mysql_stmt_fetch_column, mysql_stmt_field_count, mysql_stmt_fetch, C API Prepared statement functions
@subsubsection @code{mysql_stmt_fetch_column()}

@findex @code{mysql_stmt_fetch_column()}

@code{int mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind, unsigned int column, unsigned long offset)}

@subsubheading Description

Fetch one column from the current result set row. @code{bind} provides the
buffer where data should be placed.  It should be set up the same way as for
@code{mysql_stmt_bind_result()}. @code{column} indicates which column to
fetch. The first column is numbered 0.  @code{offset} is the offset within the
data value at which to begin retrieving data.  This can be used for fetching
the data value in pieces. The beginning of the value is offset 0.

This function was added in MySQL 4.1.2.

@subsubheading Return Values

Zero if the value was fetched successfully.  Non-zero if an error occurred.

@subsubheading Errors

@table @code
@item CR_INVALID_PARAMETER_NO
Invalid column number.
@item CR_NO_DATA
The end of the result set has already been reached.
@end table


@node mysql_stmt_field_count, mysql_stmt_init, mysql_stmt_fetch_column, C API Prepared statement functions
@subsubsection @code{mysql_stmt_field_count()}

@findex @code{mysql_stmt_field_count()}

@code{unsigned int mysql_stmt_field_count(MYSQL_STMT *stmt)}

@subsubheading Description

Returns the number of columns for the most recent statement for the statement
handler. This value will be zero for statements such as @code{INSERT} or
@code{DELETE} that do not produce result sets.

@code{mysql_stmt_field_count()} can be called after you have prepared a
statement by invoking @code{mysql_stmt_prepare()}.

This function was added in MySQL 4.1.3.

@subsubheading Return Values

An unsigned integer representing the number of columns in a result set.

@subsubheading Errors
None.


@node mysql_stmt_init, mysql_stmt_num_rows, mysql_stmt_field_count, C API Prepared statement functions
@subsubsection @code{mysql_stmt_init()}

@findex @code{mysql_stmt_init()}

@code{MYSQL_STMT *mysql_stmt_init(MYSQL *mysql)}

@subsubheading Description

Create a @code{MYSQL_STMT} handle.
The handle should be freed with @code{mysql_stmt_close(MYSQL_STMT *)}.

This function was added in MySQL 4.1.2.

@subsubheading Return values

A pointer to a @code{MYSQL_STMT} structure in case of success.
@code{NULL} if out of memory.

@subsubheading Errors

@table @code
@item CR_OUT_OF_MEMORY
Out of memory.
@end table


@node mysql_stmt_num_rows, mysql_stmt_param_count, mysql_stmt_init, C API Prepared statement functions
@subsubsection @code{mysql_stmt_num_rows()}

@findex @code{mysql_stmt_num_rows()}

@code{my_ulonglong mysql_stmt_num_rows(MYSQL_STMT *stmt)}

@subsubheading Description

Returns the number of rows in the result set.

The use of @code{mysql_stmt_num_rows()} depends on whether or not you used
@code{mysql_stmt_store_result()} to buffer the entire result set in the
statement handle.

If you use @code{mysql_stmt_store_result()}, @code{mysql_stmt_num_rows()} may be
called immediately.

@c TODO: and otherwise? Only after all rows have been fetched?

This function was added in MySQL 4.1.1.

@subsubheading Return Values

The number of rows in the result set.

@subsubheading Errors
None.


@node mysql_stmt_param_count, mysql_stmt_param_metadata, mysql_stmt_num_rows, C API Prepared statement functions
@subsubsection @code{mysql_stmt_param_count()}

@findex @code{mysql_stmt_param_count()}

@code{unsigned long mysql_stmt_param_count(MYSQL_STMT *stmt)}

@subsubheading Description

Returns the number of parameter markers present in the prepared statement.

This function was added in MySQL 4.1.2.

@subsubheading Return Values

An unsigned long integer representing the number of parameters in a
statement.

@subsubheading Errors

None.

@subsubheading Example

For the usage of @code{mysql_stmt_param_count()}, refer to the Example from
@ref{mysql_stmt_execute, , @code{mysql_stmt_execute()}}.


@node mysql_stmt_param_metadata, mysql_stmt_prepare, mysql_stmt_param_count, C API Prepared statement functions
@subsubsection @code{mysql_stmt_param_metadata()}

@findex @code{mysql_stmt_param_metadata()}

@code{MYSQL_RES *mysql_stmt_param_metadata(MYSQL_STMT *stmt)}

@c TODO: fill this in
To be added.

This function was added in MySQL 4.1.2.

@subsubheading Description


@subsubheading Return Values


@subsubheading Errors


@node mysql_stmt_prepare, mysql_stmt_reset, mysql_stmt_param_metadata, C API Prepared statement functions
@subsubsection @code{mysql_stmt_prepare()}

@findex @code{mysql_stmt_prepare()}

@code{int mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, unsigned
long length)}

@subsubheading Description

Given the statement handle returned by @code{mysql_stmt_init()},
prepares the SQL statement pointed to by the string
@code{query} and returns a status value.
The string length should be given by the @code{length} argument.
The string must consist of a single SQL statement. You should
not add a terminating semicolon (@samp{;}) or @code{\g} to the statement.

The application can include one or more parameter markers in the SQL
statement by embedding question mark (@samp{?}) characters into the SQL
string at the appropriate positions.

The markers are legal only in certain places in SQL statements. For
example, they are allowed in the @code{VALUES()} list of an @code{INSERT}
statement (to specify column values for a row), or in a comparison with a
column in a @code{WHERE} clause to specify a comparison value.
However, they are not allowed for identifiers (such as table or column
names), or to specify both
operands of a binary operator such as the @code{=} equal sign.
The latter restriction is necessary because it
would be impossible to determine the parameter type. In general,
parameters are legal only in Data Manipulation Languange (DML)
statements, and not in Data Defination Language (DDL) statements.

The parameter markers must be bound to application variables using
@code{mysql_stmt_bind_param()} before executing the statement.

This function was added in MySQL 4.1.2.


@subsubheading Return Values

Zero if the statement was prepared successfully.  Non-zero if an error occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_OUT_OF_MEMORY
Out of memory.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table

If the prepare operation was unsuccessful (that is,
@code{mysql_stmt_prepare()} returns non-zero), the error message can be
obtained by calling @code{mysql_stmt_error()}.


@subsubheading Example

For the usage of @code{mysql_stmt_prepare()}, refer to the Example from
@ref{mysql_stmt_execute, , @code{mysql_stmt_execute()}}.


@node mysql_stmt_reset, mysql_stmt_result_metadata, mysql_stmt_prepare, C API Prepared statement functions
@subsubsection @code{mysql_stmt_reset()}

@findex @code{mysql_stmt_reset()}

@code{my_bool mysql_stmt_reset(MYSQL_STMT *stmt)}

@subsubheading Description

Reset prepared statement on client and server to state after prepare.
For now this is mainly used to reset data sent with
@code{mysql_stmt_send_long_data()}.

To re-prepare the statement with another query, use
@code{mysql_stmt_prepare()}.

This function was added in MySQL 4.1.1.

@subsubheading Return Values

Zero if the statement was reset successfully.  Non-zero if an error occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_SERVER_LOST
The connection to the server was lost during the query
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table


@node mysql_stmt_result_metadata, mysql_stmt_row_seek, mysql_stmt_reset, C API Prepared statement functions
@subsubsection @code{mysql_stmt_result_metadata()}

@findex @code{mysql_stmt_result_metadata}.

@code{MYSQL_RES *mysql_stmt_result_metadata(MYSQL_STMT *stmt)}

@subsubheading Description

If a statement passed to @code{mysql_stmt_prepare()} is one that produces a result
set,
@code{mysql_stmt_result_metadata()} returns the result set
metadata in the form of a pointer to a
@code{MYSQL_RES} structure that can be used to process the
meta information such as total number of fields and individual field
information. This result set pointer can be passed as an argument to
any of the field-based API functions that process result set metadata, such
as:

@itemize @bullet
@item @code{mysql_num_fields()}
@item @code{mysql_fetch_field()}
@item @code{mysql_fetch_field_direct()}
@item @code{mysql_fetch_fields()}
@item @code{mysql_field_count()}
@item @code{mysql_field_seek()}
@item @code{mysql_field_tell()}
@item @code{mysql_free_result()}
@end itemize

The result set structure should be freed when you are done with it, which
you can do by passing it to @code{mysql_free_result()}. This is similar
to the way you free a result set obtained from a call to
@code{mysql_store_result()}.

The result set returned by @code{mysql_stmt_result_metadata()} contains only
metadata. It does not contain any row results. The rows are obtained by using
the statement handle with @code{mysql_stmt_fetch()}.

This function was added in MySQL 4.1.2.


@subsubheading Return Values

A @code{MYSQL_RES} result structure. @code{NULL} if no meta information exists
for the prepared query.


@subsubheading Errors

@table @code
@item CR_OUT_OF_MEMORY
Out of memory.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table


@subsubheading Example

For the usage of @code{mysql_stmt_result_metadata()}, refer to the
Example from @ref{mysql_stmt_fetch, , @code{mysql_stmt_fetch()}}.


@node mysql_stmt_row_seek, mysql_stmt_row_tell, mysql_stmt_result_metadata, C API Prepared statement functions
@subsubsection @code{mysql_stmt_row_seek()}

@findex @code{mysql_stmt_row_seek()}

@code{MYSQL_ROW_OFFSET mysql_stmt_row_seek(MYSQL_STMT *stmt, MYSQL_ROW_OFFSET offset)}

@subsubheading Description
Sets the row cursor to an arbitrary row in a statement result set.
The @code{offset} value is a row offset that should be a value returned
from @code{mysql_stmt_row_tell()} or from @code{mysql_stmt_row_seek()}.
This value is not a row number; if you want to seek to a row within a
result set by number, use @code{mysql_stmt_data_seek()} instead.

@c TODO: this para may not make sense. It's written in parallel with
@c mysql_data_seek(), but there is no corresponding mysql_stmt_use_result().

This function requires that the result set structure contains the entire
result of the query, so @code{mysql_stmt_row_seek()} may be used only
in conjunction with @code{mysql_stmt_store_result()}.

This function was added in MySQL 4.1.1.

@subsubheading Return Values

The previous value of the row cursor.  This value may be passed to a
subsequent call to @code{mysql_stmt_row_seek()}.

@subsubheading Errors
None.


@node mysql_stmt_row_tell, mysql_stmt_send_long_data, mysql_stmt_row_seek, C API Prepared statement functions
@subsubsection @code{mysql_stmt_row_tell()}

@findex @code{mysql_stmt_row_tell()}

@code{MYSQL_ROW_OFFSET mysql_stmt_row_tell(MYSQL_STMT *stmt)}

@subsubheading Description

Returns the current position of the row cursor for the last
@code{mysql_stmt_fetch()}. This value can be used as an argument to
@code{mysql_stmt_row_seek()}.

You should use @code{mysql_stmt_row_tell()} only after @code{mysql_stmt_store_result()}.

This function was added in MySQL 4.1.1.

@subsubheading Return Values

The current offset of the row cursor.

@subsubheading Errors
None.


@node mysql_stmt_send_long_data, mysql_stmt_sqlstate, mysql_stmt_row_tell, C API Prepared statement functions
@subsubsection @code{mysql_stmt_send_long_data()}

@findex @code{mysql_stmt_send_long_data()}.

@code{my_bool mysql_stmt_send_long_data(MYSQL_STMT *stmt, unsigned int
parameter_number, const char *data, unsigned long length)}

@subsubheading Description

Allows an application to send parameter data to the server in pieces
(or ``chunks'').
This function can be called multiple times to send the parts of a
character or binary data value for a column, which must be one of the
@code{TEXT} or @code{BLOB} data types.

@code{parameter_number} indicates which parameter to associate the data with.
Parameters are numbered beginning with 0.
@code{data} is a pointer to a buffer containing data to be sent, and
@code{length} indicates the number of bytes in the buffer.

@strong{Note}: The next @code{mysql_stmt_execute()} call will ignore the
bind buffer for all parameters that have been used with
@code{mysql_stmt_send_long_data()} since last
@code{mysql_stmt_execute()} or @code{mysql_stmt_reset()}.

If you want to reset/forget the sent data, you can do it with
@code{mysql_stmt_reset()}. @xref{mysql_stmt_reset}.

This function was added in MySQL 4.1.2.

@subsubheading Return Values

Zero if the data is sent successfully to server. Non-zero if an error
occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Commands were executed in an improper order.
@item CR_SERVER_GONE_ERROR
The MySQL server has gone away.
@item CR_OUT_OF_MEMORY
Out of memory.
@item CR_UNKNOWN_ERROR
An unknown error occurred.
@end table

@subsubheading Example
The following example demonstrates how to send the data for a
@code{TEXT} column in chunks.  It inserts the data value
@code{'MySQL - The most popular Open Source database'}
into the @code{text_column} column.
The @code{mysql} variable is assumed to be a valid connection handle.

@c TODO: replace this example?

@example
#define INSERT_QUERY "INSERT INTO test_long_data(text_column) VALUES(?)"

MYSQL_BIND bind[1];
long       length;

smtt = mysql_stmt_init(mysql);
if (!stmt)
@{
  fprintf(stderr, " mysql_stmt_init(), out of memory\n");
  exit(0);
@}
if (mysql_stmt_prepare(stmt, INSERT_QUERY, strlen(INSERT_QUERY)))
@{
  fprintf(stderr, "\n mysql_stmt_prepare(), INSERT failed");
  fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
  exit(0);
@}
 memset(bind, 0, sizeof(bind));
 bind[0].buffer_type= MYSQL_TYPE_STRING;
 bind[0].length= &length;
 bind[0].is_null= 0;

/* Bind the buffers */
if (mysql_stmt_bind_param(stmt, bind))
@{
  fprintf(stderr, "\n param bind failed");
  fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
  exit(0);
@}

 /* Supply data in chunks to server */
 if (!mysql_stmt_send_long_data(stmt,0,"MySQL",5))
@{
  fprintf(stderr, "\n send_long_data failed");
  fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
  exit(0);
@}

 /* Supply the next piece of data */
 if (mysql_stmt_send_long_data(stmt,0," - The most popular Open Source database",40))
@{
  fprintf(stderr, "\n send_long_data failed");
  fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
  exit(0);
@}

 /* Now, execute the query */
 if (mysql_stmt_execute(stmt))
@{
  fprintf(stderr, "\n mysql_stmt_execute failed");
  fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
  exit(0);
@}
@end example


@node mysql_stmt_sqlstate, mysql_stmt_store_result, mysql_stmt_send_long_data, C API Prepared statement functions
@subsubsection @code{mysql_stmt_sqlstate()}

@findex @code{mysql_stmt_sqlstate()}

@code{const char *mysql_stmt_sqlstate(MYSQL_STMT *stmt)}

@subsubheading Description

For the statement specified by @code{stmt}, @code{mysql_stmt_sqlstate()}
returns a null-terminated string containing the SQLSTATE error code for the
most recently invoked prepared statement API function that can succeed or fail.
The error code consists of five characters.
@code{"00000"} means ``no error.''
The values are specified by ANSI SQL and ODBC.
For a list of possible values, see @ref{Error-handling}.

Note that not all MySQL errors are yet mapped to SQLSTATE's.
The value @code{"HY000"} (general error) is used
for unmapped errors.

This function was added to MySQL 4.1.1.

@subsubheading Return Values

A null-terminated character string containing the SQLSTATE error code.


@node mysql_stmt_store_result,  , mysql_stmt_sqlstate, C API Prepared statement functions
@subsubsection @code{mysql_stmt_store_result()}

@findex @code{mysql_stmt_store_result()}

@code{int mysql_stmt_store_result(MYSQL_STMT *stmt)}

@subsubheading Description

You must call @code{mysql_stmt_store_result()} for every statement that
successfully produces a result set
(@code{SELECT}, @code{SHOW}, @code{DESCRIBE}, @code{EXPLAIN}), and only
if you want to buffer the complete result set by the client, so that the
subsequent @code{mysql_stmt_fetch()} call returns buffered data.

It is unnecessary to call @code{mysql_stmt_store_result()} for other
statements, but if you do, it will not harm or cause any notable performance
problem.
You can detect whether the statement produced a result set by checking
if @code{mysql_stmt_result_metadata()} returns @code{NULL}.
For more information, refer to @ref{mysql_stmt_result_metadata, ,
@code{mysql_stmt_result_metadata()}}.

@strong{Note}:
MySQL doesn't by default calculate @code{MYSQL_FIELD->max_length} for
all columns in @code{mysql_stmt_store_result()} because calculating this
would slow down @code{mysql_stmt_store_result()} considerably and most
applications doesn't need @code{max_length}.  If you want
@code{max_length} to be updated, you can call
@code{mysql_stmt_attr_set(MYSQL_STMT, STMT_ATTR_UPDATE_MAX_LENGTH, &flag)}
to enable this. @xref{mysql_stmt_attr_set}.

This function was added in MySQL 4.1.0.

@subsubheading Return Values

Zero if the results are buffered successfully.  Non-zero if an error occurred.

@subsubheading Errors

@table @code
@item CR_COMMANDS_OUT_OF_SYNC 
Commands were executed in an improper order. 
@item CR_OUT_OF_MEMORY 
Out of memory. 
@item CR_SERVER_GONE_ERROR 
The MySQL server has gone away. 
@item CR_SERVER_LOST
The connection to the server was lost during the query. 
@item CR_UNKNOWN_ERROR 
An unknown error occurred. 
@end table

@node C API Prepared statement problems, C API multiple queries, C API Prepared statement functions, C
@subsection C API Prepared statement problems

Here follows a list of the currently known problems with prepared
statements:

@itemize @bullet
@item
@code{TIME}, @code{TIMESTAMP}, and @code{DATETIME} don't support sub seconds
(for example from @code{DATE_FORMAT()}.
@item
When converting an integer to string, @code{ZEROFILL} is honored with prepared
statements
in some cases where the MySQL server doesn't print the leading zeros.
(For example, with @code{MIN(number-with-zerofill)}).
@item
When converting a floating point number to a string in the client, the value
may be slightly different in the last digits.
@end itemize


@node C API multiple queries, C API date handling, C API Prepared statement problems, C
@subsection C API Handling of Multiple Query Execution

From version 4.1, MySQL supports the execution of multiple statements
specified in a single query string. To use this capability with a given
connection, you must specify the @code{CLIENT_MULTI_STATEMENTS} option in
the flags parameter of @code{mysql_real_connect()}
when opening the connection.  You can also set this for an existing connection
by calling @code{mysql_set_server_option(MYSQL_OPTION_MULTI_STATEMENTS_ON)}

By default, @code{mysql_query()} and @code{mysql_real_query()} return
only the first query status and the subsequent queries status can
be processed using @code{mysql_more_results()} and
@code{mysql_next_result()}.

@example

/* Connect to server with option CLIENT_MULTI_STATEMENTS */
mysql_real_connect(..., CLIENT_MULTI_STATEMENTS);

/* Now execute multiple queries */
mysql_query(mysql,"DROP TABLE IF EXISTS test_table;\
                   CREATE TABLE test_table(id INT);\
                   INSERT INTO test_table VALUES(10);\
                   UPDATE test_table SET id=20 WHERE id=10;\
                   SELECT * FROM test_table;\
                   DROP TABLE test_table");
do
@{
  /* Process all results */
  ...
  printf("total affected rows: %lld", mysql_affected_rows(mysql));
  ...
  if (!(result= mysql_store_result(mysql)))
  @{
     printf(stderr, "Got fatal error processing query\n");
     exit(1);
  @}
  process_result_set(result);	/* client function */
  mysql_free_result(result);
@} while (!mysql_next_result(mysql));

@end example


@node C API date handling, C Thread functions, C API multiple queries, C
@subsection C API Handling of Date and Time Values

The new binary protocol available in MySQL 4.1 and above allows you to
send and receive date and time values (@code{DATE}, @code{TIME},
@code{DATETIME}, and @code{TIMESTAMP}), using
the @code{MYSQL_TIME} structure. The members of this structure are described
in @ref{C API Prepared statement datatypes}.

To send temporal data values, you create a prepared statement with
@code{mysql_stmt_prepare()}. Then, before calling
@code{mysql_stmt_execute()} to execute the statement, use the following
procedure to set up each temporal parameter:

@enumerate

@item
In the @code{MYSQL_BIND} structure associated with the data value, set the
@code{buffer_type} member to the type that indicates what kind of temporal
value you're sending. For
@code{DATE},
@code{TIME},
@code{DATETIME},
or
@code{TIMESTAMP}
values, set @code{buffer_type} to
@code{MYSQL_TYPE_DATE},
@code{MYSQL_TYPE_TIME},
@code{MYSQL_TYPE_DATETIME},
or
@code{MYSQL_TYPE_TIMESTAMP},
respectively.

@item
Set the @code{buffer} member of the @code{MYSQL_BIND} structure to the address
of the @code{MYSQL_TIME} structure in which you will pass the temporal value.

@item
Fill in the members of the @code{MYSQL_TIME} structure that are appropriate
for the type of temporal value you're passing.
@end enumerate

Use @code{mysql_stmt_bind_param()} to bind the parameter data to the statement.
Then you can call @code{mysql_stmt_execute()}.

To retrieve temporal values, the procedure is similar, except that you set
the @code{buffer_type} member to the type of value you expect to receive, and
the @code{buffer} member to the address of a @code{MYSQL_TIME} structure into
which the returned value should be placed.
Use @code{mysql_bind_results()} to bind the buffers to the statement after
calling @code{mysql_stmt_execute()} and before fetching the results.

Here is a simple example that inserts @code{DATE}, @code{TIME}, and
@code{TIMESTAMP} data.
The @code{mysql} variable is assumed to be a valid connection handle.

@example

  MYSQL_TIME  ts;
  MYSQL_BIND  bind[3];
  MYSQL_STMT  *stmt;

  strmov(query, "INSERT INTO test_table(date_field, time_field,
                                        timestamp_field) VALUES(?,?,?");

  stmt = mysql_stmt_init(mysql);
  if (!stmt)
  @{
    fprintf(stderr, " mysql_stmt_init(), out of memory\n");
    exit(0);
  @}
  if (mysql_stmt_prepare(mysql, query, strlen(query)))
  @{
    fprintf(stderr, "\n mysql_stmt_prepare(), INSERT failed");
    fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
    exit(0);
  @}

  /* set up input buffers for all 3 parameters */
  bind[0].buffer_type= MYSQL_TYPE_DATE;
  bind[0].buffer= (char *)&ts;  
  bind[0].is_null= 0;
  bind[0].length= 0;
  ...
  bind[1]= bind[2]= bind[0];
  ...

  mysql_stmt_bind_param(stmt, bind);

  /* supply the data to be sent in the ts structure */
  ts.year= 2002;
  ts.month= 02;
  ts.day= 03;

  ts.hour= 10;
  ts.minute= 45;
  ts.second= 20;

  mysql_stmt_execute(stmt);
  .. 

@end example


@node C Thread functions, C Embedded Server func, C API date handling, C
@subsection C API Threaded Function Descriptions

You need to use the following functions when you want to create a
threaded client. @xref{Threaded clients}.

@menu
* my_init::                     @code{my_init()}
* mysql_thread_init::           @code{mysql_thread_init()}
* mysql_thread_end::            @code{mysql_thread_end()}
* mysql_thread_safe::           @code{mysql_thread_safe()}
@end menu

@node my_init, mysql_thread_init, C Thread functions, C Thread functions
@subsubsection @code{my_init()}

@findex @code{my_init()}

@code{void my_init(void)}

@subsubheading Description

This function needs to be called once in the program before calling any
MySQL function.  This initializes some global variables that MySQL
needs.  If you are using a thread-safe client library, this will also
call @code{mysql_thread_init()} for this thread.

This is automatically called by @code{mysql_init()},
@code{mysql_server_init()} and @code{mysql_connect()}.

@subsubheading Return Values

None.

@node mysql_thread_init, mysql_thread_end, my_init, C Thread functions
@subsubsection @code{mysql_thread_init()}

@findex @code{mysql_thread_init()}

@code{my_bool mysql_thread_init(void)}

@subsubheading Description

This function needs to be called for each created thread to initialize
thread-specific variables.

This is automatically called by @code{my_init()} and @code{mysql_connect()}.

@subsubheading Return Values

Zero if successful. Non-zero if an error occurred.

@node mysql_thread_end, mysql_thread_safe, mysql_thread_init, C Thread functions
@subsubsection @code{mysql_thread_end()}

@findex @code{mysql_thread_end()}

@code{void mysql_thread_end(void)}

@subsubheading Description

This function needs to be called before calling @code{pthread_exit()} to
free memory allocated by @code{mysql_thread_init()}.

Note that this function @strong{is not invoked automatically} by the client
library.  It must be called explicitly to avoid a memory leak.

@subsubheading Return Values

None.

@node mysql_thread_safe,  , mysql_thread_end, C Thread functions
@subsubsection @code{mysql_thread_safe()}

@findex @code{mysql_thread_safe()}

@code{unsigned int mysql_thread_safe(void)}

@subsubheading Description

This function indicates whether the client is compiled as thread-safe.

@subsubheading Return Values

1 is the client is thread-safe, 0 otherwise.

@node C Embedded Server func, C API problems, C Thread functions, C
@subsection C API Embedded Server Function Descriptions

You must use the following functions if you want to allow your
application to be linked against the embedded MySQL server library.
@xref{libmysqld}.

If the program is linked with @code{-lmysqlclient} instead of
@code{-lmysqld}, these functions do nothing.  This makes it
possible to choose between using the embedded MySQL server and
a standalone server without modifying any code.

@menu
* mysql_server_init::           @code{mysql_server_init()}
* mysql_server_end::            @code{mysql_server_end()}
@end menu

@node mysql_server_init, mysql_server_end, C Embedded Server func, C Embedded Server func
@subsubsection @code{mysql_server_init()}

@findex @code{mysql_server_init()}

@code{int mysql_server_init(int argc, char **argv, char **groups)}

@subsubheading Description

This function @strong{must} be called once in the program using the
embedded server before calling any other MySQL function.  It starts
the server and initializes any subsystems (@code{mysys}, @code{InnoDB}, etc.) 
that the server uses.  If this function is not called, next call to
@code{mysql_init} will execute @code{mysql_server_init}.
If you are using the DBUG package that comes with MySQL, you should call
this after you have called @code{my_init()}.

The @code{argc} and @code{argv} arguments are analogous to the arguments
to @code{main()}.  The first element of @code{argv} is ignored (it
typically contains the program name).  For convenience, @code{argc} may
be @code{0} (zero) if there are no command-line arguments for the
server.  @code{mysql_server_init()} makes a copy of the arguments so
it's safe to destroy @code{argv} or @code{groups} after the call.

If you want to connect to an external server without starting the embedded
server, you have to specify a negative value for @code{argc}.

The @code{NULL}-terminated list of strings in @code{groups}
selects which groups in the option files will be active.
@xref{Option files}.  For convenience, @code{groups} may be
@code{NULL}, in which case the @code{[server]} and @code{[emedded]} groups
will be active.

@subsubheading Example

@example
#include <mysql.h>
#include <stdlib.h>

static char *server_args[] = @{
  "this_program",       /* this string is not used */
  "--datadir=.",
  "--key_buffer_size=32M"
@};
static char *server_groups[] = @{
  "embedded",
  "server",
  "this_program_SERVER",
  (char *)NULL
@};

int main(void) @{
  if (mysql_server_init(sizeof(server_args) / sizeof(char *),
                        server_args, server_groups))
    exit(1);

  /* Use any MySQL API functions here */

  mysql_server_end();

  return EXIT_SUCCESS;
@}
@end example

@subsubheading Return Values

0 if okay, 1 if an error occurred.

@node mysql_server_end,  , mysql_server_init, C Embedded Server func
@subsubsection @code{mysql_server_end()}

@findex @code{mysql_server_end()}

@code{void mysql_server_end(void)}

@subsubheading Description

This function @strong{must} be called once in the program after
all other MySQL functions.  It shuts down the embedded server.

@subsubheading Return Values

None.

@node C API problems, Building clients, C Embedded Server func, C
@subsection Common questions and problems when using the C API

@tindex @code{mysql_query()}
@tindex @code{mysql_store_result()}

@menu
* NULL mysql_store_result::     Why @code{mysql_store_result()} Sometimes Returns @code{NULL} After @code{mysql_query()} Returns Success
* Query results::               What Results You Can Get from a Query
* Getting unique ID::           How to Get the Unique ID for the Last Inserted Row
* C API linking problems::      Problems Linking with the C API
@end menu


@node NULL mysql_store_result, Query results, C API problems, C API problems
@subsubsection Why @code{mysql_store_result()} Sometimes Returns @code{NULL} After @code{mysql_query()} Returns Success

It is possible for @code{mysql_store_result()} to return @code{NULL}
following a successful call to @code{mysql_query()}.  When this happens, it
means one of the following conditions occurred:

@itemize @bullet
@item
There was a @code{malloc()} failure (for example, if the result set was too
large).

@item
The data couldn't be read (an error occurred on the connection).

@item
The query returned no data (for example, it was an @code{INSERT},
@code{UPDATE}, or @code{DELETE}).
@end itemize

You can always check whether the statement should have produced a
non-empty result by calling @code{mysql_field_count()}.  If
@code{mysql_field_count()} returns zero, the result is empty and the last
query was a statement that does not return values (for example, an
@code{INSERT} or a @code{DELETE}).  If @code{mysql_field_count()} returns a
non-zero value, the statement should have produced a non-empty result.
See the description of the @code{mysql_field_count()} function for an
example.

You can test for an error by calling @code{mysql_error()} or
@code{mysql_errno()}.

@node Query results, Getting unique ID, NULL mysql_store_result, C API problems
@subsubsection What Results You Can Get from a Query

In addition to the result set returned by a query, you can also get the
following information:

@itemize @bullet
@item
@code{mysql_affected_rows()} returns the number of rows affected by the last
query when doing an @code{INSERT}, @code{UPDATE}, or @code{DELETE}. 

In MySQL 3.23, there is an exception when @code{DELETE} is used without
a @code{WHERE} clause. In this case, the table is re-created as an empty
table and @code{mysql_affected_rows()} returns zero for the number of
records affected.  In MySQL 4.0, @code{DELETE} always returns the correct
number of rows deleted. For a fast recreate, use @code{TRUNCATE TABLE}.

@item
@code{mysql_num_rows()} returns the number of rows in a result set.  With
@code{mysql_store_result()}, @code{mysql_num_rows()} may be called as soon as
@code{mysql_store_result()} returns.  With @code{mysql_use_result()},
@code{mysql_num_rows()} may be called only after you have fetched all the
rows with @code{mysql_fetch_row()}.

@item
@code{mysql_insert_id()} returns the ID generated by the last
query that inserted a row into a table with an @code{AUTO_INCREMENT} index.
@xref{mysql_insert_id, , @code{mysql_insert_id()}}.

@item
Some queries (@code{LOAD DATA INFILE ...}, @code{INSERT INTO
... SELECT ...}, @code{UPDATE}) return additional information.  The result is
returned by @code{mysql_info()}.  See the description for @code{mysql_info()}
for the format of the string that it returns.  @code{mysql_info()} returns a
@code{NULL} pointer if there is no additional information.
@end itemize


@node Getting unique ID, C API linking problems, Query results, C API problems
@subsubsection How to Get the Unique ID for the Last Inserted Row

@cindex unique ID
@cindex last row, unique ID
@cindex ID, unique
@cindex tables, unique ID for last row

If you insert a record into a table that contains an @code{AUTO_INCREMENT}
column, you can obtain the value stored into that column by calling the
@code{mysql_insert_id()} function.

You can check from your C applications whether a value was stored into an
@code{AUTO_INCREMENT} column by executing the following code (which assumes
that you've already checked that the statement succeeded). It determines
whether the query was an @code{INSERT} with an @code{AUTO_INCREMENT} index:

@example
if ((result = mysql_store_result(&mysql)) == 0 &&
    mysql_field_count(&mysql) == 0 &&
    mysql_insert_id(&mysql) != 0)
@{
    used_id = mysql_insert_id(&mysql);
@}
@end example

For more information, see @ref{mysql_insert_id,  , @code{mysql_insert_id()}}.

When a new @code{AUTO_INCREMENT} value has been generated, you can also
obtain it by executing a @code{SELECT LAST_INSERT_ID()} statement with
@code{mysql_query()} and retrieving the value from the result set returned
by the statement.

For @code{LAST_INSERT_ID()},
the most recently generated ID is maintained in the server on a
per-connection basis.  It will not be changed by another client. It will not
even be changed if you update another @code{AUTO_INCREMENT} column with a
non-magic value (that is, a value that is not @code{NULL} and not @code{0}).

If you want to use the ID that was generated for one table and insert
it into a second table, you can use SQL statements like this:

@example
INSERT INTO foo (auto,text)
    VALUES(NULL,'text');              # generate ID by inserting NULL
INSERT INTO foo2 (id,text)
    VALUES(LAST_INSERT_ID(),'text');  # use ID in second table
@end example

Note that @code{mysql_insert_id()} returns the value stored into an
@code{AUTO_INCREMENT} column, whether that value is automatically generated
by storing @code{NULL} or @code{0} or was specified as an explicit value.
@code{LAST_INSERT_ID()} returns only automatically generated
@code{AUTO_INCREMENT} values. If you store an explicit value other than
@code{NULL} or @code{0}, it does not affect the value returned by
@code{LAST_INSERT_ID()}.


@node C API linking problems,  , Getting unique ID, C API problems
@subsubsection Problems Linking with the C API

@cindex linking, problems
@cindex C API, linking problems

When linking with the C API, the following errors may occur on some systems:

@example
gcc -g -o client test.o -L/usr/local/lib/mysql -lmysqlclient -lsocket -lnsl

Undefined        first referenced
 symbol          in file
floor            /usr/local/lib/mysql/libmysqlclient.a(password.o)
ld: fatal: Symbol referencing errors. No output written to client
@end example

If this happens on your system, you must include the math library by
adding @code{-lm} to the end of the compile/link line.


@node Building clients, Threaded clients, C API problems, C
@subsection Building Client Programs

@cindex client programs, building
@cindex linking
@cindex building, client programs
@cindex programs, client

If you compile MySQL clients that you've written yourself or that
you obtain from a third-party, they must be linked using the
@code{-lmysqlclient -lz} option on the link command.  You may also need to
specify a @code{-L} option to tell the linker where to find the library.  For
example, if the library is installed in @file{/usr/local/mysql/lib}, use
@code{-L/usr/local/mysql/lib -lmysqlclient -lz} on the link command.

For clients that use MySQL header files, you may need to specify a
@code{-I} option when you compile them (for example,
@code{-I/usr/local/mysql/include}), so the compiler can find the header
files.

To make it simpler to compile MySQL programs on Unix, we have provided the
@command{mysql_config} script for you. @xref{mysql_config, , @command{mysql_config}}.

You can use it to compile a MySQL client as follows:

@example
CFG=/usr/local/mysql/bin/mysql_config
sh -c "gcc -o progname `$CFG --cflags` progname.c `$CFG --libs`"
@end example

The @code{sh -c} is needed to get the shell not to treat the output from
@command{mysql_config} as one word.

@node Threaded clients, libmysqld, Building clients, C
@subsection How to Make a Threaded Client

@cindex clients, threaded
@cindex threaded clients

The client library is almost thread-safe. The biggest problem is
that the subroutines in @file{net.c} that read from sockets are not
interrupt safe.  This was done with the thought that you might want to
have your own alarm that can break a long read to a server.  If you
install interrupt handlers for the @code{SIGPIPE} interrupt,
the socket handling should be thread-safe.

New in 4.0.16: To not abort the program when a connection terminates,
MySQL blocks @code{SIGPIPE} on the first call to
@code{mysql_server_init}(), @code{mysql_init()} or
@code{mysql_connect()}.  If you want to have your own @code{SIGPIPE}
handler, you should first call @code{mysql_server_init()} and then
install your handler. In older versions of MySQL @code{SIGPIPE} was blocked,
but only in the thread safe client library, for every call to
@code{mysql_init()}.

In the older binaries we distribute on our Web site
(@uref{http://www.mysql.com/}), the client libraries are not normally
compiled with the thread-safe option (the Windows binaries are by
default compiled to be thread-safe). Newer binary distributions should
have both a normal and a thread-safe client library.

To get a threaded client where you can interrupt the client from other
threads and set timeouts when talking with the MySQL server, you should
use the @code{-lmysys}, @code{-lmystrings}, and @code{-ldbug} libraries and
the @code{net_serv.o} code that the server uses.

If you don't need interrupts or timeouts, you can just compile a
thread-safe client library @code{(mysqlclient_r)} and use this.  @xref{C,,
MySQL C API}.  In this case, you don't have to worry about the
@code{net_serv.o} object file or the other MySQL libraries.

When using a threaded client and you want to use timeouts and
interrupts, you can make great use of the routines in the
@file{thr_alarm.c} file.  If you are using routines from the
@code{mysys} library, the only thing you must remember is to call
@code{my_init()} first! @xref{C Thread functions}.

All functions except @code{mysql_real_connect()} are by default
thread-safe.  The following notes describe how to compile a thread-safe
client library and use it in a thread-safe manner.  (The notes below for
@code{mysql_real_connect()} actually apply to @code{mysql_connect()} as
well, but because @code{mysql_connect()} is deprecated, you should be
using @code{mysql_real_connect()} anyway.)

To make @code{mysql_real_connect()} thread-safe, you must recompile the
client library with this command:

@example
shell> ./configure --enable-thread-safe-client
@end example

This will create a thread-safe client library @code{libmysqlclient_r}.
(Assuming that your OS has a thread-safe @code{gethostbyname_r()} function.)
This library is thread-safe per connection.  You can let two threads
share the same connection with the following caveats:

@itemize @bullet
@item
Two threads can't send a query to the MySQL server at the same time on
the same connection.  In particular, you have to ensure that between a
@code{mysql_query()} and @code{mysql_store_result()} no other thread is using
the same connection.
@item
Many threads can access different result sets that are retrieved with
@code{mysql_store_result()}.
@item
If you use @code{mysql_use_result}, you have to ensure that no other thread
is using the same connection until the result set is closed.
However, it really is best for threaded clients that share the same
connection to use @code{mysql_store_result()}.
@item
If you want to use multiple threads on the same connection, you must
have a mutex lock around your @code{mysql_query()} and
@code{mysql_store_result()} call combination.  Once
@code{mysql_store_result()} is ready, the lock can be released and other
threads may query the same connection.
@item
If you program with POSIX threads, you can use
@code{pthread_mutex_lock()} and @code{pthread_mutex_unlock()} to
establish and release a mutex lock.
@end itemize

You need to know the following if you have a thread that is calling
MySQL functions which did not create the connection to the
MySQL database:

When you call @code{mysql_init()} or @code{mysql_connect()}, MySQL will
create a thread-specific variable for the thread that is used by the
debug library (among other things).

If you call a MySQL function, before the thread has
called @code{mysql_init()} or @code{mysql_connect()}, the thread will
not have the necessary thread-specific variables in place and you are
likely to end up with a core dump sooner or later.

The get things to work smoothly you have to do the following:

@enumerate
@item
Call @code{my_init()} at the start of your program if it calls
any other MySQL function before calling @code{mysql_real_connect()}.
@item
Call @code{mysql_thread_init()} in the thread handler before calling
any MySQL function.
@item
In the thread, call @code{mysql_thread_end()} before calling
@code{pthread_exit()}.  This will free the memory used by MySQL
thread-specific variables.
@end enumerate

You may get some errors because of undefined symbols when linking your
client with @code{libmysqlclient_r}. In most cases this is because you haven't
included the thread libraries on the link/compile line.

@node libmysqld,  , Threaded clients, C
@subsection libmysqld, the Embedded MySQL Server Library

@cindex libmysqld
@cindex embedded MySQL server library

@menu
* libmysqld overview::          Overview of the Embedded MySQL Server Library
* libmysqld compiling::         Compiling Programs with @code{libmysqld}
* libmysqld restrictions::      Restrictions when using the Embedded MySQL Server
* libmysqld options::           Using Option Files with the Embedded Server
* libmysqld TODO::              Things left to do in Embedded Server (TODO)
* libmysqld example::           A Simple Embedded Server Example
* libmysqld licensing::         Licensing the Embedded Server
@end menu

@node libmysqld overview, libmysqld compiling, libmysqld, libmysqld
@subsubsection Overview of the Embedded MySQL Server Library

The embedded MySQL server library makes it possible to run a
full-featured MySQL server inside a client application.  The
main benefits are increased speed and more simple management for
embedded applications.

The embedded server library is based on the client/server version of MySQL,
which is written in C/C++. Consequently, the embedded server also
is written in C/C++. There is no embedded server available in other
languages.

The API is identical for the embedded MySQL version and the
client/server version.  To change an old threaded application to use the
embedded library, you normally only have to add calls to the following
functions:

@multitable @columnfractions .25 .70
@item @strong{Function} @tab @strong{When to Call}
@item @code{mysql_server_init()} @tab Should be called before any other MySQL function is called, preferably early in the @code{main()} function.
@item @code{mysql_server_end()} @tab Should be called before your program exits.
@item @code{mysql_thread_init()} @tab Should be called in each thread you create that will access MySQL.
@item @code{mysql_thread_end()} @tab Should be called before calling @code{pthread_exit()}
@end multitable

Then you must link your code with @file{libmysqld.a} instead of @file{libmysqlclient.a}.

The @code{mysql_server_@var{xxx}()} functions are also included in
@file{libmysqlclient.a} to allow you to change between the embedded and the
client/server version by just linking your application with the right
library. @xref{mysql_server_init, , @code{mysql_server_init()}}.


@node libmysqld compiling, libmysqld restrictions, libmysqld overview, libmysqld
@subsubsection Compiling Programs with @code{libmysqld}

To get a @code{libmysqld} library you should configure MySQL with the
@code{--with-embedded-server} option.

When you link your program with @code{libmysqld}, you must also include
the system-specific @code{pthread} libraries and some libraries that
the MySQL server uses.  You can get the full list of libraries by executing
@command{mysql_config --libmysqld-libs}.

The correct flags for compiling and linking a threaded program
must be used, even if you do not directly call any thread
functions in your code.

@node libmysqld restrictions, libmysqld options, libmysqld compiling, libmysqld
@subsubsection Restrictions when using the Embedded MySQL Server

The embedded server has the following limitations:

@itemize @bullet
@item
No support for @code{ISAM} tables. (This is mainly done to make the library smaller)
@item
No user-defined functions (UDFs).
@item
No stack trace on core dump.
@item
No internal RAID support. (This is not normally needed as most OS has
nowadays support for big files).
@item
You cannot set this up as a master or a slave (no replication).
@item
You can't connect to an embedded server from an outside process with
sockets or TCP/IP.
@end itemize

Some of these limitations can be changed by editing the @file{mysql_embed.h}
include file and recompiling MySQL.

@node libmysqld options, libmysqld TODO, libmysqld restrictions, libmysqld
@subsubsection Using Option Files with the Embedded Server

@cindex defaults, embedded

The following is the recommended way to use option files to make it easy
to switch between a client/server application and one where MySQL is
embedded. @xref{Option files}.

@itemize @bullet
@item
Put common options in the @code{[server]} section. These will be read by
both MySQL versions.
@item
Put client/server-specific options in the @code{[mysqld]} section.
@item
Put embedded MySQL-specific options in the @code{[embedded]} section.
@item
Put application-specific options in a @code{[ApplicationName_SERVER]}
section.
@end itemize

@node libmysqld TODO, libmysqld example, libmysqld options, libmysqld
@subsubsection Things left to do in Embedded Server (TODO)

@cindex TODO, embedded server

@itemize @bullet
@item
We are going to provide options to leave out some parts of MySQL to make
the library smaller.
@item
There is still a lot of speed optimization to do.
@item
Errors are written to @code{stderr}.  We will add an option to specify a
filename for these.
@item
We have to change @code{InnoDB} to not be so verbose when using in the embedded
version.
@end itemize


@node libmysqld example, libmysqld licensing, libmysqld TODO, libmysqld
@subsubsection A Simple Embedded Server Example

This example program and makefile should work without any
changes on a Linux or FreeBSD system.  For other operating
systems, minor changes will be needed.  This example is
designed to give enough details to understand the problem,
without the clutter that is a necessary part of a real
application.

To try out the example, create an @file{test_libmysqld} directory
at the same level as the mysql-4.0 source directory.  Save
the @file{test_libmysqld.c} source and the @file{GNUmakefile} in the
directory, and run GNU @file{make} from inside the @file{test_libmysqld}
directory.

@file{test_libmysqld.c}
@example
/*
 * A simple example client, using the embedded MySQL server library
 */

#include <mysql.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

MYSQL *db_connect(const char *dbname);
void db_disconnect(MYSQL *db);
void db_do_query(MYSQL *db, const char *query);

const char *server_groups[] = @{
  "test_libmysqld_SERVER", "embedded", "server", NULL
@};

int
main(int argc, char **argv)
@{
  MYSQL *one, *two;

  /* mysql_server_init() must be called before any other mysql
   * functions.
   *
   * You can use mysql_server_init(0, NULL, NULL), and it will
   * initialize the server using groups = @{
   *   "server", "embedded", NULL
   *  @}.
   *
   * In your $HOME/.my.cnf file, you probably want to put:

[test_libmysqld_SERVER]
language = /path/to/source/of/mysql/sql/share/english

   * You could, of course, modify argc and argv before passing
   * them to this function.  Or you could create new ones in any
   * way you like.  But all of the arguments in argv (except for
   * argv[0], which is the program name) should be valid options
   * for the MySQL server.
   *
   * If you link this client against the normal mysqlclient
   * library, this function is just a stub that does nothing.
   */
  mysql_server_init(argc, argv, (char **)server_groups);

  one = db_connect("test");
  two = db_connect(NULL);

  db_do_query(one, "SHOW TABLE STATUS");
  db_do_query(two, "SHOW DATABASES");

  mysql_close(two);
  mysql_close(one);

  /* This must be called after all other mysql functions */
  mysql_server_end();

  exit(EXIT_SUCCESS);
@}

static void
die(MYSQL *db, char *fmt, ...)
@{
  va_list ap;
  va_start(ap, fmt);
  vfprintf(stderr, fmt, ap);
  va_end(ap);
  (void)putc('\n', stderr);
  if (db)
    db_disconnect(db);
  exit(EXIT_FAILURE);
@}

MYSQL *
db_connect(const char *dbname)
@{
  MYSQL *db = mysql_init(NULL);
  if (!db)
    die(db, "mysql_init failed: no memory");
  /*
   * Notice that the client and server use separate group names.
   * This is critical, because the server will not accept the
   * client's options, and vice versa.
   */
  mysql_options(db, MYSQL_READ_DEFAULT_GROUP, "test_libmysqld_CLIENT");
  if (!mysql_real_connect(db, NULL, NULL, NULL, dbname, 0, NULL, 0))
    die(db, "mysql_real_connect failed: %s", mysql_error(db));

  return db;
@}

void
db_disconnect(MYSQL *db)
@{
  mysql_close(db);
@}

void
db_do_query(MYSQL *db, const char *query)
@{
  if (mysql_query(db, query) != 0)
    goto err;

  if (mysql_field_count(db) > 0)
  @{
    MYSQL_RES   *res;
    MYSQL_ROW    row, end_row;
    int num_fields;

    if (!(res = mysql_store_result(db)))
      goto err;
    num_fields = mysql_num_fields(res);
    while ((row = mysql_fetch_row(res)))
    @{
      (void)fputs(">> ", stdout);
      for (end_row = row + num_fields; row < end_row; ++row)
        (void)printf("%s\t", row ? (char*)*row : "NULL");
      (void)fputc('\n', stdout);
    @}
    (void)fputc('\n', stdout);
    mysql_free_result(res);
  @}
  else
    (void)printf("Affected rows: %lld\n", mysql_affected_rows(db));

  return;

err:
  die(db, "db_do_query failed: %s [%s]", mysql_error(db), query);
@}
@end example

@file{GNUmakefile}
@example
# This assumes the MySQL software is installed in /usr/local/mysql
inc      := /usr/local/mysql/include/mysql
lib      := /usr/local/mysql/lib

# If you have not installed the MySQL software yet, try this instead
#inc      := $(HOME)/mysql-4.0/include
#lib      := $(HOME)/mysql-4.0/libmysqld

CC       := gcc
CPPFLAGS := -I$(inc) -D_THREAD_SAFE -D_REENTRANT
CFLAGS   := -g -W -Wall
LDFLAGS  := -static
# You can change -lmysqld to -lmysqlclient to use the
# client/server library
LDLIBS    = -L$(lib) -lmysqld -lz -lm -lcrypt

ifneq (,$(shell grep FreeBSD /COPYRIGHT 2>/dev/null))
# FreeBSD
LDFLAGS += -pthread
else
# Assume Linux
LDLIBS += -lpthread
endif

# This works for simple one-file test programs
sources := $(wildcard *.c)
objects := $(patsubst %c,%o,$(sources))
targets := $(basename $(sources))

all: $(targets)

clean:
        rm -f $(targets) $(objects) *.core
@end example

@node libmysqld licensing,  , libmysqld example, libmysqld
@subsubsection Licensing the Embedded Server

We encourage everyone to promote free software by releasing
code under the GPL or a compatible license.  For those who
are not able to do this, another option is to purchase a
commercial license for the MySQL code from MySQL AB.
For details, please see @uref{http://www.mysql.com/company/legal/licensing/}.


@node PHP, Perl, C, MySQL APIs
@section MySQL PHP API

@cindex PHP API

PHP is a server-side, HTML-embedded scripting language that may be used to
create dynamic Web pages.  It contains support for accessing several
databases, including MySQL.  PHP may be run as a separate program
or compiled as a module for use with the Apache Web server.

The distribution and documentation are available at the PHP Web site
(@uref{http://www.php.net/}).

@menu
* PHP problems::                Common Problems with MySQL and PHP
@end menu

@node PHP problems,  , PHP, PHP
@subsection Common Problems with MySQL and PHP

@itemize @bullet
@item Error: "Maximum Execution Time Exceeded"
This is a PHP limit; go into the @file{php.ini} file and set the maximum
execution time up from 30 seconds to something higher, as needed.
It is also not a bad idea to double the RAM allowed per script to 16MB instead of
8MB.
@item Error: "Fatal error: Call to unsupported or undefined function mysql_connect() in .."
This means that your PHP version isn't compiled with MySQL support.
You can either compile a dynamic MySQL module and load it into PHP or
recompile PHP with built-in MySQL support.  This is described in
detail in the PHP manual.
@item Error: "undefined reference to `uncompress'"
This means that the client library is compiled with support for a compressed
client/server protocol. The fix is to add @code{-lz} last when linking
with @code{-lmysqlclient}.
@end itemize


@node Perl, Cplusplus, PHP, MySQL APIs
@section MySQL Perl API

@cindex APIs, Perl
@cindex Perl API
@cindex @code{DBI} interface
@cindex @code{DBI/DBD} interface


The Perl @code{DBI} module provides a generic interface for database access.
You can write a DBI script that works with many different database engines
without change. To use DBI, you must install the @code{DBI} module, as well
as a DataBase Driver (DBD) module for each type of server you want to access.
For MySQL, this driver is the @code{DBD::mysql} module.

Perl DBI is now the recommended Perl interface. It replaces an older
interface called @code{mysqlperl}, which should be considered obsolete.

Installation instructions for Perl DBI support are given in
@ref{Perl support}.

DBI information is available at the command line, online, or in printed form:

@itemize @bullet
@item
Once you have the @code{DBI} and @code{DBD::mysql} modules installed, you can
get information about them at the command line with the @code{perldoc} command:

@example
shell> perldoc DBI
shell> perldoc DBI::FAQ
shell> perldoc DBD::mysql
@end example

You can also use @code{pod2man}, @code{pod2html}, and so forth to translate
this information into other formats.

@item
For online information about Perl DBI, visit the DBI Web site,
@uref{http://dbi.perl.org/}. That site hosts a general DBI mailing list.
MySQL AB hosts a list specifically about @code{DBD::mysql}; see
@ref{Mailing-list}.

@item
For printed information, the official DBI book is @cite{Programming the Perl
DBI} (Alligator Descartes and Tim Bunce, O'Reilly & Associates, 2000).
Information about the book is available at the DBI Web site,
@uref{http://dbi.perl.org/}.

For information that focuses specifically on using DBI with MySQL, see
@cite{MySQL and Perl for the Web} (Paul DuBois, New Riders, 2001). This
book's Web site is @uref{http://www.kitebird.com/mysql-perl/}.

@end itemize


@node Cplusplus, Python, Perl, MySQL APIs
@section MySQL C++ API

@menu
* Borland C++::                 Borland C++
@end menu


@cindex MySQL++
@cindex C++ APIs

@code{MySQL++} is the MySQL API for C++. More
information can be found at @uref{http://www.mysql.com/products/mysql++/}.


@node Borland C++,  , Cplusplus, Cplusplus
@subsection Borland C++

@cindex Borland C++ compiler

You can compile the MySQL Windows source with Borland C++ 5.02.
(The Windows source includes only projects for Microsoft VC++, for
Borland C++ you have to do the project files yourself.)

One known problem with Borland C++ is that it uses a different structure
alignment than VC++.  This means that you will run into problems if you
try to use the default @code{libmysql.dll} libraries (that was compiled
with VC++) with Borland C++. To avoid this problem, only call
@code{mysql_init()} with @code{NULL} as an argument, not a pre-allocated
@code{MYSQL} structure.


@node Python, Tcl, Cplusplus, MySQL APIs
@section MySQL Python API

@cindex Python API

@code{MySQLdb} provides MySQL support for Python, compliant with the
Python DB API version 2.0. It can be found at
@uref{http://sourceforge.net/projects/mysql-python/}.


@node Tcl, Eiffel, Python, MySQL APIs
@section MySQL Tcl API

@cindex Tcl API

@code{MySQLtcl} is a simple API for accessing a MySQL database server from the Tcl
programming language. It can be found at @uref{http://www.xdobry.de/mysqltcl/}.

@node Eiffel,  , Tcl, MySQL APIs
@section MySQL Eiffel Wrapper

@cindex Eiffel Wrapper
@cindex wrappers, Eiffel

Eiffel MySQL is an interface to the MySQL database server using the Eiffel
programming language, written by Michael Ravits. It can be found at
@uref{http://efsa.sourceforge.net/archive/ravits/mysql.htm}.


@node MySQL Connectors, Error-handling, MySQL APIs, Top
@chapter MySQL Connectors

@cindex Connectors, MySQL
@cindex Connector/ODBC
@cindex Connector/JDBC

This chapter describes MySQL Connectors, drivers that provide connectivity to
the MySQL server for client programs.

@menu
* ODBC Connector::              MySQL ODBC Support
* Java Connector::              MySQL Java Connectivity (JDBC)
@end menu

@node ODBC Connector, Java Connector, MySQL Connectors, MySQL Connectors
@section MySQL ODBC Support

@cindex ODBC
@cindex Windows
@cindex MyODBC
@cindex Connector/ODBC


MySQL provides support for ODBC by means of MySQL Connector/ODBC, the
family of MyODBC drivers.  This is the reference for the Connector/ODBC
product family of MyODBC drivers that provide ODBC 3.5x compliant access
to the MySQL Database System.  It will teach you how to install MyODBC
and how to use it.  You will also information about common programs that
are known to work with MyODBC and answers to some of the most frequently
asked questions about MyODBC.

This reference applies to MyODBC @value{myodbc3_version}.  You can find a
manual for an older version of MyODBC in the binary or source distribution
for that version.

This is a reference to the MySQL ODBC drivers, not a general
ODBC reference.  For more information about ODBC, refer to
@uref{http://www.microsoft.com/data/}.

The application development part of this reference assumes a good working
knowledge of C, general DBMS knowledge, and finally, but not least,
familiarity with MySQL.  For more information about MySQL functionality and
its syntax, refer to @uref{http://dev.mysql.com/doc/}.

If you have questions that are not aswered in this document, please send
a mail message to @email{myodbc@@lists.mysql.com}.

@menu
* MyODBC Introduction::         Introduction to MyODBC
* MyODBC General Information::  General Information About ODBC and MyODBC
* Installing MyODBC::           How to Install MyODBC
* MyODBC Windows binary installation::  Installing MyODBC from a Binary Distribution on Windows
* MyODBC Unix binary installation::  Installing MyODBC from a Binary Distribution on Unix
* MyODBC Windows source installation::  Installing MyODBC from a Source Distribution on Windows
* MyODBC Unix source::          Installing MyODBC from a Source Distribution on Unix
* Development source::          Installing MyODBC from the BitKeeper Development Source Tree
* MyODBC Configuration::        MyODBC Configuration
* Connection::                  MyODBC Connection-Related Issues
* MSAccess::                    MyODBC and Microsoft Access
* MSVBA::                       MyODBC and Microsoft VBA and ASP
* Tools::                       MyODBC and Third-Party ODBC Tools
* Functionality::               MyODBC General Functionality
* Basic MyODBC application steps::  Basic MyODBC Application Steps 
* MyODBC API Reference::        MyODBC API Reference
* MyODBC Data Types::           MyODBC Data Types
* MyODBC Error Codes::          MyODBC Error Codes
* MyODBC With VB::              MyODBC With VB: ADO, DAO and RDO
* MyODBC with .NET::            MyODBC with Microsoft .NET
* MyODBC Credits::              Credits
@end menu

@node MyODBC Introduction, MyODBC General Information, ODBC Connector, ODBC Connector
@subsection Introduction to MyODBC

@menu
* ODBC::                        What is ODBC?
* Connector/ODBC::              What is Connector/ODBC?
* MyODBC 2.50::                 What is MyODBC 2.50?
* MyODBC 3.51::                 What is MyODBC 3.51?
* Where to Get MyODBC::         Where to Get MyODBC
* MyODBC Supported Platforms::  Supported Platforms
* MyODBC Mailing List::         MyODBC Mailing List
* MyODBC Forum ::               MyODBC Forum
* MyODBC bug report::           How to Report MyODBC Problems or Bugs
* MyODBC patch submission::     How to Submit a MyODBC Patch
@end menu

@node ODBC, Connector/ODBC, MyODBC Introduction, MyODBC Introduction
@subsubsection What is ODBC?

ODBC (Open Database Connectivity) provides a way for client programs to
access a wide range of databases or data sources.  ODBC is a standardized
API that allows connections to SQL database servers.  It was developed
according to the specifications of the SQL Access Group and defines a set
of function calls, error codes, and data types that can be used to develop
database-independent applications.  ODBC usually is used when database
independence or simultaneous access to different data sources is required.

For more information about ODBC, refer to
@uref{http://www.microsoft.com/data/}.


@node Connector/ODBC, MyODBC 2.50, ODBC, MyODBC Introduction
@subsubsection What is Connector/ODBC?

Connector/ODBC is the term designating the MySQL AB product family
of MySQL ODBC drivers. These are known as the MyODBC drivers.


@node MyODBC 2.50, MyODBC 3.51, Connector/ODBC, MyODBC Introduction
@subsubsection What is MyODBC 2.50?

MyODBC 2.50 is a 32-bit ODBC driver from MySQL AB that is based on ODBC 2.50
specification level 0 (with level 1 and 2 features). This is one of the most
popular ODBC drivers in the Open Source market, used by many users to access
the MySQL functionality.


@node MyODBC 3.51, Where to Get MyODBC, MyODBC 2.50, MyODBC Introduction
@subsubsection What is MyODBC 3.51?

MyODBC 3.51 is a 32-bit ODBC driver, also known as the MySQL ODBC 3.51
driver.  This version is enhanced compared to the existing MyODBC 2.50
driver.  It has support for ODBC 3.5x specification level 1 (complete core
API + level 2 features) in order to continue to provide all functionality of
ODBC for accessing MySQL.


@node Where to Get MyODBC, MyODBC Supported Platforms, MyODBC 3.51, MyODBC Introduction
@subsubsection Where to Get MyODBC

MySQL AB distributes all its products under the General Public License
(GPL). You can get a copy of the latest version of MyODBC binaries and
sources from the MySQL AB Web site @uref{http://dev.mysql.com/downloads/}.

For more information about MyODBC, visit
@uref{http://www.mysql.com/products/myodbc/}.

For more information about licensing, visit
@uref{http://www.mysql.com/company/legal/licensing/}.


@node MyODBC Supported Platforms, MyODBC Mailing List, Where to Get MyODBC, MyODBC Introduction
@subsubsection Supported Platforms

MyODBC can be used on all major platforms supported by
MySQL, such as:

@itemize @bullet
@item Windows 95, 98, Me, NT, 2000, XP, and 2003
@item All Unix Operating Systems
@itemize @bullet
@item AIX
@item Amiga
@item BSDI
@item DEC
@item FreeBSD
@item HP-UX 10, 11
@item Linux
@item Mac OS X Server
@item Mac OS X
@item NetBSD
@item OpenBSD
@item OS/2
@item SGI Irix
@item Solaris
@item SunOS
@item SCO OpenServer
@item SCO UnixWare
@item Tru64 Unix
@end itemize
@end itemize

If a binary distribution is not available for downloading for a
particular platform, you can build the driver yourself by
downloading the driver sources. You can contribute the binaries to MySQL
by sending a mail message to @email{myodbc@@lists.mysql.com}, so that it
becomes available for other users.


@node MyODBC Mailing List, MyODBC Forum , MyODBC Supported Platforms, MyODBC Introduction
@subsubsection MyODBC Mailing List

MySQL AB provides assistance to the user community by means of its mailing
lists. For MyODBC-related issues, you can get help from experienced
users by using the @email{myodbc@@lists.mysql.com} mailing list.

For information about subscribing to MySQL mailing lists or to browse
list archives, visit @uref{http://lists.mysql.com/}. 

Of particular interest is the ODBC forum in the MySQL Connectors section of the forums.

@node MyODBC Forum , MyODBC bug report, MyODBC Mailing List, MyODBC Introduction
@subsubsection MyODBC Forum

Community support from experienced users is available through the MySQL Forums,
located at @uref{http://forums.mysql.com}.
@node MyODBC bug report, MyODBC patch submission, MyODBC Forum , MyODBC Introduction
@subsubsection How to Report MyODBC Problems or Bugs

@cindex reporting, Connector/ODBC problems
@cindex Connector/ODBC, reporting problems
@cindex reporting, MyODBC problems
@cindex MyODBC, reporting problems
@cindex problems, ODBC

If you encounter difficulties or problems with MyODBC, you should start
by making a log file from the @code{ODBC Manager} (the log you get when
requesting logs from @code{ODBC ADMIN}) and MyODBC. The procedure for doing
this is described in @ref{MyODBC trace}.

Check the MyODBC trace file to find out what could be wrong.
You should be able to determine what statements were issued by searching for
the string @code{>mysql_real_query} in the @file{myodbc.log} file.

You should also try issuing the statements from the @command{mysql} client
program or from @code{admndemo}. This will help you determine whether the
error is in MyODBC or MySQL.

If you find out something is wrong, please only send the relevant rows
(maximum 40 rows) to the @code{myodbc} mailing list.
@xref{Mailing-list}.
Please never send the whole MyODBC or ODBC log file!

If you are unable to find out what's wrong, the last option is to
create an archive in @command{tar} or Zip format that contains a MyODBC trace file,
the ODBC log file, and a @file{README} file that explains the problem.  You can send this
to @uref{ftp://ftp.mysql.com/pub/mysql/upload/}.  Only we at
MySQL AB will have access to the files you upload, and we will
be very discreet with the data.

If you can create a program that also demonstrates the problem, please include
it in the archive as well.

If the program works with some other SQL server, you should include an ODBC log
file where you do exactly the same thing in the other SQL server.

Remember that the more information you can supply to us, the more
likely it is that we can fix the problem.


@node MyODBC patch submission,  , MyODBC bug report, MyODBC Introduction
@subsubsection How to Submit a MyODBC Patch

You can send a patch or suggest a better solution for any existing code
or problems by sending a mail message to @email{myodbc@@lists.mysql.com}.


@node MyODBC General Information, Installing MyODBC, MyODBC Introduction, ODBC Connector
@subsection General Information About ODBC and MyODBC

@menu
* Introduction to ODBC::        Introduction to ODBC
* MyODBC Architecture::         MyODBC Architecture
* Driver Manager::              ODBC Driver Managers
* Types of MySQL ODBC Drivers::  Types of MySQL ODBC Drivers
@end menu


@node Introduction to ODBC, MyODBC Architecture, MyODBC General Information, MyODBC General Information
@subsubsection Introduction to ODBC

Open Database Connectivity (ODBC) is a widely accepted application-programming
interface (API) for database access. It is based on the Call-Level Interface
(CLI) specifications from X/Open and ISO/IEC for database APIs and uses
Structured Query Language (SQL) as its database access language. 

A survey of ODBC functions supported by MyODBC is given at
@ref{MyODBC API Reference}.  For general information about ODBC, see
@uref{http://www.microsoft.com/data/}.


@node MyODBC Architecture, Driver Manager, Introduction to ODBC, MyODBC General Information
@subsubsection MyODBC Architecture

The MyODBC architecture is based on five components, as shown in the
following diagram:

@* @image{Images/myarchitecture,2.65in,2.8in} @*

@table @strong
@item Application:

An application is a program that calls the ODBC API to access the data from
the MySQL server. The Application communicates with the Driver Manager
using the standard ODBC calls.  The Application does not care where the
data is stored, how it is stored, or even how the system is configured to
access the data.  It needs to know only the Data Source Name (DSN).

A number of tasks are common to all applications, no matter how they use ODBC.
These tasks are:
@itemize @bullet
@item Selecting the MySQL server and connecting to it
@item Submitting SQL statements for execution
@item Retrieving results (if any)
@item Processing errors
@item Committing or rolling back the transaction enclosing the SQL statement
@item Disconnecting from the MySQL server
@end itemize

Because most data access work is done with SQL, the primary tasks for
applications that use ODBC are submitting SQL statements and retrieving
any results generated by those statements.

@item Driver manager:

The Driver Manager is a library that manages communication
between application and driver or drivers. It performs the following tasks:

@itemize @bullet
@item Resolves Data Source Names (DSN)
@item Driver loading and unloading
@item Processes ODBC function calls or passes them to the driver
@end itemize

@item MyODBC Driver:

The MyODBC driver is a library that implements the functions in the
ODBC API. It processes ODBC function calls, submits SQL requests to MySQL
server, and returns results back to the application. If necessary, the driver
modifies an application's request so that the request conforms to syntax
supported by the MySQL.

@item ODBC.INI:

@file{ODBC.INI} is the ODBC configuration file that stores the driver
and database information required to connect to the server. It is used by
the Driver Manager to determine which driver to be loaded using the Data
Source Name.  The driver uses this to read connection parameters based on
the DSN specified.  For more information, @ref{MyODBC Configuration}.

@item MySQL Server:

The MySQL server is the source of data. MySQL is:

@itemize @bullet
@item A database management system (DBMS)
@item A relational database management system (RDBMS)
@item Open Source Software
@end itemize

@end table


@node Driver Manager, Types of MySQL ODBC Drivers, MyODBC Architecture, MyODBC General Information
@subsubsection ODBC Driver Managers

An ODBC Driver Manager is a library that manages communication between
the ODBC aware application and driver(s). Its main functionality includes:

@itemize @bullet
@item Resolving Data Source Names (DSN)
@item Driver loading and unloading
@item Processing ODBC function calls or passing them to the driver
@end itemize
	
The following driver managers are commonly used:

@itemize @bullet
@item Microsoft Windows ODBC Driver Manager (@file{odbc32.dll}), @uref{http://www.microsoft.com/data/}
@item unixODBC Driver Manager for Unix (@file{libodbc.so}), @uref{http://www.unixodbc.org}.
@item iODBC ODBC Driver Manager for Unix (@file{libiodbc.so}), @uref{http://www.iodbc.org}
@end itemize

MyODBC 3.51 also is shipped with UnixODBC beginning with version 2.1.2.


@node Types of MySQL ODBC Drivers,  , Driver Manager, MyODBC General Information
@subsubsection Types of MySQL ODBC Drivers

MySQL AB supports two Open Source ODBC drivers for accessing MySQL
functionality through the ODBC API: MyODBC (MyODBC 2.50) and MySQL ODBC
3.51 Driver (MyODBC 3.51).

Note: From this section onward, we refer both the drivers
generically as MyODBC.  Whenever there is a difference, we use the
original names.


@node Installing MyODBC, MyODBC Windows binary installation, MyODBC General Information, ODBC Connector
@subsection How to Install MyODBC

@c TODO: after conversion to DocBook, subsume following installation
@c sections _under_ this one.

MyODBC works on Windows 9x, Me, NT, 2000, XP, and 2003, and on most Unix platforms.

MyODBC is Open Source. You can find the newest
version at @uref{http://dev.mysql.com/downloads/connector/odbc/}.
Please note that the 2.50.x versions are LGPL licensed,
whereas the 3.51.x versions are GPL licensed.

If you have problem with MyODBC and your program also works
with OLEDB, you should try the OLEDB driver.

Normally you need to install MyODBC only on Windows machines.
You need MyODBC for Unix only if you have a program like
ColdFusion that is running on a Unix machine and uses ODBC to connect
for database access.

If you want to install MyODBC on a Unix box, you will also need
an ODBC manager.  MyODBC is known to work with most Unix ODBC managers.

@itemize @bullet
@item
To make a connection to a Unix box from a Windows box with an ODBC
application (one that doesn't support MySQL natively), you must
first install MyODBC on the Windows machine.
@item
The user and Windows machine must have access privileges for the
MySQL server on the Unix machine.  This is set up with the
@code{GRANT} command. @xref{GRANT,,@code{GRANT}}.
@item
You must create an ODBC DSN entry as follows:

@enumerate
@item
Open the Control Panel on the Windows machine.
@item
Double-click the @code{ODBC Data Sources 32-bit} icon.
@item
Click the tab @code{User DSN}.
@item
Click the @code{Add} button.
@item
Select MySQL in the screen @code{Create New Data Source} and click
the @code{Finish} button.
@item
The MySQL Driver default configuration screen will be shown.
@xref{DSN on Windows}.
@end enumerate

@item
Now start your application and select the ODBC driver with the DSN that you
specified in the ODBC administrator.
@end itemize

Notice that other configuration options are shown on the MySQL screen that
you can try if you run into problems (options such as trace, don't prompt
on connect, and so forth).


@c TODO: after conversion to DocBook, subsume next several installation
@c sections inside preceding section.

@node MyODBC Windows binary installation, MyODBC Unix binary installation, Installing MyODBC, ODBC Connector
@subsection Installing MyODBC from a Binary Distribution on Windows

To install MyODBC on Windows, you should download the appropriate
distribution file from @uref{http://dev.mysql.com/downloads/connector/odbc/},
unpack it, and execute the @command{MyODBC-@var{VERSION}.exe} file.

On Windows, you may get the following error when trying to install the
older MyODBC 2.50 driver:

@example
An error occurred while copying C:\WINDOWS\SYSTEM\MFC30.DLL. Restart
Windows and try installing again (before running any applications
which use ODBC)
@end example

The problem is that some other program is using ODBC.  Because of how
Windows is designed, you may not be able in this case to install new
ODBC drivers with Microsoft's ODBC setup program. In most cases, you can
continue by pressing @code{Ignore} to copy the rest of the MyODBC files and
the final installation should still work.  If it doesn't, the solution is
to re-boot your computer in ``safe mode.'' Choose safe mode by pressing F8
just before your machine starts Windows during re-booting, install MyODBC,
and re-boot to normal mode.


@node MyODBC Unix binary installation, MyODBC Windows source installation, MyODBC Windows binary installation, ODBC Connector
@subsection Installing MyODBC from a Binary Distribution on Unix


@menu
* MyODBC Unix RPM installation::  Installing MyODBC from an RPM Distribution
* MyODBC Unix tarball installation::  Installing MyODBC from a Binary Tarball Distribution
@end menu

@node MyODBC Unix RPM installation, MyODBC Unix tarball installation, MyODBC Unix binary installation, MyODBC Unix binary installation
@subsubsection Installing MyODBC from an RPM Distribution

To install or upgrade MyODBC from an RPM distribution on
Linux, simply download the RPM distribution of the latest version
of MyODBC and follow the instructions below.  Use @command{su root}
to become @code{root}, then install the RPM file.

If you are installing for the first time:

@example
shell> su root
shell> rpm -ivh MyODBC-3.51.01.i386-1.rpm
@end example

If the driver already exists, upgrade like this:

@example
shell> su root
shell> rpm -Uvh MyODBC-3.51.01.i386-1.rpm
@end example

If there is any dependancy error for MySQL client library,
@code{libmysqlclient}, simply ignore it by supplying the @code{--nodeps}
option, and then make sure the MySQL client shared library is in the path
or set through @code{LD_LIBRARY_PATH}.

This installs the driver libraries and related documents to
@file{/usr/local/lib} and @file{/usr/share/doc/MyODBC} respectively. Now
proceed onto @ref{DSN on Unix, configuring the DSN on Unix}.

To @strong{uninstall} the driver, become @code{root} and execute
an @command{rpm} command:

@example
shell> su root
shell> rpm -e MyODBC
@end example


@node MyODBC Unix tarball installation,  , MyODBC Unix RPM installation, MyODBC Unix binary installation
@subsubsection Installing MyODBC from a Binary Tarball Distribution

To install the driver from a tarball distribution (@file{.tar.gz} file),
download the latest version of the driver for your operating system and
follow these steps:

@example
shell> su root
shell> gunzip MyODBC-3.51.01-i686-pc-linux.tar.gz
shell> tar xvf MyODBC-3.51.01-i686-pc-linux.tar
shell> cd MyODBC-3.51.01-i686-pc-linux
@end example

Read the installation instructions in the @file{INSTALL-BINARY} file
and execute these commands.

@example
shell> cp libmyodbc* /usr/local/lib
shell> cp odbc.ini /usr/local/etc
shell> export ODBCINI=/usr/local/etc/odbc.ini
@end example

Then proceed on to @ref{DSN on Unix,how to configure the DSN on
unix} to configure the DSN for MyODBC. For more information,
refer to the @file{INSTALL-BINARY} file that comes with your distribution.


@node MyODBC Windows source installation, MyODBC Unix source, MyODBC Unix binary installation, ODBC Connector
@subsection Installing MyODBC from a Source Distribution on Windows

@menu
* MyODBC Windows source requirements::  Requirements
* MyODBC 3.51 Windows building::  Building MyODBC 3.51
* MyODBC 3.51 Windows testing::  Testing
* MyODBC 2.50 Windows building::  Building MyODBC 2.50
@end menu

@node MyODBC Windows source requirements, MyODBC 3.51 Windows building, MyODBC Windows source installation, MyODBC Windows source installation
@subsubsection Requirements

@itemize @bullet
@item
MDAC, Microsoft Data Access SDK from
@uref{http://www.microsoft.com/data/}.
@item
MySQL client libraries and include files from MySQL 4.0.0 or higher.
(Preferably MySQL 4.0.16 or higher).
This is required because MyODBC uses new calls and structures that
exist only starting from this version of the library.
To get the client libraries and include files, visit
@uref{http://dev.mysql.com/downloads/}.
@end itemize

@node MyODBC 3.51 Windows building, MyODBC 3.51 Windows testing, MyODBC Windows source requirements, MyODBC Windows source installation
@subsubsection Building MyODBC 3.51

MyODBC 3.51 source distributions include @file{Makefiles} that
uses @command{nmake}. In the distribution, you can find @file{Makefile}
for building the release version and @file{Makefile_debug} for building
debugging versions of the driver libraries and DLLs.

To build the driver, use this procedure:

@enumerate

@item
Download and extract the sources to a folder, then change location into that
folder.  The following command assumes the folder is named @file{myodbc3-src}:

@example
C:\> cd myodbc3-src
@end example

@item
Edit @file{Makefile} to specify the correct path for the MySQL client
libraries and headers files. Then use use the following commands to build
and install the release version:

@example
C:\> nmake -f Makefile
C:\> nmake -f Makefile install
@end example

@command{nmake -f Makefile} builds the release version of the driver
and places the binaries in subdirectory called @file{Release}.

@command{nmake -f Makefile install} installs (copies) the driver DLLs
and libraries(@file{myodbc3.dll}, @file{myodbc3.lib}) to your system
directory.

@item
To build the debug version, use @file{Makefile_Debug} rather than
@file{Makefile}, as shown below:

@example
C:\> nmake -f Makefile_debug
C:\> nmake -f Makefile_debug install
@end example

@item
You can clean and rebuild the driver by using:

@example
C:\> nmake -f Makefile clean
C:\> nmake -f Makefile install
@end example

@end enumerate

@strong{Note}:

@itemize @bullet

@item
Make sure to specify the correct MySQL client libraries and header files
path in the Makefiles (set the @code{MYSQL_LIB_PATH} and
@code{MYSQL_INCLUDE_PATH} variables). The default header file path is
assumed to be @file{C:\mysql\include}. The default library path is assumed
to be @file{C:\mysql\lib\opt} for release DLLs and @file{C:\mysql\lib\debug}
for debug versions.

@item
For the complete usage of @command{nmake}, visit
@uref{http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcepb40/htm/_wcepb_nmake_tool.asp}.

@item
If you are using the BitKeeper tree for compiling, All
Windows-specific @file{Makefiles} are named as @file{Win_Makefile*}.

@end itemize


@node MyODBC 3.51 Windows testing, MyODBC 2.50 Windows building, MyODBC 3.51 Windows building, MyODBC Windows source installation
@subsubsection Testing

After the driver libraries are copied/installed to the system directory, you
can test whether the libraries are properly built by using the samples
provided in the @file{samples} subdirectory:

@example
C:\> cd samples
C:\> nmake -f Makefile all
@end example


@node MyODBC 2.50 Windows building,  , MyODBC 3.51 Windows testing, MyODBC Windows source installation
@subsubsection Building MyODBC 2.50

The MyODBC 2.50 source distribution includes VC workspace files. You can
build the driver using these files (@file{.dsp} and @file{.dsw}) directly
by loading them from Microsoft Visual Studio 6.0 or higher.


@node MyODBC Unix source, Development source, MyODBC Windows source installation, ODBC Connector
@subsection Installing MyODBC from a Source Distribution on Unix

@menu
* MyODBC Unix requirements::    Requirements
* MyODBC Unix configure options::  Typical @command{configure} Options
* MyODBC Unix thread-safe::     Thread-Safe Client
* MyODBC Unix library options::  Shared or Static Options
* MyODBC Unix debugging options::  Enabling Debugging Information
* MyODBC Unix documentation options::  Enabling the Documentation
* MyODBC Unix building::        Building and Compilation
* MyODBC Unix shared libraries::  Building Shared Libraries
* MyODBC Unix installing::      Installing Driver Libraries
* MyODBC Unix testing::         Testing MyODBC on Unix
* MyODBC Mac OS X::             Mac OS X Notes
* MyODBC HP-UX::                HP-UX Notes
* MyODBC AIX::                  AIX Notes:
@end menu

@node MyODBC Unix requirements, MyODBC Unix configure options, MyODBC Unix source, MyODBC Unix source
@subsubsection Requirements

@itemize @bullet
@item
MySQL client libraries and include files from MySQL 4.0.0 or higher.
(Preferably MySQL 4.0.16 or higher).
This is required because MyODBC uses new calls and structures that
exist only starting from this version of the library.
To get the client libraries and include files, visit
@uref{http://dev.mysql.com/downloads/}.

@c TODO: I can't understand the following weird concatenation of sentences.
@c Does it mean "The libmysqlclient MySQL library must be configured
@c with the --enable-thread-safe-client option and installed as a
@c shared library"?

@item
The MySQL library must be configured with the
@code{--enable-thread-safe-client} option.
libmysqlclient installed as a shared library.

@item
One of the following Unix ODBC driver managers must be installed:

@itemize @minus
@item
@code{iodbc} 3.0 or later (@uref{http://www.iodbc.org})
@item
@code{unixodbc} Alpha 3 or later (@uref{http://www.unixodbc.org})
@end itemize

@item
If using a @strong{character set} that isn't compiled into the MySQL
client library (the defaults are: latin1 big5 czech euc_kr gb2312 gbk sjis
tis620 ujis) then you need to install the mysql character definitions
from the @file{charsets} directory into @var{SHAREDIR} (by default,
@file{/usr/local/mysql/share/mysql/charsets}). These should already be
into place if you have installed the MySQL server on the same machine.

@end itemize

Once you have all the required files, unpack the source files to a
separate directory and follow the instructions as given below:

@node MyODBC Unix configure options, MyODBC Unix thread-safe, MyODBC Unix requirements, MyODBC Unix source
@subsubsection Typical @command{configure} Options

The @command{configure} script gives you a great deal of control over how
you configure your MyODBC build. Typically you do this using options on the
@command{configure} command line. You can also affect @command{configure}
using certain environment variables. For a list of options and environment
variables supported by @command{configure}, run this command:

@example
shell> ./configure --help
@end example

Some of the more commonly used @command{configure} options are described here:

@enumerate
@item
To compile MyODBC, you need to supply the MySQL client include and library
files path using the @code{--with-mysql-path=@var{DIR}} option, where
@var{DIR} is the directory where the MySQL is installed.

MySQL compile options can be determined by running
@code{@var{DIR}/bin/mysql_config}.

@item
Supply the standard header and library files path for your
ODBC Driver Manager(@code{iodbc} or @code{unixobc}).

@itemize @bullet

@item
If you are using @code{iodbc} and @code{iodbc} is not installed in its default
location (@file{/usr/local}), you might have to use
the @code{--with-iodbc=@var{DIR}} option, where
@var{DIR} is the directory where iodbc is installed.

If the iodbc headers do not reside in @file{@var{DIR}/include},
you can use the @code{--with-iodbc-includes=@var{INCDIR}} option to
specify their location.

The applies to libraries. If they are not in @file{@var{DIR}/lib},
you can use the @code{--with-iodbc-libs=@var{LIBDIR}} option.

@item
If you are using @code{unixODBC}, use the @code{--with-unixODBC=@var{DIR}}
option (case sensitive) to make @command{configure} look for @code{unixODBC}
instead of @code{iodbc} by default, @var{DIR} is the directory where
unixODBC is installed.

If the unixODBC headers and libraries aren't located in
@file{@var{DIR}/include} and @file{@var{DIR}/lib}, use
the @code{--with-unixODBC-includes=@var{INCDIR}}
and @code{--with-unixODBC-libs=@var{LIBDIR}} options.

@end itemize

@item
You might want to specify an installation prefix other than
@file{/usr/local}.  For example, to install the MyODBC drivers in
@file{/usr/local/odbc/lib}, use the
@code{--prefix=/usr/local/odbc} option.

@end enumerate

The final configuration command will look something like this:

@example
shell> ./configure --prefix=/usr/local \
           --with-iodbc=/usr/local \
           --with-mysql-path=/usr/local/mysql
@end example


@node MyODBC Unix thread-safe, MyODBC Unix library options, MyODBC Unix configure options, MyODBC Unix source
@subsubsection Thread-Safe Client

In order to link the driver with MySQL thread safe client libraries
@file{libmysqlclient_r.so} or @file{libmysqlclient_r.a}, you must specify the
following @command{configure} option:

@example
--enable-thread-safe
@end example

and can be disabled(default) using

@example
--disable-thread-safe
@end example

This option enables the building of driver thread-safe library
@file{libmyodbc3_r.so} from by linking with mysql thread-safe client library
@file{libmysqlclient_r.so} (The extensions are OS dependent).

In case while configuring with thread-safe option, and gotten into a
configure error; then look at the @file{config.log} and see if it is due
to the lack of thread-libraries in the system; and supply one with LIBS
options i.e.

@example
LIBS="-lpthread" ./configure ..
@end example


@node MyODBC Unix library options, MyODBC Unix debugging options, MyODBC Unix thread-safe, MyODBC Unix source
@subsubsection Shared or Static Options

You can enable or disable the shared and static versions using these options:

@example
--enable-shared[=yes/no]
--disable-shared
--enable-static[=yes/no]
--disable-static
@end example


@node MyODBC Unix debugging options, MyODBC Unix documentation options, MyODBC Unix library options, MyODBC Unix source
@subsubsection Enabling Debugging Information

By default, all the binary distributions are built as non-debugging versions
(configured with @code{--without-debug}).

To enable debugging information,
build the driver from source distribution and use the
@code{--with-debug}) when you run @command{configure}.


@node MyODBC Unix documentation options, MyODBC Unix building, MyODBC Unix debugging options, MyODBC Unix source
@subsubsection Enabling the Documentation

This option is available only for @code{BK} clone trees; not for
normal source distributions.

By default, the driver is built with (@code{--without-docs}); And
in case if you want the documentation to be taken care in the normal
build, then configure with:
@example
 --with-docs
@end example


@node MyODBC Unix building, MyODBC Unix shared libraries, MyODBC Unix documentation options, MyODBC Unix source
@subsubsection Building and Compilation

To build the driver libraries, you have to just execute @command{make},
which takes care of everything.

@example
shell> make
@end example

If any errors occur, correct them and continue
the build process. If you aren't able to build, then send a detailed email
to @email{myodbc@@lists.mysql.com} for further assistance.


@node MyODBC Unix shared libraries, MyODBC Unix installing, MyODBC Unix building, MyODBC Unix source
@subsubsection Building Shared Libraries

On most platforms, MySQL doesn't build or support @file{.so} (shared)
client libraries by default, because building with shared libraries has
caused us problems in the past.

In cases like this, you have to download the MySQL distribution
and configure it with these options:

@example
--without-server --enable-shared
@end example

To build shared driver libraries, you must specify the
@code{--enable-shared} option for @command{configure}.  By default,
@command{configure} does not enable this option.

If you have configured with the @code{--disable-shared} option, you can
build the @file{.so} file from the static libraries using the following
commands:

@example
shell> cd MyODBC-3.51.01
shell> make
shell> cd driver
shell> CC=/usr/bin/gcc \
       $CC -bundle -flat_namespace -undefined error \
           -o .libs/libmyodbc3-3.51.01.so \
           catalog.o connect.o cursor.o dll.o error.o execute.o \
           handle.o info.o misc.o myodbc3.o options.o prepare.o \
           results.o transact.o utility.o \
           -L/usr/local/mysql/lib/mysql/ \
           -L/usr/local/iodbc/lib/ \
           -lz -lc -lmysqlclient -liodbcinst
@end example

Make sure to change @code{-liodbcinst} to @code{-lodbcinst} if you are
using unixODBC instead of iODBC, and configure the library paths
accordingly.

This builds and places the @file{libmyodbc3-3.51.01.so} file in the
@file{.libs} directory.  Copy this file to MyODBC library directory
(@file{/usr/local/lib} (or the @file{lib} directory under the installation
directory that you supplied with the @code{--prefix}).

@example
shell> cd .libs
shell> cp libmyodbc3-3.51.01.so /usr/local/lib
shell> cd /usr/local/lib
shell> ln -s libmyodbc3-3.51.01.so libmyodbc3.so
@end example

To build the thread-safe driver library:

@example
shell> CC=/usr/bin/gcc \
       $CC -bundle -flat_namespace -undefined error
	      -o .libs/libmyodbc3_r-3.51.01.so
	      catalog.o connect.o cursor.o dll.o error.o execute.o
	      handle.o info.o misc.o myodbc3.o options.o prepare.o
	      results.o transact.o utility.o
	      -L/usr/local/mysql/lib/mysql/
	      -L/usr/local/iodbc/lib/
	      -lz -lc -lmysqlclient_r -liodbcinst
@end example


@node MyODBC Unix installing, MyODBC Unix testing, MyODBC Unix shared libraries, MyODBC Unix source
@subsubsection Installing Driver Libraries

To install the driver libraries, execute the following command:

@example
shell> make install
@end example

That command installs one of the following sets of libraries:

For MyODBC 3.51:

@itemize @bullet
@item
@file{libmyodbc3.so}
@item
@file{libmyodbc3-3.51.01.so}, where 3.51.01 is the version of the driver
@item
@file{libmyodbc3.a}
@end itemize

For thread-safe MyODBC 3.51:

@itemize @bullet
@item
@file{libmyodbc3_r.so}
@item
@file{libmyodbc3-3_r.51.01.so}
@item
@file{libmyodbc3_r.a}
@end itemize

For MyODBC 2.5.0:

@itemize @bullet
@item
@file{libmyodbc.so}
@item
@file{libmyodbc-2.50.39.so}, where 2.50.39 is the version of the driver
@item
@file{libmyodbc.a}
@end itemize

For more information on build process, refer to the @file{INSTALL} file
that comes with the source distribution. Note that if you are trying to
use the @command{make} from Sun, you may end up with errors. On
the other hand, GNU @command{gmake} should work fine on all
platforms.


@node MyODBC Unix testing, MyODBC Mac OS X, MyODBC Unix installing, MyODBC Unix source
@subsubsection Testing MyODBC on Unix

To run the basic samples provided in the distribution with the libraries
that you built, just execute:
@example
shell> make test
@end example

Make sure the DSN 'myodbc3' is configured first in @file{odbc.ini} and
environment variable @code{ODBCINI} is pointing to the right
@file{odbc.ini} file; and MySQL server is running. You can find a sample
@file{odbc.ini} with the driver distribution.

You can even modify the @file{samples/run-samples} script to pass the desired
DSN, UID, and PASSWORD values as the command line arguments to each sample.


@node MyODBC Mac OS X, MyODBC HP-UX, MyODBC Unix testing, MyODBC Unix source
@subsubsection Mac OS X Notes

To build the driver on Mac OS X (Darwin), make use of the
following @command{configure} example:

@example
shell> ./configure --prefix=/usr/local
			       --with-unixODBC=/usr/local
			       --with-mysql-path=/usr/local/mysql
			       --disable-shared
			       --enable-gui=no
			       --host=powerpc-apple
@end example

The command assumes that the unixODBC and MySQL are installed in the default
locations. If not, configure accordingly.

On Mac OS X, @code{--enable-shared} builds @file{.dylib} files by default.
You can build @file{.so} files like this:

@example
shell> make
shell> cd driver
shell> CC=/usr/bin/gcc \
       $CC -bundle -flat_namespace -undefined error
           -o .libs/libmyodbc3-3.51.01.so *.o
           -L/usr/local/mysql/lib/
           -L/usr/local/iodbc/lib
           -liodbcinst -lmysqlclient -lz -lc
@end example

To build the thread-safe driver library:

@example
shell> CC=/usr/bin/gcc \
       $CC -bundle -flat_namespace -undefined error
       -o .libs/libmyodbc3-3.51.01.so *.o
       -L/usr/local/mysql/lib/
       -L/usr/local/iodbc/lib
       -liodbcinst -lmysqlclienti_r -lz -lc -lpthread
@end example

Make sure to change the @code{-liodbcinst} to @code{-lodbcinst} in case of
using unixODBC instead of iODBC and configure the libraries path
accordingly.

In Apple's version of GCC, both @command{cc} and @command{gcc} are actually
symbolic links to @command{gcc3}.

Now copy this library to the @file{$prefix/lib} directory and symlink to
@file{libmyodbc3.so}.

You can cross-check the output shared-library properties using this command:

@example
shell> otool -LD .libs/libmyodbc3-3.51.01.so
@end example


@node MyODBC HP-UX, MyODBC AIX, MyODBC Mac OS X, MyODBC Unix source
@subsubsection HP-UX Notes

To build the driver on HP-UX 10.x or 11.x, make use of
the following @command{configure} example:

If using @command{cc}:

@example
shell> CC="cc" \
       CFLAGS="+z" \
       LDFLAGS="-Wl,+b:-Wl,+s" \
       ./configure --prefix=/usr/local
			       --with-unixodbc=/usr/local
			       --with-mysql-path=/usr/local/mysql/lib/mysql
			       --enable-shared
			       --enable-thread-safe
@end example


If using @command{gcc}:

@example
shell> CC="gcc" \
       LDFLAGS="-Wl,+b:-Wl,+s" \
       ./configure --prefix=/usr/local
			       --with-unixodbc=/usr/local
			       --with-mysql-path=/usr/local/mysql
			       --enable-shared
			       --enable-thread-safe
@end example

Once the driver is built, cross-check its attributes using
@command{chatr .libs/libmyodbc3.sl}
to see whether or not you need to have the MySQL client
libraries path using the @code{SHLIB_PATH} environment variable. For
static versions, ignore all shared-library options and run @command{configure}
with the @code{--disable-shared} option.


@node MyODBC AIX,  , MyODBC HP-UX, MyODBC Unix source
@subsubsection AIX Notes:

To build the driver on AIX, make use of
the following @command{configure} example:

@example
shell> ./configure --prefix=/usr/local
			       --with-unixodbc=/usr/local
			       --with-mysql-path=/usr/local/mysql
			       --disable-shared
			       --enable-thread-safe
@end example

@strong{NOTE:} For more information about how to build and set up the
static and shared libraries across the different platforms refer to '
@uref{http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html,
Using static and shared libraries across platforms}'.


@node Development source, MyODBC Configuration, MyODBC Unix source, ODBC Connector
@subsection Installing MyODBC from the BitKeeper Development Source Tree

Note: You should read this section only if you are interested in helping us
test our new code.

To obtain our most recent development source tree, use these instructions:

@enumerate
@item
Download BitKeeper from
@uref{http://www.bitmover.com/cgi-bin/download.cgi}.  You will need
BitKeeper 3.0 or newer to access our repository.
@item
Follow the instructions to install it.
@item
After BitKeeper is installed, first go to the directory you
want to work from, and then use this command if you want to clone
the MyODBC 3.51 branch:

@example
shell> bk clone bk://mysql.bkbits.net/myodbc3 myodbc-3.51
@end example

In the preceding example, the source tree will be set up in the
@file{myodbc-3.51/} or by default @file{myodbc3/} subdirectory of
your current directory. If you are behind the firewall and can only
initiate HTTP connections, you can also use BitKeeper via
HTTP. If you are required to use a proxy server, simply set the
environment variable @code{http_proxy} to point to your proxy:

@example
shell> export http_proxy="http://your.proxy.server:8080/"
@end example

Now, simply replace the @code{bk://} with @code{http://} when doing a
clone. Example:

@example
shell> bk clone http://mysql.bkbits.net/myodbc3 myodbc-3.51
@end example

The initial download of the source tree may take a while, depending on the
speed of your connection; be patient.
@item
You will need GNU @code{autoconf 2.52} (or newer), @code{automake 1.4},
@code{libtool 1.4}, and @code{m4} to run the next set of commands.

@example
shell> cd myodbc-3.51
shell> bk -r edit
shell> aclocal; autoheader; autoconf;  automake;
shell> ./configure  # Add your favorite options here
shell> make
@end example

For more information on how to build, refer to @file{INSTALL} file located
in the same directory. On Windows, make use of Windows
Makefiles @file{WIN-Makefile} and @file{WIN-Makefile_debug} in
building the driver, for more information, see
@ref{MyODBC Windows source installation}.
@item
When the build is done, run @command{make install} to install the
MyODBC 3.51 driver on your system.
@item
If you have gotten to the @command{make} stage and the distribution does
not compile, please report it to @email{myodbc@@lists.mysql.com}.
@item
After the initial @command{bk clone} operation to get the source tree, you
should run @command{bk pull} periodically to get the updates.
@item
You can examine the change history for the tree with all the diffs by using
@command{bk sccstool}.  If you see some funny diffs or code that you have a
question about, do not hesitate to send e-mail to
@email{myodbc@@lists.mysql.com}.

Also, if you think you have a better idea on how to do something, send an
e-mail to the same address with a patch. @command{bk diffs} will produce a
patch for you after you have made changes to the source. If you do not
have the time to code your idea, just send a description.
@item
BitKeeper has a nice help utility that you can access via
@command{bk helptool}.
@end enumerate

You can also browse changesets, comments and source code online by
browsing to @uref{http://mysql.bkbits.net:8080/myodbc3}.


@node MyODBC Configuration, Connection, Development source, ODBC Connector
@subsection MyODBC Configuration

This section describes how to configure MyODBC, including
DSN creation and the different arguments that the driver takes as
an input arguments in the connection string. It also describes how
to create an ODBC trace file.

@menu
* Data Source Name::            What is a Data Source Name?
* DSN on Windows::              Configuring a MyODBC DSN on Windows
* DSN on Unix::                 Configuring a MyODBC DSN on Unix
* Connection parameters::       Connection Parameters
* Without DSN::                 Connecting Without a Predefined DSN
* Remote connection::           Establishing a Remote Connection to System A from System B
* MyODBC trace::                Getting an ODBC Trace File
* MyODBC Tested Applications::  Applications Tested with MyODBC
* Programs Known to Work With MyODBC::  Programs Known to Work With MyODBC
@end menu

@node Data Source Name, DSN on Windows, MyODBC Configuration, MyODBC Configuration
@subsubsection What is a Data Source Name?

A "data source" is a place where data comes from.  The data source must
have a persistent identifier, the Data Source Name. Using the Data Source
Name, MySQL can access initialization information. With the initialization
information, MySQL knows where to access the database and what settings
to use when the access starts.

In effect, the data source is the @emph{path} to the data. In different
contexts this might mean different things, but typically it identifies
a running MySQL server (for example via a network address or service
name), plus the default database for that server at connection time, plus
necessary connection information such as the port. The MySQL drivers (and,
on Windows systems, the ODBC Driver Manager) will use the data source for
connecting. An administrative utility called the Microsoft ODBC Data Source
Administrator may be useful for this purpose.

There are two places where the initialization information might be: in
the Windows registry (on a Windows system), or in a DSN file (on any system).

If the information is in the Windows registry, it is called a "Machine
data source". It might be a "User data source", in which case only one
user can see it. Or it might be a "System data source" in which case
it is accessible to all users on the computer, or indeed to all users
connected to the computer, if the users are connected by Microsoft Windows
NT services. When you run the ODBC Data Administration program, you will
have a choice whether to use "User" or "System" -- there are separate tabs.

If the information is in a DSN file, it is called a "File data source". This
is a text file. Its advantages are: (a) it is an option for any kind of
computer, not just a computer with a Windows operating system; (b) its
contents can be transmitted or copied relatively easily.


@node DSN on Windows, DSN on Unix, Data Source Name, MyODBC Configuration
@subsubsection Configuring a MyODBC DSN on Windows

To add and configure a new MyODBC data source on Windows, use the
@code{ODBC Data Source Administrator}. The @code{ODBC Administrator}
updates your data source connection information. As you
add data sources, the @code{ODBC Administrator} updates the
registry information for you.

To open the @code{ODBC Administrator} from the Control Panel:

@enumerate

@item
Click @code{Start}, point to @code{Settings}, and then click @code{Control
Panel}.

@item
On computers running Microsoft Windows 2000 or newer, double-click
@code{Administrative Tools}, and then double-click @code{Data Sources
(ODBC)}. On computers running older versions of Windows, double-click
@code{32-bit ODBC} or @code{ODBC}.

@* @image{Images/mydsn-icon} @*

The @code{ODBC Data Source Administrator} dialog box appears, as
shown here:

@* @image{Images/mydsn} @*

Click @code{Help} for detailed information about each tab of the @code{ODBC
Data Source Administrator} dialog box.

@end enumerate

To add a data source on Windows:

@enumerate

@item
Open the @code{ODBC Data Source Administrator}.

@item
In the @code{ODBC Data Source Administrator} dialog box, click
@code{Add}. The @code{Create New Data Source} dialog box appears.

@item
Select @code{MySQL ODBC 3.51 Driver}, and then click @code{Finish}.
The @code{MySQL ODBC 3.51 Driver - DSN Configuration} dialog box appears,
as shown here:

@* @image{Images/mydsn-setup} @*

@item
In the @code{Data Source Name} box, enter the name of the data
source you want to access. It can be any valid name that you choose.

@item
In the @code{Description} box, enter the description needed for the DSN.

@item
For @code{Host or Server Name (or IP)} box, enter the name of the MySQL
server host that you want to access. By default, it is @code{localhost}.

@item
In the @code{Database Name} box, enter the name of the MySQL database
that you want to use as the default database.

@item
In the @code{User} box, enter your MySQL username (your database
user ID).

@item
In the @code{Password} box, enter your password.

@item
In the @code{Port} box, enter the port number if it is not the default (3306).

@item
In the @code{SQL Command} box, you can enter an optional SQL statement that
you want to issue automatically after the connection has been established.

The final dialog looks like this:

@* @image{Images/mydsn-example} @*

Click @code{OK} to add this data source.

@end enumerate

@strong{Note}: Upon clicking @code{OK}, the @code{Data Sources} dialog
box appears, and the @code{ODBC Administrator} updates the registry
information. The username and connect string that you entered become the
default connection values for this data source when you connect to it.

You can also test whether your settings are suitable for connecting to the
server using the button @code{Test Data Source}. This feature is available
only for the MyODBC 3.51 driver. A successful test results in the following
window:

@* @image{Images/mydsn-test-success} @*

A failed test results in an error:

@* @image{Images/mydsn-test-fail} @*

The DSN configuration dialog also has an @code{Options} button. If you
select it, the following options dialog appears displaying that control
driver behavior. Refer to @ref{Connection parameters} for information
about the meaning of these options.

@* @image{Images/mydsn-options} @*

@strong{Note}: The options listed under @code{Driver Trace Options} are
disabled (grayed out) unless you are using the debugging version of the
driver DLL.

To modify a data source on Windows:

@enumerate

@item
Open the @code{ODBC Data Source Administrator}. Click the appropriate
DSN tab.
@item
Select the MySQL data source that you want to modify and then click
@code{Configure}.  The @code{MySQL ODBC 3.51 Driver - DSN Configuration}
dialog box appears.
@item
Modify the applicable data source fields, and then click @code{OK}.

@end enumerate

When you have finished modifying the information in this dialog box, the
@code{ODBC Administrator} updates the registry information.


@node DSN on Unix, Connection parameters, DSN on Windows, MyODBC Configuration
@subsubsection Configuring a MyODBC DSN on Unix

On @code{Unix}, you configure DSN entries directly in the
@file{odbc.ini} file. Here is a typical @file{odbc.ini} file that configures
@code{myodbc} and @code{myodbc3} as the DSN names for MyODBC 2.50 and MyODBC
3.51, respectively:

@example
;
;  odbc.ini configuration for MyODBC and MyODBC 3.51 drivers
;

[ODBC Data Sources]
myodbc      = MyODBC 2.50 Driver DSN
myodbc3     = MyODBC 3.51 Driver DSN

[myodbc]
Driver       = /usr/local/lib/libmyodbc.so
Description  = MyODBC 2.50 Driver DSN
SERVER       = localhost
PORT         =
USER         = root
Password     =
Database     = test
OPTION       = 3
SOCKET       =

[myodbc3]
Driver       = /usr/local/lib/libmyodbc3.so
Description  = MyODBC 3.51 Driver DSN
SERVER       = localhost
PORT         =
USER         = root
Password     =
Database     = test
OPTION       = 3
SOCKET       =

[Default]
Driver       = /usr/local/lib/libmyodbc3.so
Description  = MyODBC 3.51 Driver DSN
SERVER       = localhost
PORT         =
USER         = root
Password     =
Database     = test
OPTION       = 3
SOCKET       =
@end example


Refer to the @ref{Connection parameters}, for the list of
connection parameters that can be supplied.

@strong{Note}: If you are using unixODBC, you can use the following tools
in order to set up the DSN:

@itemize @bullet
@item
ODBCConfig GUI tool(@uref{http://www.unixodbc.org/config.html, HOWTO: ODBCConfig})
@item
odbcinst
@end itemize

In some cases when using unixODBC, you might get this error:

@example
Data source name not found and no default driver specified
@end example

If this happens, make sure the @code{ODBCINI} and @code{ODBCSYSINI}
environment variables are pointing to the right @file{odbc.ini} file.  For
example, if your @file{odbc.ini} file is located in @file{/usr/local/etc},
set the environment variables like this:

@example
export ODBCINI=/usr/local/etc/odbc.ini
export ODBCSYSINI=/usr/local/etc
@end example


@node Connection parameters, Without DSN, DSN on Unix, MyODBC Configuration
@subsubsection Connection Parameters

You can specify the following parameters for MyODBC in the @code{[Data
Source Name]} section of an @code{ODBC.INI} file or through the
@code{InConnectionString} argument in the @code{SQLDriverConnect()} call.

@multitable @columnfractions .15 .20 .65
@item @strong{Parameter} @tab @strong{Default Value} @tab @strong{Comment}
@item @code{user} @tab ODBC (on Windows) @tab The username used to connect to MySQL.
@item @code{server} @tab @code{localhost} @tab The hostname of the MySQL server.
@item @code{database} @tab @tab The default database.
@item @code{option} @tab 0 @tab Options that specify how MyODBC should work. See below.
@item @code{port} @tab 3306 @tab The TCP/IP port to use if @code{server} is not @code{localhost}.
@item @code{stmt} @tab @tab A statement to execute when connecting to MySQL.
@item @code{password} @tab @tab The password for the @code{user} account on @code{server}.
@item @code{socket} @tab @tab The Unix socket file or Windows named pipe to connect to if @code{server} is @code{localhost}.
@end multitable

The @code{option} argument is used to tell MyODBC that the client isn't 100%
ODBC compliant. On Windows, you normally select options by toggling the
checkboxes in the connection screen, but you can also select them in the
@code{option} argument. The following options are listed in the order
in which they appear in the MyODBC connect screen:

@multitable @columnfractions .10 .90
@item @strong{Value} @tab @strong{Description}
@item 1 @tab The client can't handle that MyODBC returns the real width of a column.
@item 2 @tab  The client can't handle that MySQL returns the true value of affected rows.  If this flag is set, MySQL returns ``found rows'' instead.  You must have MySQL 3.21.14 or newer to get this to work.
@item 4 @tab Make a debug log in @file{c:\myodbc.log}.  This is the same as putting @code{MYSQL_DEBUG=d:t:O,c::\myodbc.log} in @file{AUTOEXEC.BAT}. (On Unix, the file is @file{/tmp/myodbc.log}.)
@item 8  @tab Don't set any packet limit for results and parameters.
@item 16 @tab Don't prompt for questions even if driver would like to prompt.
@item 32 @tab Enable or disable the dynamic cursor support. (Not allowed in MyODBC 2.50.)
@item 64 @tab Ignore use of database name in @code{db_name.tbl_name.col_name}.
@item 128 @tab Force use of ODBC manager cursors (experimental).
@item 256 @tab Disable the use of extended fetch (experimental).
@item 512 @tab Pad @code{CHAR} columns to full column length.
@item 1024 @tab @code{SQLDescribeCol()} will return fully qualified column names.
@item 2048 @tab Use the compressed client/server protocol.
@item 4096 @tab Tell server to ignore space after function name and before @samp{(} (needed by PowerBuilder).  This will make all function names keywords.
@item 8192 @tab Connect with named pipes to a @command{mysqld} server running on NT.
@item 16384 @tab Change @code{LONGLONG} columns to @code{INT} columns (some applications can't handle @code{LONGLONG}).
@item 32768 @tab Return 'user' as @code{Table_qualifier} and @code{Table_owner} from @code{SQLTables} (experimental).
@item 65536 @tab Read parameters from the @code{[client]} and @code{[odbc]} groups from @file{my.cnf}.
@item 131072 @tab Add some extra safety checks (should not be needed but...).
@item 262144 @tab Disable transactions.
@item 524288 @tab Enable query logging to @file{c:\myodbc.sql}(@file{/tmp/myodbc.sql}) file. (Enabled only in debug mode.)
@item 1048576 @tab Do not cache the results locally in the driver,
instead read from server (@code{mysql_use_result()}). This works only for
forward-only cursors. This option is very important in dealing
with large tables when you don't want the driver to cache the
entire result set.
@item 2097152 @tab Force the use of @code{Forward-only} cursor type. In case
of applications setting the default static/dynamic cursor type, and one
wants driver to use non-cache result sets, then this option will ensure
the forward-only cursor behavior.
@end multitable

To select multiple options, add together their values.  For example,
setting @code{option} to 12 (4+8) gives you debugging without packet limits.

The default @file{myodbc3.dll} is compiled for optimal performance.  If you
want to to debug MyODBC 3.51 (for example, to enable tracing), you should
instead use @file{myodbc3d.dll}.  To install this file, copy
@file{myodbc3d.dll} over the installed @file{myodbc3.dll} file. Make sure to
revert back to the release version of the driver DLL once you are done with
the debugging because the debug version may cause performance issues.

For MyODBC 2.50, @file{myodbc.dll} and @file{myodbcd.dll} are used instead.

The following table shows some recommended @code{option} values for
various configurations:

@multitable @columnfractions .7 .3
@item @strong{Configuration} @tab @strong{Option Value}
@item Microsoft Access        @tab 3
@item Microsoft Visual Basic  @tab 3
@item Large tables with too many rows @tab 2049
@item Driver trace generation (Debug mode) @tab	4
@item Query log generation (Debug mode)	@tab 524288
@item Generate driver trace as well as query log (Debug mode) @tab 524292
@item Large tables with no-cache results  @tab 3145731
@end multitable


@node Without DSN, Remote connection, Connection parameters, MyODBC Configuration
@subsubsection Connecting Without a Predefined DSN

Yes.  You can connect to the MySQL server using SQLDriverConnect, by
specifying the @code{DRIVER} name field. Here are the connection strings
for MyODBC using DSN-Less connection:

@strong{For MyODBC 2.50:}

@example
ConnectionString = "DRIVER=@{MySQL@};\
                    SERVER=localhost;\
                    DATABASE=test;\
                    USER=venu;\
                    PASSWORD=venu;\
                    OPTION=3;"
@end example

@strong{For MyODBC 3.51:}

@example
ConnectionString = "DRIVER=@{MySQL ODBC 3.51 Driver@};\
                    SERVER=localhost;\
                    DATABASE=test;\
                    USER=venu;\
                    PASSWORD=venu;\
                    OPTION=3;"
@end example

If your programming language converts backslash followed by whitespace to
a space, it is preferable to specify the connection string as a single long
string, or to use a concatenation of multiple strings that does not add
spaces in between.  For example:

@example
ConnectionString = "DRIVER=@{MySQL ODBC 3.51 Driver@};"
                    "SERVER=localhost;"
                    "DATABASE=test;"
                    "USER=venu;"
                    "PASSWORD=venu;"
                    "OPTION=3;"
@end example

Refer to the @ref{Connection parameters}, for the list of connection parameters that can be supplied.


@node Remote connection, MyODBC trace, Without DSN, MyODBC Configuration
@subsubsection Establishing a Remote Connection to System A from System B

If you want to connect to system A from system B with a username
and password of @code{myuser} and @code{mypassword}, here is a simple
procedure.

On system A, follow these steps:

@enumerate

@item
Start the MySQL server.

@item
Use
@code{GRANT} to set up an account with a username of @code{myuser} that can
connect from system B using a password of @code{myuser}:

@example
GRANT ALL ON *.* to 'myuser'@@'B' IDENTIFIED BY 'mypassword';
@end example

@item
The @code{GRANT} statement grants all privileges to user @file{myuser} for
connecting
from system B using the password @code{mypassword}. To execute this statement,
you should be either @code{root} on system A (or another user who has
appropriate privileges). For more information about MySQL privileges, refer to
@ref{User Account Management}.

@end enumerate

On system B, follow these steps:

@enumerate

@item
Configure a MyODBC DSN using the following connection parameters:

@example
DSN            = remote_test
SERVER or HOST = A (or IP address of system A)
DATABASE       = test (The default database or an appropriate one)
USER           = myuser
PASSWORD       = mypassword
@end example

To set up a DSN-less connection, refer to @ref{Without DSN}.

@item
Check whether you are able to access system A from system B by
using ping or other means. If you are not able to reach system A, check
your network or Internet connections or contact your system administrator.

@item
Now, try to connect using @code{DSN=remote_test}. If it fails, trace the
MyODBC log, and take the further steps based on the error message
from the log. If you need further assistance, send a detailed mail message
to @email{myodbc@@lists.mysql.com}.

@end enumerate

You can also find a simple HOWTO at
@uref{http://www.phphelp.com/tutorial/using-myodbc-to-connect-to-a-remote-database.html}.


@node MyODBC trace, MyODBC Tested Applications, Remote connection, MyODBC Configuration
@subsubsection Getting an ODBC Trace File

If you encounter difficulties or problems with MyODBC, you should start
by making a log file from the @code{ODBC Manager} (the log you get when
requesting logs from @code{ODBC ADMIN}) and MyODBC.

To get an ODBC trace through Driver Manager, do the following:

@itemize @bullet
@item
Open ODBC Data source administrator:

@enumerate

@item
Click @code{Start}, point to @code{Settings}, and then click @code{Control
Panel}.

@item
On computers running Microsoft Windows 2000, XP, or 2003, double-click
@code{Administrative Tools}, and then double-click @code{Data Sources
(ODBC)}, as shown below.

@* @image{Images/mydsn-icon} @*

On computers running an earlier version of Microsoft Windows, double-click
@code{32-bit ODBC} or @code{ODBC} in the Control Panel.

@item
The @code{ODBC Data Source Administrator} dialog box appears, as shown
below:

@* @image{Images/mydsn} @*

@item
Click Help for detailed information about each tab of the ODBC Data
Source Administrator dialog box.

@end enumerate

@item
Enable the trace option.
The procedure for this differs for Windows and Unix.

To enable the trace option on Windows:

@enumerate
@item
The @code{Tracing} tab of the ODBC Data Source Administrator
dialog box enables you to configure the way ODBC function calls are
traced.

@item
When you activate tracing from the @code{Tracing} tab, the
@code{Driver Manager} will log all ODBC function calls for all
subsequently run applications.

@item
ODBC function calls from applications running before tracing is
activated are not logged. ODBC function calls are recorded in a
log file you specify.

@item
Tracing ceases only after you click @code{Stop Tracing Now}. Remember that
while tracing is on, the log file continues to increase in size and
that tracing affects the performance of all your ODBC applications.

@* @image{Images/mydsn-trace} @*

@end enumerate

To enable the trace option on Unix:

@enumerate
@item
On Unix, you need to explicitly set the @code{Trace} option in the
@file{ODBC.INI} file.

Set the tracing @code{ON} or @code{OFF} by using @code{TraceFile} and
@code{Trace} parameters in @file{odbc.ini} as shown below:

@example
TraceFile  = /tmp/odbc.trace
Trace      = 1
@end example

@code{TraceFile} specifies the name and full path of the trace file
and @code{Trace} is set to @code{ON} or @code{OFF}. You can also use
@code{1} or @code{YES} for @code{ON} and @code{0} or @code{NO} for
@code{OFF}.  If you are using @command{ODBCConfig} from @code{unixODBC},
then follow the instructions for tracing @code{unixODBC} calls at
@uref{http://www.unixodbc.org/config.html,HOWTO-ODBCConfig}.

@end enumerate

To generate a MyODBC log, do the following:

@enumerate

@item
Ensure that you are using the driver debug DLL (that is, @file{myodbc3d.dll}
and not @file{myodbc3.dll} for MyODBC 3.51, and @file{myodbcd.dll} for
MyODBC 2.50).

The easiest way to do this is to get @file{myodbc3d.dll} (or
@file{myodbcd.dll}) from the MyODBC 3.51 distribution and copy it over
the @file{myodbc3.dll} (or @file{myodbc.dll}), which is probably in your
@file{C:\windows\system32} or @file{C:\winnt\system32} directory. Note
that you probably want to restore the old @file{myodbc.dll} file when you
have finished testing, as this is a lot faster than @file{myodbc3d.dll}
(or @file{myodbcd.dll}), so do keep a backup copy of original DLLs.

@item
Enable the @code{Trace MyODBC} option flag in the MyODBC connect/configure
screen. The log will be written to file @file{C:\myodbc.log}.  If the trace
option is not remembered when you are going back to the above screen, it
means that you are not using the @file{myodbcd.dll} driver (see above). On
Linux or if you are using DSN-Less connection, then you need to supply
@code{OPTION=4} in the connection string.

@item
Start your application and try to get it to fail.  Then check the MyODBC
trace file to find out what could be wrong.

If you find out something is wrong, please send a mail message to
@email{myodbc@@lists.mysql.com} (or to @email{support@@mysql.com}
if you have a support contract from MySQL AB) with a brief description of
the problem, with the following additional information:

@itemize @bullet
@item MyODBC version
@item ODBC Driver Manager type and version
@item MySQL server version
@item ODBC trace from Driver Manager
@item MyODBC log file from MyODBC driver
@item Simple reproducible sample
@end itemize

@end enumerate

Remember that the more information you can supply to us,
the more likely it is that we can fix the problem!

Also, before posting the bug, check the MyODBC mailing list archive at
@uref{http://lists.mysql.com/}.

@end itemize


@node MyODBC Tested Applications, Programs Known to Work With MyODBC, MyODBC trace, MyODBC Configuration
@subsubsection Applications Tested with MyODBC

MyODBC has been tested with the following applications:

@itemize @bullet
@item
MS Access 95, 97, 2000, and 2002
@item
C++-Builder, Borland Builder 4
@item
Centura Team Developer (formerly Gupta SQL/Windows)
@item
ColdFusion (on Solaris and NT with service pack 5),
@uref{http://www.njwtech.net/addons/coldfusion/mysql.html, How-to:
MySQL and Coldfusion}.
@uref{http://www.macromedia.com/v1/handlers/index.cfm?ID=11328&Method=Full&PageCall=/support/index.cfm,
Troubleshooting Data Sources and Database Connectivity for UnixPlatforms}.
@item Crystal Reports
@item DataJunction
@item Delphi
@item ERwin
@item MS Excel
@item iHTML
@item FileMaker Pro
@item FoxPro
@item Notes 4.5/4.6
@item MS Visio Enterprise 2000
@item Vision
@item Visual Objects
@item Visual Interdev
@item SBSS
@item Perl DBD-ODBC
@item Paradox
@item Powerbuilder
@item Powerdesigner 32-bit
@item MS Visual C++
@item Visual Basic
@item ODBC.NET through CSharp(C#), VB and C++
@item
Data Architect(@uref{http://thekompany.com/products/dataarchitect/})
@item
SQLExpress for Xbase++(@uref{http://www.SQLExpress.net})
@item
Open Office (@uref{http://www.openoffice.org})
@uref{http://dba.openoffice.org/proposals/MySQL_OOo.html, How-to: MySQL
+ OpenOffice}.
@uref{http://www.unixodbc.org/doc/OOoMySQL.pdf, How-to: OpenOffice + MyODBC + unixODBC}.
@item
Star Office (@uref{http://wwws.sun.com/software/star/staroffice/6.0/index.html})
@item
G2-ODBC bridge (@uref{http://www.gensym.com})
@item
Sambar Server (@uref{http://www.sambarserver.info})
@uref{http://www.sambarserver.info/article.php?sid=66, How-to: MyODBC + SambarServer + MySQL}.
@end itemize

If you know of any other applications that work with MyODBC, please send
mail to @email{myodbc@@lists.mysql.com} about them.


@node Programs Known to Work With MyODBC,  , MyODBC Tested Applications, MyODBC Configuration
@subsubsection Programs Known to Work With MyODBC

Most programs should work with MyODBC, but for each of those listed
here, we have tested it ourselves or received confirmation from some user
that it works. Many of the descriptions provide workarounds for problems
that you might encounter.

@table @asis
@item @strong{Program}
@strong{Comment}
@cindex Access program

@item Access
To make Access work:
@itemize @bullet
@item
If you are using Access 2000, you should get and install the newest (version
2.6 or higher) Microsoft MDAC (@code{Microsoft Data Access Components}) from
@uref{http://www.microsoft.com/data/}.  This will fix a bug in Access that
when you export data to MySQL, the table and column names aren't specified.
Another way to work around this bug is to upgrade to MyODBC 2.50.33 and
MySQL 3.23.x, which together provide a workaround for the problem.

You should also get and apply the Microsoft Jet 4.0 Service Pack 5 (SP5)
which can be found at
@uref{http://support.microsoft.com/default.aspx?scid=kb;EN-US;q239114}.
This will fix some cases where columns are marked as @code{#DELETED#}
in Access.

Note: If you are using MySQL 3.22, you must to apply the
MDAC patch and use MyODBC 2.50.32 or 2.50.34 and up to work around
this problem.
@item
For all versions of Access, you should enable the MyODBC @code{Return
matching rows} option. For Access 2.0, you should additionally enable
the @code{Simulate ODBC 1.0} option.
@item
You should have a timestamp in all tables that you want to be able to update.
For maximum portability, don't use a length specification in the column
declaration.  That is, use @code{TIMESTAMP}, not @code{TIMESTAMP(@var{n})},
@var{n} < 14.
@item
You should have a primary key in the table. If not, new or updated rows
may show up as @code{#DELETED#}.
@item
Use only @code{DOUBLE} float fields. Access fails when comparing with
single floats.  The symptom usually is that new or updated rows may show
up as @code{#DELETED#} or that you can't find or update rows.
@item
If you are using MyODBC to link to a table that has a @code{BIGINT}
column, the results will be displayed as @code{#DELETED}. The
work around solution is:

@itemize @bullet
@item
Have one more dummy column with @code{TIMESTAMP} as the data type.
@item
Select the @code{Change BIGINT columns to INT} option in the connection
dialog in ODBC DSN Administrator.
@item
Delete the table link from Access and re-create it.
@end itemize

Old records still will display as @code{#DELETED#}, but newly
added/updated records will be displayed properly.
@item
If you still get the error @code{Another user has changed your data} after
adding a @code{TIMESTAMP} column, the following trick may help you:

Don't use a @code{table} data sheet view. Instead, create a form with the
fields you want, and use that @code{form} data sheet view.  You should
set the @code{DefaultValue} property for the @code{TIMESTAMP} column to
@code{NOW()}.  It may be a good idea to hide the @code{TIMESTAMP} column
from view so your users are not confused.
@item
In some cases, Access may generate illegal SQL statements that
MySQL can't understand. You can fix this by selecting
@code{"Query|SQLSpecific|Pass-Through"} from the Access menu.
@item
On NT, Access will report @code{BLOB} columns as @code{OLE OBJECTS}. If
you want to have @code{MEMO} columns instead, you should change @code{BLOB}
columns to @code{TEXT} with @code{ALTER TABLE}.
@item
Access can't always handle @code{DATE} columns properly. If you have a problem
with these, change the columns to @code{DATETIME}.
@item
If you have in Access a column defined as @code{BYTE}, Access will try
to export this as @code{TINYINT} instead of @code{TINYINT UNSIGNED}.
This will give you problems if you have values larger than 127 in the column.
@end itemize

@item ADO
@cindex ADO program
When you are coding with the ADO API and MyODBC, you need to
pay attention to some default properties that aren't supported by the
MySQL server.  For example, using the @code{CursorLocation Property}
as @code{adUseServer} will return a result of @minus{}1 for the
@code{RecordCount Property}.  To have the right value, you need to set
this property to @code{adUseClient}, as shown in the VB code here:

@example
Dim myconn As New ADODB.Connection
Dim myrs As New Recordset
Dim mySQL As String
Dim myrows As Long

myconn.Open "DSN=MyODBCsample"
mySQL = "SELECT * from user"
myrs.Source = mySQL
Set myrs.ActiveConnection = myconn
myrs.CursorLocation = adUseClient
myrs.Open
myrows = myrs.RecordCount

myrs.Close
myconn.Close
@end example

Another workaround is to use a @code{SELECT COUNT(*)} statement
for a similar query to get the correct row count.

@item Active server pages (ASP)
You should select the @code{Return matching rows} option.

@item BDE applications
To get these to work, you should select the
@code{Don't optimize column widths} and @code{Return matching rows} options.

@item Borland Builder 4
@cindex Borland Builder 4 program
When you start a query, you can use the @code{Active} property or the
@code{Open} method.  Note that @code{Active} will start by automatically
issuing a @code{SELECT * FROM ...} query. That may not be a good thing if
your tables are large.

@item ColdFusion (On Unix)
@cindex ColdFusion program
The following information is taken from the ColdFusion documentation:

Use the following information to configure ColdFusion Server for Linux
to use the unixODBC driver with MyODBC for MySQL data
sources.  Allaire has verified that MyODBC 2.50.26
works with MySQL 3.22.27 and ColdFusion for Linux. (Any
newer version should also work.) You can download MyODBC at
@uref{http://dev.mysql.com/downloads/connector/odbc/}.

ColdFusion Version 4.5.1 allows you to us the ColdFusion Administrator
to add the MySQL data source. However, the driver is not
included with ColdFusion Version 4.5.1. Before the MySQL driver
will appear in the ODBC datasources drop-down list, you must build and
copy the MyODBC driver to
@file{/opt/coldfusion/lib/libmyodbc.so}.

The Contrib directory contains the program @file{mydsn-@var{xxx}.zip} which allows
you to build and remove the DSN registry file for the MyODBC driver
on Coldfusion applications.

@item DataJunction
@cindex DataJunction
You have to change it to output @code{VARCHAR} rather than @code{ENUM}, as
it exports the latter in a manner that causes MySQL problems.

@item Excel
@cindex Excel
Works. A few tips:
@itemize @bullet
@item
If you have problems with dates, try to select them as strings using the
@code{CONCAT()} function. For example:
@example
SELECT CONCAT(rise_time), CONCAT(set_time)
    FROM sunrise_sunset;
@end example
Values retrieved as strings this way should be correctly recognized
as time values by Excel97.

The purpose of @code{CONCAT()} in this example is to fool ODBC into thinking
the column is of ``string type.'' Without the @code{CONCAT()}, ODBC knows the
column is of time type, and Excel does not understand that.

Note that this is a bug in Excel, because it automatically converts a
string to a time. This would be great if the source was a text file, but
is unfortunate when the source is an ODBC connection that reports
exact types for each column.
@end itemize

@item Word
@cindex Word program

To retrieve data from MySQL to Word/Excel documents, you need to
use the MyODBC driver and the Add-in Microsoft Query help.

For example, create a database with a table containing two columns of text:

@itemize @bullet
@item
Insert rows using the @command{mysql} client command-line tool.
@item
Create a DSN file using the ODBC manager, for example, @file{my} for the
database that was just created.
@item
Open the Word application.
@item
Create a blank new document.
@item
In the @code{Database} tool bar, press the @code{Insert Database} button.
@item
Press the @code{Get Data} button.
@item
At the right hand of the @code{Get Data} screen, press the @code{Ms Query}
button.
@item
In @code{Ms Query}, create a new data source using the @file{my} DSN file.
@item
Select the new query.
@item
Select the columns that you want.
@item
Make a filter if you want.
@item
Make a Sort if you want.
@item
Select @code{Return Data to Microsoft Word}.
@item
Click @code{Finish}.
@item
Click @code{Insert Data} and select the records.
@item
Click @code{OK} and you see the rows in your Word document.
@end itemize

@item odbcadmin
@cindex odbcadmin program
Test program for ODBC.

@item Delphi
@cindex Delphi program
You must use BDE Version 3.2 or newer.  Select the @code{Don't optimize column width}
option when connecting to MySQL.

Also, here is some potentially useful Delphi code that sets up both an
ODBC entry and a BDE entry for MyODBC. The BDE entry requires a BDE
Alias Editor that is free at a Delphi Super Page near
you. (Thanks to Bryan Brunton @email{bryan@@flesherfab.com} for this):

@example
fReg:= TRegistry.Create;
  fReg.OpenKey('\Software\ODBC\ODBC.INI\DocumentsFab', True);
  fReg.WriteString('Database', 'Documents');
  fReg.WriteString('Description', ' ');
  fReg.WriteString('Driver', 'C:\WINNT\System32\myodbc.dll');
  fReg.WriteString('Flag', '1');
  fReg.WriteString('Password', '');
  fReg.WriteString('Port', ' ');
  fReg.WriteString('Server', 'xmark');
  fReg.WriteString('User', 'winuser');
  fReg.OpenKey('\Software\ODBC\ODBC.INI\ODBC Data Sources', True);
  fReg.WriteString('DocumentsFab', 'MySQL');
  fReg.CloseKey;
  fReg.Free;

  Memo1.Lines.Add('DATABASE NAME=');
  Memo1.Lines.Add('USER NAME=');
  Memo1.Lines.Add('ODBC DSN=DocumentsFab');
  Memo1.Lines.Add('OPEN MODE=READ/WRITE');
  Memo1.Lines.Add('BATCH COUNT=200');
  Memo1.Lines.Add('LANGDRIVER=');
  Memo1.Lines.Add('MAX ROWS=-1');
  Memo1.Lines.Add('SCHEMA CACHE DIR=');
  Memo1.Lines.Add('SCHEMA CACHE SIZE=8');
  Memo1.Lines.Add('SCHEMA CACHE TIME=-1');
  Memo1.Lines.Add('SQLPASSTHRU MODE=SHARED AUTOCOMMIT');
  Memo1.Lines.Add('SQLQRYMODE=');
  Memo1.Lines.Add('ENABLE SCHEMA CACHE=FALSE');
  Memo1.Lines.Add('ENABLE BCD=FALSE');
  Memo1.Lines.Add('ROWSET SIZE=20');
  Memo1.Lines.Add('BLOBS TO CACHE=64');
  Memo1.Lines.Add('BLOB SIZE=32');

  AliasEditor.Add('DocumentsFab','MySQL',Memo1.Lines);
@end example

@item C++ Builder
@cindex C++ Builder
Tested with BDE Version 3.0. The only known problem is that when the table
schema changes, query fields are not updated. BDE, however, does not seem
to recognize primary keys, only the index named @code{PRIMARY}, though this
has not been a problem.

@item Vision
You should select the @code{Return matching rows} option.

@item Visual Basic
@cindex Visual Basic
To be able to update a table, you must define a primary key for the table.

Visual Basic with ADO can't handle big integers. This means that some queries
like @code{SHOW PROCESSLIST} will not work properly.  The fix is to use
@code{OPTION=16384} in the ODBC connect string or to select
the @code{Change BIGINT columns to INT} option in the MyODBC connect
screen.  You may also want to select the @code{Return matching rows} option.

@item VisualInterDev
If you have a @code{BIGINT} in your result, you may get the error
@code{[Microsoft][ODBC Driver Manager] Driver does not support this parameter}
Try selecting the @code{Change BIGINT
columns to INT} option in the MyODBC connect screen.

@item Visual Objects
You should select the @code{Don't optimize column widths} option.

@item MS Visio Enterprise 2000
We made database model diagram by connecting from MS Vision Enterprise 
2000 to MySQL via MyODBC (2.50.37 or greater) and using Visio's reverse 
engineer function to retrieve information about the DB (Visio shows all 
the column definitions, primary keys, Indexes and so on). Also we tested 
by designing new tables in Visio and exported them to MySQL via MyODBC.

@end table

@c TODO: after conversion to DocBook, wrap next several "chapters"
@c inside a parent "MyODBC Frequently Asked Questions" element.

@node Connection, MSAccess, MyODBC Configuration, ODBC Connector
@subsection MyODBC Connection-Related Issues

This section answers MyODBC connection-related questions.

@menu
* Setup-error::                 While Configuring a MyODBC DSN, a @code{Could Not Load Translator or Setup Library} Error Occurs
* Access denied error::         While Connecting, an @code{Access denied} Error Occurs
* Connection pool::             INFO: About ODBC Connection Pooling
@end menu

@node Setup-error, Access denied error, Connection, Connection
@subsubsection While Configuring a MyODBC DSN, a @code{Could Not Load Translator or Setup Library} Error Occurs

For more information, refer to
@uref{http://support.microsoft.com/default.aspx?scid=kb;EN-US;q260558,MS KnowledgeBase
Article(Q260558)}. Also, make sure you have the latest valid
@file{ctl3d32.dll} in your system directory.


@node Access denied error, Connection pool, Setup-error, Connection
@subsubsection While Connecting, an @code{Access denied} Error Occurs

Refer to @ref{Access denied}.


@node Connection pool,  , Access denied error, Connection
@subsubsection INFO: About ODBC Connection Pooling

Refer to this document about connection pooling:
@uref{http://support.microsoft.com/default.aspx?scid=kb;EN-US;q169470}.


@node MSAccess, MSVBA, Connection, ODBC Connector
@subsection MyODBC and Microsoft Access


This section of the document answers questions related to MyODBC
with Microsoft Access.

@menu
* MSAccess Setup::              How to Set Up Microsoft Access to Work with MySQL using MyODBC?
* Export of Data::              How to Export a Table or Query from Access to MySQL?
* Import of Data::              How to Import or Link MySQL Database Tables to Access?
* Linked Tables::               The Structure or Location of a Linked Table has been Changed. Can I See Those Changes Locally in Linked Tables?
* DELETED problem::             When I Insert or Update a Record in Linked Tables, I Get @code{#DELETED#}
* Write conflict::              How Do I Handle Write Conflicts or Row Location Errors?
* Access97 Export::             Whenever I Export a Table from Access 97, a Strange Syntax Error Occurs
* Modified error::              Access Returns @code{Another user has modified the record that you have modified} While Editing Records
* Trapping ODBC Errors::        How to Trap ODBC Login Error Messages in Access?
* Optimize Access::             How Do I Optimize Access for Performance with MyODBC?
* Access-Long Tables::          I Have Very Long Tables. What is the Best Configuration for MyODBC to Access These Tables?
* Query-Timeout::               How to Set the QueryTimeout Value for ODBC Connections?
* MySQL tools with Access::     INFO: Tools to Export/Import from/to Access to/from MySQL
@end menu


@node MSAccess Setup, Export of Data, MSAccess, MSAccess
@subsubsection How to Set Up Microsoft Access to Work with MySQL using MyODBC?


The following must be done on your client PC in order to make Microsoft
Access work with MyODBC.

@enumerate

@item
If you are using Access 2000, you should get and install the newest (version
2.6 or higher) Microsoft MDAC (@code{Microsoft Data Access Components}) from
@uref{http://www.microsoft.com/data/}.  This will fix a bug in Access that
when you export data to MySQL, the table and column names aren't specified.
Another way to work around this bug is to upgrade to MyODBC 2.50.33 and
MySQL 3.23.x, which together provide a workaround for the problem.

You should also get and apply the Microsoft Jet 4.0 Service Pack 5 (SP5)
which can be found at
@uref{http://support.microsoft.com/default.aspx?scid=kb;EN-US;q239114}.
This will fix some cases where columns are marked as @code{#DELETED#}
in Access.

Note: If you are using MySQL 3.22, you must to apply the
MDAC patch and use MyODBC 2.50.32 or 2.50.34 and up to work around
this problem.
@item
Install the latest version of MySQL from @uref{http://dev.mysql.com/downloads/}.
@item
Install the latest version of MyODBC 3.51 or 2.50 from
@uref{http://dev.mysql.com/downloads/connector/odbc/}.
@item
For all Access versions, you should enable the @code{Return matching rows}
option.
@item
Now start working with Access as the front-end for MySQL Server through MyODBC.

@end enumerate



@node Export of Data, Import of Data, MSAccess Setup, MSAccess
@subsubsection How to Export a Table or Query from Access to MySQL?


You cannot export a table or query to MySQL unless you have installed
MyODBC.

To export a table from Access to MySQL, follow these instructions:

@enumerate

@item
When you open an Access database or an Access project, a Database window
will appear.  It displays shortcuts for creating new database objects and
opening existing objects.

@* @image{Images/myaccess} @*

@item
Click the name of the @code{table} or @code{query} you want to export,
and then in the @code{File} menu, select @code{Export}.

@item
In the @code{Export Object Type @var{Object name} To} dialog box, in the
@code{Save As Type} box, select @code{ODBC Databases ()} as shown here:

@* @image{Images/myaccess-odbc} @*

@item
In the @code{Export} dialog box, enter a name for the file (or use the
suggested name), and then select @code{OK}.

@item
The Select Data Source dialog box is displayed; it lists the defined data
sources for any ODBC drivers installed on your computer.  Click either the
File Data Source or Machine Data Source tab, and then double-click the
MyODBC or MyODBC 3.51 data source that you want to export to. To define
a new data source for MyODBC, please @ref{DSN on Windows}.

@end enumerate

Microsoft Access connects to the MySQL Server through this data source
and exports new tables and or data.


@node Import of Data, Linked Tables, Export of Data, MSAccess
@subsubsection How to Import or Link MySQL Database Tables to Access?

You cannot export a table or query to MySQL database unless you have installed
the MyODBC.

@strong{To import or link a table(s) from MySQL to Access, follow the instructions:}

@enumerate

@item
Open a database, or switch to the Database window for the open database.
@item
To import tables, on the @code{File} menu, point to @code{Get External Data},
and then click @code{Import}.
To link tables, on the File menu, point to @code{Get External Data}, and
then click @code{Link Tables}.
@item
In the @code{Import} (or @code{Link}) dialog box, in the Files Of Type
box, select @code{ODBC Databases ()}.
The Select Data Source dialog box lists the defined data sources The Select Data
Source dialog box is displayed; it lists the defined data sources for any ODBC
drivers installed on your computer.
Click either the File Data Source or Machine Data Source tab, and then double-click
the MyODBC or MyODBC 3.51 data source that you want to export to. To
define a new data source for the MyODBC or MyODBC 3.51 driver, please
@ref{DSN on Windows}.
@item
If the ODBC data source that you selected requires you to log on, enter your login
ID and password (additional information might also be required), and then click
@code{OK}.
@item
Microsoft Access connects to the MySQL server through @code{ODBC data source }
and displays the list of tables that you can @code{import} or @code{link}.
@item
Click each table that you want to @code{import} or @code{link}, and then click
@code{OK}. If you're linking a table and it doesn't have an index that uniquely
identifies each record, then Microsoft Access displays a list of the fields in
the linked table. Click a field or a combination of fields that will uniquely
identify each record, and then click @code{OK}.

@end enumerate



@node Linked Tables, DELETED problem, Import of Data, MSAccess
@subsubsection The Structure or Location of a Linked Table has been Changed. Can I See Those Changes Locally in Linked Tables?


Yes. Use the following procedure to view or to refresh links when the
structure or location of a linked table has changed. The Linked Table Manager
lists the paths to all currently linked tables.

@strong{To wiew or refresh links}:

@enumerate

@item
Open the database that contains links to tables.
@item
On the @code{Tools} menu, point to @code{Add-ins}, and then click @code{Linked Table Manager}.
@item
Select the check box for the tables whose links you want to refresh.
@item
Click OK to refresh the links.

@end enumerate

Microsoft Access confirms a successful refresh or, if the table wasn't
found, displays the @code{Select New Location of} <table name> dialog box
in which you can specify its the table's new location.If several selected
tables have moved to the new location that you specify, the Linked Table
Manager searches that location for all selected tables, and updates all
links in one step.

@strong{To vhange the path for a set of linked tables}:

@enumerate

@item
Open the database that contains links to tables.
@item
On the @code{Tools} menu, point to @code{Add-ins}, and then click @code{Linked Table Manager}.
@item
Select the @code{Always Prompt For A New Location} check box.
@item
Select the check box for the tables whose links you want to change, and then click @code{OK}.
@item
In the @code{Select New Location of} <table name> dialog box, specify the new location, click
@code{Open}, and then click @code{OK}.

@end enumerate


@node DELETED problem, Write conflict, Linked Tables, MSAccess
@subsubsection When I Insert or Update a Record in Linked Tables, I Get @code{#DELETED#}

If the inserted or updated records are shown as @code{#DELETED#} in the access, then:

@itemize @bullet
@item
If you are using Access 2000, you should get and install the newest (version
2.6 or higher) Microsoft MDAC (@code{Microsoft Data Access Components}) from
@uref{http://www.microsoft.com/data/}.  This will fix a bug in Access that
when you export data to MySQL, the table and column names aren't specified.
Another way to work around this bug is to upgrade to MyODBC 2.50.33 and
MySQL 3.23.x, which together provide a workaround for the problem.

You should also get and apply the Microsoft Jet 4.0 Service Pack 5 (SP5)
which can be found at
@uref{http://support.microsoft.com/default.aspx?scid=kb;EN-US;q239114}.
This will fix some cases where columns are marked as @code{#DELETED#}
in Access.

Note: If you are using MySQL 3.22, you must to apply the
MDAC patch and use MyODBC 2.50.32 or 2.50.34 and up to work around
this problem.

@item
For all versions of Access, you should enable the MyODBC @code{Return
matching rows} option. For Access 2.0, you should additionally enable
the @code{Simulate ODBC 1.0} option.

@item
You should have a timestamp in all tables that you want to be able to update.
For maximum portability, don't use a length specification in the column
declaration.  That is, use @code{TIMESTAMP}, not @code{TIMESTAMP(@var{n})},
@var{n} < 14.

@item
You should have a primary key in the table. If not, new or updated rows
may show up as @code{#DELETED#}.

@item
Use only @code{DOUBLE} float fields. Access fails when comparing with
single floats.  The symptom usually is that new or updated rows may show
up as @code{#DELETED#} or that you can't find or update rows.

@item
If you are using MyODBC to link to a table that has a @code{BIGINT}
column, the results will be displayed as @code{#DELETED}. The
work around solution is:

@itemize @bullet
@item
Have one more dummy column with @code{TIMESTAMP} as the data type.
@item
Select the @code{Change BIGINT columns to INT} option in the connection
dialog in ODBC DSN Administrator.
@item
Delete the table link from Access and re-create it.
@end itemize

Old records still will display as @code{#DELETED#}, but newly
added/updated records will be displayed properly.

@end itemize


@node Write conflict, Access97 Export, DELETED problem, MSAccess
@subsubsection How Do I Handle Write Conflicts or Row Location Errors?

If you see the following errors, 
select the @code{Return Matching Rows} option in the DSN configuration
dialog, or specify @code{OPTION=2}, as the connection parameter:

@example
Write Conflict. Another user has changed your data.

Row cannot be located for updating. Some values may have been changed
since it was last read.
@end example


@node Access97 Export, Modified error, Write conflict, MSAccess
@subsubsection Whenever I Export a Table from Access 97, a Strange Syntax Error Occurs

This is a strange issue from Access 97, and doesn't appear with Access 2000 or 2002.
You can overcome this by upgrading the MyODBC driver to at least MyODBC 3.51.02.


@node Modified error, Trapping ODBC Errors, Access97 Export, MSAccess
@subsubsection Access Returns @code{Another user has modified the record that you have modified} While Editing Records

With some programs, this error may occur:
@code{Another user has modified the record that you have modified}. In most
cases, this can be solved by doing one of the following things:

@itemize @bullet

@item
Add a primary key for the table if there isn't one already.
@item
Add a timestamp column if there isn't one already.
@item
Only use double float fields. Some programs may fail when they compare
single floats.
@end itemize

If these strategies don't help, you should start by making a log file from
the ODBC manager (the log you get when requesting logs from ODBCADMIN)
and a MyODBC log to help you figure out why things go wrong.
For instructions, see @ref{MyODBC trace}.


@node Trapping ODBC Errors, Optimize Access, Modified error, MSAccess
@subsubsection How to Trap ODBC Login Error Messages in Access?


Read ``How to Trap ODBC Login Error Messages in Access'' at
@uref{http://support.microsoft.com/support/kb/articles/Q124/9/01.asp?LN=EN-US&SD=gn&FR=0%3CP%3E}.


@node Optimize Access, Access-Long Tables, Trapping ODBC Errors, MSAccess
@subsubsection How Do I Optimize Access for Performance with MyODBC?


@itemize bullet
@item
@uref{http://support.microsoft.com/default.aspx?scid=kb;en-us;128808,Optimizing for Client/Server Performance}
@item
@uref{http://support.microsoft.com/default.aspx?scid=kb;en-us;164481,Tips for Converting Applications to Using ODBCDirect}
@item
@uref{http://support.microsoft.com/default.aspx?scid=kb;EN-US;q99321,Tips for Optimizing Queries on Attached SQL Tables}
@end itemize


@node Access-Long Tables, Query-Timeout, Optimize Access, MSAccess
@subsubsection I Have Very Long Tables. What is the Best Configuration for MyODBC to Access These Tables?

If you have very large (long) tables in Access, it might take a very long
time to open them. Or you might run low on virtual memory and eventually get
an @code{ODBC Query Failed} error and the table will not open.  To deal with
this, select the following options:

@itemize @bullet
@item
Return Matching Rows (2)
@item
Allow BIG Results (8).
@end itemize

These add up to a value of 10 (@code{OPTION=10}).


@node Query-Timeout, MySQL tools with Access, Access-Long Tables, MSAccess
@subsubsection How to Set the QueryTimeout Value for ODBC Connections?

Read ``Set the QueryTimeout Value for ODBC Connections'' at
@uref{http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B153756}.


@node MySQL tools with Access,  , Query-Timeout, MSAccess
@subsubsection INFO: Tools to Export/Import from/to Access to/from MySQL

Refer to @uref{http://www.mysql.com/portal/software/convertors/,converters} section for list of available tools.


@node MSVBA, Tools, MSAccess, ODBC Connector
@subsection MyODBC and Microsoft VBA and ASP

This section answers questions related to using MyODBC
with Microsoft Visual Basic(ADO, DAO & RDO) and ASP.

@menu
* count-error::                 Why Does @code{SELECT COUNT(*) FROM @var{tbl_name}} Return an Error?
* chunk::                       Whenever I Use the @code{AppendChunk()} or @code{GetChunk()} ADO Methods, I Get an Error @code{Multiple-step operation generated errors. Check each status value}.
* Total number of rows::        How to Find the Total Number of Rows Affected by a Particular SQL Statement in ADO?
* Blob-Article::                How Do I Handle Blob Data in Visual Basic?
* VB-Types::                    How Do I Map Visual Basic Data Types to MySQL Types?
* SAMPLE - VB::                 SAMPLES: VB with ADO, DAO and RDO
* ASP::                         ASP and MySQL with MyODBC
* ADO::                         INFO: Frequently Asked Questions on ActiveX Data Objects (ADO)
@end menu


@node count-error, chunk, MSVBA, MSVBA
@subsubsection Why Does @code{SELECT COUNT(*) FROM @var{tbl_name}} Return an Error?

It's because the @code{COUNT(*)} expression is returning a @code{BIGINT},
and ADO can't make sense of a number this big.  Select the @code{Change
BIGINT columns to INT} option (option value 16384).


@node chunk, Total number of rows, count-error, MSVBA
@subsubsection Whenever I Use the @code{AppendChunk()} or @code{GetChunk()} ADO Methods, I Get an Error @code{Multiple-step operation generated errors. Check each status value}.


The @code{GetChunk()} and @code{AppendChunk()} methods from ADO doesn't work as
expected when the cursor location is specified as adUseServer. On the other
hand, you can overcome this error by using adUseClient.

A simple example can be found from,  @uref{http://www.dwam.net/iishelp/ado/docs/adomth02_4.htm}


@node Total number of rows, Blob-Article, chunk, MSVBA
@subsubsection How to Find the Total Number of Rows Affected by a Particular SQL Statement in ADO?

You can make use of @code{RecordsAffected} property in the ADO execute method. For more
information on the usage of execute method, refer to
@uref{http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/mdmthcnnexecute.asp}.


@node Blob-Article, VB-Types, Total number of rows, MSVBA
@subsubsection How Do I Handle Blob Data in Visual Basic?

Here is an excellent article from Mike Hillyer
(@email{m.hillyer@@telusplanet.net}); explaining how to insert
and/or fetch data from blob columns through MyODBC from ADO:
@uref{http://www.dynamergy.com/mike/articles/blobaccessvb.html,MySQL
BLOB columns and Visual Basic 6}.


@node VB-Types, SAMPLE - VB, Blob-Article, MSVBA
@subsubsection How Do I Map Visual Basic Data Types to MySQL Types?

Here is yet another good article from Mike Hillyer
(@email{m.hillyer@@telusplanet.net}):
@uref{http://www.dynamergy.com/mike/articles/vbmysqldatatypes.php, How
to map Visual basic data type to MySQL types}.


@node SAMPLE - VB, ASP, VB-Types, MSVBA
@subsubsection SAMPLES: VB with ADO, DAO and RDO

A simple examples for the usage of ADO, DAO and RDO with VB can be found her:

@itemize @bullet
@item
ADO sample: @ref{MyODBC With VB}
@item
DAO sample: @ref{MyODBC With VB}
@item
RDO sample: @ref{MyODBC With VB}
@end itemize

If you find any other good example or HOW-TO on ADO/DAO/RDO, then please send the details to @email{myodbc@@lists.mysql.com}

@node ASP, ADO, SAMPLE - VB, MSVBA
@subsubsection ASP and MySQL with MyODBC

For more information about how to access MySQL via ASP using MyODBC,
refer to the following articles:

@itemize @bullet
@item
@uref{http://www.devarticles.com/c/a/ASP/Using-MyODBC-To-Access-Your-MySQL-Database-Via-ASP/,
Using MyODBC To Access Your MySQL Database Via ASP}
@item
@uref{http://www.dwam.net/mysql/asp_myodbc.asp,
ASP and MySQL at DWAM.NT}
@end itemize

A Frequently Asked Questions list for ASP can be found at
@uref{http://support.microsoft.com/default.aspx?scid=/Support/ActiveServer/faq/data/adofaq.asp}.


@node ADO,  , ASP, MSVBA
@subsubsection INFO: Frequently Asked Questions on ActiveX Data Objects (ADO)

For information, see
@uref{http://support.microsoft.com/default.aspx?scid=kb;EN-US;q183606,
ActiveX Data Objects(ADO) Freqently Asked Questions}.


@node Tools, Functionality, MSVBA, ODBC Connector
@subsection MyODBC and Third-Party ODBC Tools

This section answers questions related to MyODBC
with various ODBC-related tools; such as Microsoft Word, Excel and
ColdFusion.

@menu
* DocToExcel::                  How to Retrieve Data from MySQL into MS-Word/Excel Documents?
* MSDTS::                       Exporting Tables from MS DTS to MySQL Using MyODBC Results in a Syntax Error
* HOWTO-CF::                    HOWTO: Configure MySQL+MyODBC+unixODBC+ColdFusion on Solaris
@end menu


@node DocToExcel, MSDTS, Tools, Tools
@subsubsection How to Retrieve Data from MySQL into MS-Word/Excel Documents?

To retrieve data from MySQL to Word/Excel documents, you need to
use the MyODBC driver and the Add-in Microsoft Query help.

For example, create a database with a table containing two columns of text:

@itemize @bullet
@item
Insert rows using the @command{mysql} client command-line tool.
@item
Create a DSN file using the ODBC manager, for example, @file{my} for the
database that was just created.
@item
Open the Word application.
@item
Create a blank new document.
@item
In the @code{Database} tool bar, press the @code{Insert Database} button.
@item
Press the @code{Get Data} button.
@item
At the right hand of the @code{Get Data} screen, press the @code{Ms Query}
button.
@item
In @code{Ms Query}, create a new data source using the @file{my} DSN file.
@item
Select the new query.
@item
Select the columns that you want.
@item
Make a filter if you want.
@item
Make a Sort if you want.
@item
Select @code{Return Data to Microsoft Word}.
@item
Click @code{Finish}.
@item
Click @code{Insert Data} and select the records.
@item
Click @code{OK} and you see the rows in your Word document.
@end itemize

@node MSDTS, HOWTO-CF, DocToExcel, Tools
@subsubsection Exporting Tables from MS DTS to MySQL Using MyODBC Results in a Syntax Error

This is an issue similar to that of Access 97 when your table consists
of @code{TEXT} or @code{VARCHAR} data types. You can fix this error by
upgrading your MyODBC driver to version 3.51.02 or higher.

@node HOWTO-CF,  , MSDTS, Tools
@subsubsection HOWTO: Configure MySQL+MyODBC+unixODBC+ColdFusion on Solaris

Refer to
@uref{http://dbforums.com/showthread.php?threadid=174934,
     MySQL ColdFusion unixODBC MyODBC and Solaris - how to succeed}


@node Functionality, Basic MyODBC application steps, Tools, ODBC Connector
@subsection MyODBC General Functionality

This section of the document answers questions related to MyODBC
general functionality.

@menu
* ODBC and last_insert_id::     How to Get the Value of an @code{AUTO_INCREMENT} Column in ODBC
* Dynamic Cursor::              Does MyODBC Support Dynamic Cursor Type?
* Transaction::                 What Causes @code{Transactions are not enabled} Errors?
* NoCursor::                    What Causes @code{Cursor not found} Errors?
* MyODBC Compatibility::        Can I Use MyODBC 2.50 Applications with MyODBC 3.51?
* MyODBC-Net::                  Can I Access MySQL from .NET Environment Using MyODBC?
* performance::                 Why Does MyODBC Perform Poorly, and Also Make a Lot of Disk Activity for Relatively Small Queries?
@end menu


@node ODBC and last_insert_id, Dynamic Cursor, Functionality, Functionality
@subsubsection How to Get the Value of an @code{AUTO_INCREMENT} Column in ODBC

@cindex AUTO-INCREMENT, ODBC

A common problem is how to get the value of an automatically generated ID
from an @code{INSERT} statement. With ODBC, you can do something like this (assuming
that @code{auto} is an @code{AUTO_INCREMENT} field):

@example
INSERT INTO tbl (auto,text) VALUES(NULL,'text');
SELECT LAST_INSERT_ID();
@end example

Or, if you are just going to insert the ID into another table, you can do this:

@example
INSERT INTO tbl (auto,text) VALUES(NULL,'text');
INSERT INTO tbl2 (id,text) VALUES(LAST_INSERT_ID(),'text');
@end example

@xref{Getting unique ID}.

For the benefit of some ODBC applications (at least Delphi and Access),
the following query can be used to find a newly inserted row:
@example
SELECT * FROM tbl WHERE auto IS NULL;
@end example


@node Dynamic Cursor, Transaction, ODBC and last_insert_id, Functionality
@subsubsection Does MyODBC Support Dynamic Cursor Type?

Yes. MyODBC 3.51 supports @code{Dynamic cursor} type along with
@code{Forward-only} and @code{static}.

Due to the performance issues, the driver does not support this feature by
default. You can enable this by specifying the connection option flag as
@code{OPTION=32} or by checking the @code{Enable Dynamic Cursor} option
from the DSN configuration.


@node Transaction, NoCursor, Dynamic Cursor, Functionality
@subsubsection What Causes @code{Transactions are not enabled} Errors?

The driver returns this error when an application issues any transactional
call but the underlying MySQL server either does not support transactions
or they are not enabled.

To avoid this problem, you must use a server that has either or both of the
@code{InnoDB} or @code{BDB} storage engines enabled, and use tables of those
types.  MySQL servers from version 4.0 and up support @code{InnoDB} by
default.  MySQL-Max servers also support @code{BDB} on platforms where
@code{BDB} is available.

Also, if your server supports transactional table types (@code{InnoDB}
and @code{BDB})
make sure the @code{disable transactions} option is not set from the DSN
configuration.


@node NoCursor, MyODBC Compatibility, Transaction, Functionality
@subsubsection What Causes @code{Cursor not found} Errors?

This is becuase the application is using old MyODBC 2.50 version, and
it did not set the cursor name explicitly through SQLSetCursorName. The fix
is to upgrade to MyODBC 3.51 version.


@node MyODBC Compatibility, MyODBC-Net, NoCursor, Functionality
@subsubsection Can I Use MyODBC 2.50 Applications with MyODBC 3.51?

Yes. If you find something is not working with MyODBC 3.51 that works with
MyODBC 2.50, then send a mail message to @email{myodbc@@lists.mysql.com}

@node MyODBC-Net, performance, MyODBC Compatibility, Functionality
@subsubsection Can I Access MySQL from .NET Environment Using MyODBC?

Yes. You can make use of @strong{odbc.net} to connect to MySQL through
MyODBC. Here are the few basic samples to connect to MySQL from
VC.NET and VB.NET.
@itemize @bullet
@item
See @ref{ODBC.NET(C-sharp),  , ODBC.NET: CSHAR(C#)}
@item
See @ref{ODBC.NET(VB)}
@end itemize

Here is yet another excellent article
"@uref{http://www.mysql.com/newsletter/2002-07/a0000000035.html,Exploring
MySQL on .NET environment}" by @strong{Venu} (MyODBC developer)
that covers about all MySQL .NET interfaces along with
some useful examples.

@strong{Caution}: Using ODBC.NET with MyODBC, while fetching empty string
(0 length), it starts giving the SQL_NO_DATA exception. You can get the
patch for this from @uref{http://support.microsoft.com/default.aspx?scid=kb;EN-US;q319243}.


@node performance,  , MyODBC-Net, Functionality
@subsubsection Why Does MyODBC Perform Poorly, and Also Make a Lot of Disk Activity for Relatively Small Queries?

MyODBC is a lot faster than any other ODBC driver. Slowness might be
due to not using the following options.

@itemize @bullet
@item
The @strong{ODBC Tracing} option is turned on. You can cross-check whether
this option is not turned on by following the instructions from
@uref{http://support.microsoft.com/default.aspx?scid=kb;EN-US;268591,
here}.

@* @image{Images/mydsn-trace} @*

As shown in the above image, the 'When to trace' option from the ODBC
Data Source Administrator 'Tracing' tab should always point to 'Start
Tracing Now', instead of 'Stop Tracing Now'.

@item
The @strong{Debug version} of the driver is used. If you are using the
debug version of the driver DLL, it can also relatively slow down the
query processing time. You can cross-check whether you are using the
debug or release version of the DLL from the 'Comments' section
of the driver DLL properties (from the sytem directory, right click
on the driver DLL and click on properties) as shown below:

@* @image{Images/mydll-properties} @*

@item
The @strong{Driver trace and query logs} are enabled. Even if you intent
to use the debug version of the driver (you should always use the release
version in the production environment), make sure the driver trace and
query log options(OPTION=4,524288 respectively) are not enabled as
shown below:

@* @image{Images/mydsn-options} @*

@end itemize


@c TODO: after conversion to DocBook, wrap next several "chapters"
@c inside a parent "Developing Applications Using MyODBC" element.
@c Initial para can be:
@c This chapter contains information about developing applications that
@c access a MySQL server using MyODBC as the interface.

@node Basic MyODBC application steps, MyODBC API Reference, Functionality, ODBC Connector
@subsection Basic MyODBC Application Steps 

Interacting with a MySQL server from MyODBC applications involves the
following operations:

@itemize @bullet    
@item Configure the MyODBC DSN
@item Connect to MySQL server
@item Initialization operations
@item Execute SQL statements
@item Retrieve results
@item Perform Transactions
@item Disconnect from the server
@end itemize

Most applications use some variation of these steps. The basic application 
steps are shown in the following diagram:

@* @image{Images/myflowchart,6in,8in} @*


@node MyODBC API Reference, MyODBC Data Types, Basic MyODBC application steps, ODBC Connector
@subsection MyODBC API Reference

This section summarizes ODBC routines, categorized by functionality.

For the complete ODBC API reference, please refer to the ODBC Programer's
Reference at
@uref{http://msdn.microsoft.com/library/en-us/odbc/htm/odbcabout_this_manual.asp}.

An application can call @code{SQLGetInfo} function to obtain conformance 
information about MyODBC. To obtain information about support for a specific 
function in the driver, an application can call @code{SQLGetFunctions}.

Note: For backward compatibility, the MyODBC 3.51 driver supports all
deprecated functions.

The following tables list MyODBC API calls grouped by task:

@strong{Connecting to a data source:}

@multitable @columnfractions .22 .13 .13 .17 .35
@item @strong{Function name} @tab @strong{MyODBC} @tab @strong{MyODBC} @tab @strong{Conformance} @tab @strong{Purpose}
@item @tab @strong{2.50} @tab @strong{3.51} @tab @tab

@item @code{SQLAllocHandle} @tab No @tab Yes @tab ISO 92 @tab Obtains an environment, connection, statement, or descriptor handle. 
@item @code{SQLConnect} @tab Yes @tab Yes @tab ISO 92 @tab Connects to a specific driver by data source name, user ID, and password. 
@item @code{SQLDriverConnect} @tab Yes @tab Yes @tab ODBC @tab Connects to a specific driver by connection string or requests that the Driver Manager and driver display connection dialog boxes for the user. 
@item @code{SQLAllocEnv} @tab Yes @tab Yes @tab Deprecated @tab Obtains an environment handle allocated from driver. 
@item @code{SQLAllocConnect} @tab Yes @tab Yes @tab Deprecated @tab Obtains a connection handle 
@end multitable

@strong{Obtaining information about a driver and data source:}

@multitable @columnfractions .22 .13 .13 .17 .35
@item @strong{Function name} @tab @strong{MyODBC} @tab @strong{MyODBC} @tab @strong{Conformance} @tab @strong{Purpose}
@item @tab @strong{2.50} @tab @strong{3.51} @tab @tab

@item @code{SQLDataSources} @tab No @tab No @tab ISO 92 @tab Returns the list of available data sources, handled by the Driver Manager
@item @code{SQLDrivers} @tab No @tab No @tab ODBC @tab Returns the list of installed drivers and their attributes, handles by Driver Manager
@item @code{SQLGetInfo} @tab Yes @tab Yes @tab ISO 92 @tab Returns information about a specific driver and data source. 
@item @code{SQLGetFunctions} @tab Yes @tab Yes @tab ISO 92 @tab Returns supported driver functions. 
@item @code{SQLGetTypeInfo} @tab Yes @tab Yes @tab ISO 92 @tab Returns information about supported data types. 
@end multitable

@strong{Setting and retrieving driver attributes:}

@multitable @columnfractions .22 .13 .13 .17 .35
@item @strong{Function name} @tab @strong{MyODBC} @tab @strong{MyODBC} @tab @strong{Conformance} @tab @strong{Purpose}
@item @tab @strong{2.50} @tab @strong{3.51} @tab @tab

@item @code{SQLSetConnectAttr} @tab No @tab Yes @tab ISO 92 @tab Sets a connection attribute.
@item @code{SQLGetConnectAttr} @tab No @tab Yes @tab ISO 92 @tab Returns the value of a connection attribute.
@item @code{SQLSetConnectOption} @tab Yes @tab Yes @tab Deprecated @tab Sets a connection option
@item @code{SQLGetConnectOption} @tab Yes @tab Yes @tab Deprecated @tab Returns the value of a connection option
@item @code{SQLSetEnvAttr} @tab No @tab Yes @tab ISO 92 @tab Sets an environment attribute. 
@item @code{SQLGetEnvAttr} @tab No @tab Yes @tab ISO 92 @tab Returns the value of an environment attribute. 
@item @code{SQLSetStmtAttr} @tab No @tab Yes @tab ISO 92 @tab Sets a statement attribute. 
@item @code{SQLGetStmtAttr} @tab No @tab Yes @tab ISO 92 @tab Returns the value of a statement attribute. 
@item @code{SQLSetStmtOption} @tab Yes @tab Yes @tab Deprecated @tab Sets a statement option
@item @code{SQLGetStmtOption} @tab Yes @tab Yes @tab Deprecated @tab Returns the value of a statement option 
@end multitable

@strong{Preparing SQL requests:}

@multitable @columnfractions .22 .13 .13 .17 .35
@item @strong{Function name} @tab @strong{MyODBC} @tab @strong{MyODBC} @tab @strong{Conformance} @tab @strong{Purpose}
@item @tab @strong{2.50} @tab @strong{3.51} @tab @tab

@item @code{SQLAllocStmt} @tab Yes @tab Yes @tab Deprecated @tab Allocates a statement handle
@item @code{SQLPrepare} @tab Yes @tab Yes @tab ISO 92 @tab Prepares an SQL statement for later execution. 
@item @code{SQLBindParameter} @tab Yes @tab Yes @tab ODBC @tab Assigns storage for a parameter in an SQL statement. 
@item @code{SQLGetCursorName} @tab Yes @tab Yes @tab ISO 92 @tab Returns the cursor name associated with a statement handle. 
@item @code{SQLSetCursorName} @tab Yes @tab Yes @tab ISO 92 @tab Specifies a cursor name. 
@item @code{SQLSetScrollOptions} @tab Yes @tab Yes @tab ODBC @tab Sets options that control cursor behavior.
@end multitable

@strong{Submitting requests:}

@multitable @columnfractions .22 .13 .13 .17 .35
@item @strong{Function name} @tab @strong{MyODBC} @tab @strong{MyODBC} @tab @strong{Conformance} @tab @strong{Purpose}
@item @tab @strong{2.50} @tab @strong{3.51} @tab @tab

@item @code{SQLExecute} @tab Yes @tab Yes @tab ISO 92 @tab Executes a prepared statement.
@item @code{SQLExecDirect} @tab Yes @tab Yes @tab ISO 92 @tab Executes a statement
@item @code{SQLNativeSql} @tab Yes @tab Yes @tab ODBC @tab Returns the text of an SQL statement as translated by the driver. 
@item @code{SQLDescribeParam} @tab Yes @tab Yes @tab ODBC @tab Returns the description for a specific parameter in a statement. 
@item @code{SQLNumParams} @tab Yes @tab Yes @tab ISO 92 @tab Returns the number of parameters in a statement. 
@item @code{SQLParamData} @tab Yes @tab Yes @tab ISO 92 @tab Used in conjunction with @code{SQLPutData} to supply parameter data at execution time. (Useful for long data values.) 
@item @code{SQLPutData} @tab Yes @tab Yes @tab ISO 92 @tab Sends part or all of a data value for a parameter. (Useful for long data values.) 
@end multitable

@strong{Retrieving results and information about results:}

@multitable @columnfractions .22 .13 .13 .17 .35
@item @strong{Function name} @tab @strong{MyODBC} @tab @strong{MyODBC} @tab @strong{Conformance} @tab @strong{Purpose}
@item @tab @strong{2.50} @tab @strong{3.51} @tab @tab

@item @code{SQLRowCount} @tab Yes @tab Yes @tab ISO 92 @tab Returns the number of rows affected by an insert, update, or delete request.
@item @code{SQLNumResultCols} @tab Yes @tab Yes @tab ISO 92 @tab Returns the number of columns in the result set.
@item @code{SQLDescribeCol} @tab Yes @tab Yes @tab ISO 92 @tab Describes a column in the result set. 
@item @code{SQLColAttribute} @tab No @tab Yes @tab ISO 92 @tab Describes attributes of a column in the result set. 
@item @code{SQLColAttributes} @tab Yes @tab Yes @tab Deprecated @tab Describes attributes of a column in the result set. 
@item @code{SQLFetch} @tab Yes @tab Yes @tab ISO 92 @tab Returns multiple result rows. 
@item @code{SQLFetchScroll} @tab No @tab Yes @tab ISO 92 @tab Returns scrollable result rows. 
@item @code{SQLExtendedFetch} @tab Yes @tab Yes @tab Deprecated @tab Returns scrollable result rows. 
@item @code{SQLSetPos} @tab Yes @tab Yes @tab ODBC @tab Positions a cursor within a fetched block of data and allows an application to refresh data in the rowset or to update or delete data in the result set. 
@item @code{SQLBulkOperations} @tab No @tab Yes @tab ODBC @tab Performs bulk insertions and bulk bookmark operations, including update, delete, and fetch by bookmark. 
@end multitable

@strong{Retrieving error or diagnostic information:}

@multitable @columnfractions .22 .13 .13 .17 .35
@item @strong{Function name} @tab @strong{MyODBC} @tab @strong{MyODBC} @tab @strong{Conformance} @tab @strong{Purpose}
@item @tab @strong{2.50} @tab @strong{3.51} @tab @tab

@item @code{SQLError} @tab Yes @tab Yes @tab Deprecated @tab Returns additional error or status information 
@item @code{SQLGetDiagField} @tab Yes @tab Yes @tab ISO 92 @tab Returns additional diagnostic information (a single field of the diagnostic data structure). 
@item @code{SQLGetDiagRec} @tab Yes @tab Yes @tab ISO 92 @tab Returns additional diagnostic information (multiple fields of the diagnostic data structure). 
@end multitable

@strong{Obtaining information about the data source's system tables (catalog
functions) item:}

@multitable @columnfractions .22 .13 .13 .17 .35
@item @strong{Function name} @tab @strong{MyODBC} @tab @strong{MyODBC} @tab @strong{Conformance} @tab @strong{Purpose}
@item @tab @strong{2.50} @tab @strong{3.51} @tab @tab

@item @code{SQLColumnPrivileges} @tab Yes @tab Yes @tab ODBC @tab Returns a list of columns and associated privileges for one or more tables.
@item @code{SQLColumns} @tab Yes @tab Yes @tab X/Open @tab Returns the list of column names in specified tables.
@item @code{SQLForeignKeys} @tab Yes @tab Yes @tab ODBC @tab Returns a list of column names that make up foreign keys, if they exist for a specified table. 
@item @code{SQLPrimaryKeys} @tab Yes @tab Yes @tab ODBC @tab Returns the list of column names that make up the primary key for a table. 
@item @code{SQLSpecialColumns} @tab Yes @tab Yes @tab X/Open @tab Returns information about the optimal set of columns that uniquely identifies a row in a specified table, or the columns that are automatically updated when any value in the row is updated by a transaction. 
@item @code{SQLStatistics} @tab Yes @tab Yes @tab ISO 92 @tab Returns statistics about a single table and the list of indexes associated with the table. 
@item @code{SQLTablePrivileges} @tab Yes @tab Yes @tab ODBC @tab Returns a list of tables and the privileges associated with each table. 
@item @code{SQLTables} @tab Yes @tab Yes @tab X/Open @tab Returns the list of table names stored in a specific data source. 
@end multitable

@strong{Performing transactions:}

@multitable @columnfractions .22 .13 .13 .17 .35
@item @strong{Function name} @tab @strong{MyODBC} @tab @strong{MyODBC} @tab @strong{Conformance} @tab @strong{Purpose}
@item @tab @strong{2.50} @tab @strong{3.51} @tab @tab

@item @code{SQLTransact} @tab Yes @tab Yes @tab Deprecated @tab Commits or rolls back a transaction 
@item @code{SQLEndTran} @tab No @tab Yes @tab ISO 92 @tab Commits or rolls back a transaction. 
@end multitable

@strong{Terminating a statement:}

@multitable @columnfractions .22 .13 .13 .17 .35
@item @strong{Function name} @tab @strong{MyODBC} @tab @strong{MyODBC} @tab @strong{Conformance} @tab @strong{Purpose}
@item @tab @strong{2.50} @tab @strong{3.51} @tab @tab

@item @code{SQLFreeStmt} @tab Yes @tab Yes @tab ISO 92 @tab Ends statement processing, discards pending results, and, optionally, frees all resources associated with the statement handle. 
@item @code{SQLCloseCursor} @tab Yes @tab Yes @tab ISO 92 @tab Closes a cursor that has been opened on a statement handle. 
@item @code{SQLCancel} @tab Yes @tab Yes @tab ISO 92 @tab Cancels an SQL statement. 
@end multitable

@strong{Terminating a connection:}

@multitable @columnfractions .22 .13 .13 .17 .35
@item @strong{Function name} @tab @strong{MyODBC} @tab @strong{MyODBC} @tab @strong{Conformance} @tab @strong{Purpose}
@item @tab @strong{2.50} @tab @strong{3.51} @tab @tab

@item @code{SQLDisconnect} @tab Yes @tab Yes @tab ISO 92 @tab Closes the connection. 
@item @code{SQLFreeHandle} @tab No @tab Yes @tab ISO 92 @tab Releases an environment, connection, statement, or descriptor handle.
@item @code{SQLFreeConnect} @tab Yes @tab Yes @tab Deprecated @tab Releases connection handle
@item @code{SQLFreeEnv} @tab Yes @tab Yes @tab Deprecated @tab Releases an environment handle
@end multitable


@node MyODBC Data Types, MyODBC Error Codes, MyODBC API Reference, ODBC Connector
@subsection MyODBC Data Types

The following table illustrates how driver maps the server data types to default 
SQL and C data types:

@multitable @columnfractions .33 .33 .33
@item @strong{Native Value} @tab @strong{SQL Type} @tab @strong{C Type}
@item @code{bit} @tab @code{SQL_BIT} @tab @code{SQL_C_BIT}
@item @code{tinyint} @tab @code{SQL_TINYINT} @tab @code{SQL_C_STINYINT}
@item @code{tinyint unsigned} @tab @code{SQL_TINYINT} @tab @code{SQL_C_UTINYINT}
@item @code{bigint}  @tab @code{SQL_BIGINT} @tab @code{SQL_C_SBIGINT}
@item @code{bigint unsigned} @tab @code{SQL_BIGINT} @tab @code{SQL_C_UBIGINT}
@item @code{long varbinary} @tab @code{SQL_LONGVARBINARY} @tab @code{SQL_C_BINARY}
@item @code{blob} @tab @code{SQL_VARBINARY} @tab @code{SQL_C_BINARY}
@item @code{longblob} @tab @code{SQL_VARBINARY} @tab @code{SQL_C_BINARY}
@item @code{tinyblob} @tab @code{SQL_BINARY} @tab @code{SQL_C_BINARY}
@item @code{mediumblob} @tab @code{SQL_LONGVARBINARY} @tab @code{SQL_C_BINARY}
@item @code{long varchar} @tab @code{SQL_LONGVARCHAR} @tab @code{SQL_C_CHAR}
@item @code{text} @tab @code{SQL_LONGVARCHAR} @tab @code{SQL_C_CHAR}
@item @code{mediumtext} @tab @code{SQL_LONGVARCHAR} @tab @code{SQL_C_CHAR}
@item @code{char} @tab @code{SQL_CHAR} @tab @code{SQL_C_CHAR}
@item @code{numeric} @tab @code{SQL_NUMERIC} @tab @code{SQL_C_CHAR}
@item @code{decimal} @tab @code{SQL_DECIMAL} @tab @code{SQL_C_CHAR}
@item @code{integer} @tab @code{SQL_INTEGER} @tab @code{SQL_C_SLONG}
@item @code{integer unsigned} @tab @code{SQL_INTEGER} @tab @code{SQL_C_ULONG}
@item @code{int} @tab @code{SQL_INTEGER} @tab @code{SQL_C_SLONG}
@item @code{int unsigned} @tab @code{SQL_INTEGER} @tab @code{SQL_C_ULONG}
@item @code{mediumint} @tab @code{SQL_INTEGER} @tab @code{SQL_C_SLONG}
@item @code{mediumint unsigned} @tab @code{SQL_INTEGER} @tab @code{SQL_C_ULONG}
@item @code{smallint} @tab @code{SQL_SMALLINT} @tab @code{SQL_C_SSHORT}
@item @code{smallint unsigned} @tab @code{SQL_SMALLINT} @tab @code{SQL_C_USHORT}
@item @code{real} @tab @code{SQL_FLOAT} @tab @code{SQL_C_DOUBLE}
@item @code{double} @tab @code{SQL_FLOAT} @tab @code{SQL_C_DOUBLE}
@item @code{float} @tab @code{SQL_REAL} @tab @code{SQL_C_FLOAT}
@item @code{double precision} @tab @code{SQL_DOUBLE} @tab @code{SQL_C_DOUBLE}
@item @code{date} @tab @code{SQL_DATE} @tab @code{SQL_C_DATE}
@item @code{time} @tab @code{SQL_TIME} @tab @code{SQL_C_TIME}
@item @code{year} @tab @code{SQL_SMALLINT} @tab @code{SQL_C_SHORT}
@item @code{datetime} @tab @code{SQL_TIMESTAMP} @tab @code{SQL_C_TIMESTAMP}
@item @code{timestamp} @tab @code{SQL_TIMESTAMP} @tab @code{SQL_C_TIMESTAMP}
@item @code{text} @tab @code{SQL_VARCHAR} @tab @code{SQL_C_CHAR}
@item @code{varchar} @tab @code{SQL_VARCHAR} @tab @code{SQL_C_CHAR}
@item @code{enum} @tab @code{SQL_VARCHAR} @tab @code{SQL_C_CHAR}
@item @code{set} @tab @code{SQL_VARCHAR} @tab @code{SQL_C_CHAR}
@item @code{bit} @tab @code{SQL_CHAR} @tab @code{SQL_C_CHAR}
@item @code{bool} @tab @code{SQL_CHAR} @tab @code{SQL_C_CHAR}
@end multitable


@node MyODBC Error Codes, MyODBC With VB, MyODBC Data Types, ODBC Connector
@subsection MyODBC Error Codes

The following tables lists the error codes returned by the driver apart 
from the server errors.

@multitable @columnfractions .15 .18 .18 .49
@item @strong{Native Code} @tab @strong{SQLSTATE 2} @tab @strong{SQLSTATE 3} @tab @strong{Error Message}
@item 500 @tab 01000 @tab 01000 @tab General warning
@item 501 @tab 01004 @tab 01004 @tab String data, right truncated
@item 502 @tab 01S02 @tab 01S02 @tab Option value changed
@item 503 @tab 01S03 @tab 01S03 @tab No rows updated/deleted
@item 504 @tab 01S04 @tab 01S04 @tab More than one row updated/deleted
@item 505 @tab 01S06 @tab 01S06 @tab Attempt to fetch before the result set returned the first row set
@item 506 @tab 07001 @tab 07002 @tab @code{SQLBindParameter} not used for all parameters
@item 507 @tab 07005 @tab 07005 @tab Prepared statement not a cursor-specification
@item 508 @tab 07009 @tab 07009 @tab Invalid descriptor index
@item 509 @tab 08002 @tab 08002 @tab Connection name in use
@item 510 @tab 08003 @tab 08003 @tab Connection does not exist
@item 511 @tab 24000 @tab 24000 @tab Invalid cursor state
@item 512 @tab 25000 @tab 25000 @tab Invalid transaction state
@item 513 @tab 25S01 @tab 25S01 @tab Transaction state unknown
@item 514 @tab 34000 @tab 34000 @tab Invalid cursor name
@item 515 @tab S1000 @tab HY000 @tab General driver defined error
@item 516 @tab S1001 @tab HY001 @tab Memory allocation error
@item 517 @tab S1002 @tab HY002 @tab Invalid column number
@item 518 @tab S1003 @tab HY003 @tab Invalid application buffer type
@item 519 @tab S1004 @tab HY004 @tab Invalid SQL data type
@item 520 @tab S1009 @tab HY009 @tab Invalid use of null pointer
@item 521 @tab S1010 @tab HY010 @tab Function sequence error
@item 522 @tab S1011 @tab HY011 @tab Attribute can not be set now
@item 523 @tab S1012 @tab HY012 @tab Invalid transaction operation code
@item 524 @tab S1013 @tab HY013 @tab Memory management error
@item 525 @tab S1015 @tab HY015 @tab No cursor name available
@item 526 @tab S1024 @tab HY024 @tab Invalid attribute value
@item 527 @tab S1090 @tab HY090 @tab Invalid string or buffer length
@item 528 @tab S1091 @tab HY091 @tab Invalid descriptor field identifier
@item 529 @tab S1092 @tab HY092 @tab Invalid attribute/option identifier
@item 530 @tab S1093 @tab HY093 @tab Invalid parameter number
@item 531 @tab S1095 @tab HY095 @tab Function type out of range
@item 532 @tab S1106 @tab HY106 @tab Fetch type out of range
@item 533 @tab S1117 @tab HY117 @tab Row value out of range
@item 534 @tab S1109 @tab HY109 @tab Invalid cursor position
@item 535 @tab S1C00 @tab HYC00 @tab Optional feature not implemented
@item 0 @tab 21S01 @tab 21S01 @tab Column count does not match value count
@item 0 @tab 23000 @tab 23000 @tab Integrity constraint violation
@item 0 @tab 42000 @tab 42000 @tab Syntax error or access violation
@item 0 @tab 42S02 @tab 42S02 @tab Base table or view not found
@item 0 @tab 42S12 @tab 42S12 @tab Index not found
@item 0 @tab 42S21 @tab 42S21 @tab Column already exists
@item 0 @tab 42S22 @tab 42S22 @tab Column not found
@item 0 @tab 08S01 @tab 08S01 @tab Communication link failure
@end multitable


@node MyODBC With VB, MyODBC with .NET, MyODBC Error Codes, ODBC Connector
@subsection MyODBC With VB: ADO, DAO and RDO

This section contains simple examples of the use of MySQL ODBC 3.51 Driver
with ADO, DAO and RDO.

@menu
* ADO - rs.addNew::             ADO: @code{rs.addNew}, @code{rs.delete}, and @code{rs.update} 
* DAO - rs.addNew::             DAO: @code{rs.addNew}, @code{rs.update}, and Scrolling 
* RDO - rs.addNew and rs.update::  RDO: @code{rs.addNew} and @code{rs.update} 
@end menu

@node ADO - rs.addNew, DAO - rs.addNew, MyODBC With VB, MyODBC With VB
@subsubsection ADO: @code{rs.addNew}, @code{rs.delete}, and @code{rs.update} 

The following ADO (ActiveX Data Objects) example creates a table
@code{my_ado} and demonstrates the use of @code{rs.addNew}, @code{rs.delete},
and @code{rs.update}.

@example
Private Sub myodbc_ado_Click()

  Dim conn As ADODB.Connection
  Dim rs As ADODB.Recordset
  Dim fld As ADODB.Field
  Dim sql As String

  'connect to MySQL server using MySQL ODBC 3.51 Driver
  Set conn = New ADODB.Connection
  conn.ConnectionString = "DRIVER=@{MySQL ODBC 3.51 Driver@};"_
                        & "SERVER=localhost;"_ 
                        & " DATABASE=test;"_
                        & "UID=venu;PWD=venu; OPTION=3"

  conn.Open

  'create table
  conn.Execute "DROP TABLE IF EXISTS my_ado"
  conn.Execute "CREATE TABLE my_ado(id int not null primary key, name varchar(20)," _
                                 & "txt text, dt date, tm time, ts timestamp)"

  'direct insert
  conn.Execute "INSERT INTO my_ado(id,name,txt) values(1,100,'venu')"
  conn.Execute "INSERT INTO my_ado(id,name,txt) values(2,200,'MySQL')"
  conn.Execute "INSERT INTO my_ado(id,name,txt) values(3,300,'Delete')"

  Set rs = New ADODB.Recordset
  rs.CursorLocation = adUseServer

  'fetch the initial table ..
  rs.Open "SELECT * FROM my_ado", conn
    Debug.Print rs.RecordCount
    rs.MoveFirst
    Debug.Print String(50, "-") & "Initial my_ado Result Set " & String(50, "-")
    For Each fld In rs.Fields
      Debug.Print fld.Name,
      Next
      Debug.Print

      Do Until rs.EOF
      For Each fld In rs.Fields
      Debug.Print fld.Value,
      Next
      rs.MoveNext
      Debug.Print
    Loop
  rs.Close

  'rs insert
  rs.Open "select * from my_ado", conn, adOpenDynamic, adLockOptimistic
  rs.AddNew
  rs!Name = "Monty"
  rs!txt = "Insert row"
  rs.Update
  rs.Close

  'rs update
  rs.Open "SELECT * FROM my_ado"
  rs!Name = "update"
  rs!txt = "updated-row"
  rs.Update
  rs.Close

  'rs update second time..
  rs.Open "SELECT * FROM my_ado"
  rs!Name = "update"
  rs!txt = "updated-second-time"
  rs.Update
  rs.Close

  'rs delete
  rs.Open "SELECT * FROM my_ado"
  rs.MoveNext
  rs.MoveNext
  rs.Delete
  rs.Close

  'fetch the updated table ..
  rs.Open "SELECT * FROM my_ado", conn
    Debug.Print rs.RecordCount
    rs.MoveFirst
    Debug.Print String(50, "-") & "Updated my_ado Result Set " & String(50, "-")
    For Each fld In rs.Fields
      Debug.Print fld.Name,
      Next
      Debug.Print

      Do Until rs.EOF
      For Each fld In rs.Fields
      Debug.Print fld.Value,
      Next
      rs.MoveNext
      Debug.Print
    Loop
  rs.Close
  conn.Close
End Sub
@end example


@node DAO - rs.addNew, RDO - rs.addNew and rs.update, ADO - rs.addNew, MyODBC With VB
@subsubsection DAO: @code{rs.addNew}, @code{rs.update}, and Scrolling 

The following DAO (Data Access Objects) example creates a table @code{my_dao}
and demonstrates the use of @code{rs.addNew}, @code{rs.update}, and result
set scrolling.

@example
Private Sub myodbc_dao_Click()

  Dim ws As Workspace
  Dim conn As Connection
  Dim queryDef As queryDef
  Dim str As String

  'connect to MySQL using MySQL ODBC 3.51 Driver
  Set ws = DBEngine.CreateWorkspace("", "venu", "venu", dbUseODBC)
  str = "odbc;DRIVER=@{MySQL ODBC 3.51 Driver@};"_
                        & "SERVER=localhost;"_ 
                        & " DATABASE=test;"_
                        & "UID=venu;PWD=venu; OPTION=3"
  Set conn = ws.OpenConnection("test", dbDriverNoPrompt, False, str)

  'Create table my_dao
  Set queryDef = conn.CreateQueryDef("", "drop table if exists my_dao")
  queryDef.Execute

  Set queryDef = conn.CreateQueryDef("", "create table my_dao(Id INT AUTO_INCREMENT PRIMARY KEY, " _
                                                           & "Ts TIMESTAMP(14) NOT NULL, Name varchar(20), Id2 INT)")
  queryDef.Execute

  'Insert new records using rs.addNew
  Set rs = conn.OpenRecordset("my_dao")
  Dim i As Integer

    For i = 10 To 15
    rs.AddNew
    rs!Name = "insert record" & i
    rs!Id2 = i
    rs.Update
    Next i
             rs.Close

  'rs update..
  Set rs = conn.OpenRecordset("my_dao")
  rs.Edit
  rs!Name = "updated-string"
  rs.Update
  rs.Close

  'fetch the table back...
  Set rs = conn.OpenRecordset("my_dao", dbOpenDynamic)
  str = "Results:"
  rs.MoveFirst
  While Not rs.EOF
  str = " " & rs!Id & " , " & rs!Name & ", " & rs!Ts & ", " & rs!Id2
  Debug.Print "DATA:" & str
  rs.MoveNext
  Wend

  'rs Scrolling
  rs.MoveFirst
  str = " FIRST ROW: " & rs!Id & " , " & rs!Name & ", " & rs!Ts & ", " & rs!Id2
  Debug.Print str

  rs.MoveLast
  str = " LAST ROW: " & rs!Id & " , " & rs!Name & ", " & rs!Ts & ", " & rs!Id2
  Debug.Print str

  rs.MovePrevious
  str = " LAST-1 ROW: " & rs!Id & " , " & rs!Name & ", " & rs!Ts & ", " & rs!Id2
  Debug.Print str

  'free all resources
  rs.Close
  queryDef.Close
  conn.Close
  ws.Close

End Sub
@end example


@node RDO - rs.addNew and rs.update,  , DAO - rs.addNew, MyODBC With VB
@subsubsection RDO: @code{rs.addNew} and @code{rs.update} 

The following RDO (Remote Data Objects) example creates
a table @code{my_rdo} and demonstrates the use of @code{rs.addNew}
and @code{rs.update}.

@example
Dim rs As rdoResultset
    Dim cn As New rdoConnection
    Dim cl As rdoColumn
    Dim SQL As String

    'cn.Connect = "DSN=test;"
    cn.Connect = "DRIVER=@{MySQL ODBC 3.51 Driver@};"_
                        & "SERVER=localhost;"_ 
                        & " DATABASE=test;"_
                        & "UID=venu;PWD=venu; OPTION=3"

    cn.CursorDriver = rdUseOdbc
    cn.EstablishConnection rdDriverPrompt


    'drop table my_rdo
    SQL = "drop table if exists my_rdo"
    cn.Execute SQL, rdExecDirect

    'create table my_rdo
    SQL = "create table my_rdo(id int, name varchar(20))"
    cn.Execute SQL, rdExecDirect

    'insert - direct
    SQL = "insert into my_rdo values (100,'venu')"
    cn.Execute SQL, rdExecDirect

    SQL = "insert into my_rdo values (200,'MySQL')"
    cn.Execute SQL, rdExecDirect

    'rs insert
    SQL = "select * from my_rdo"
    Set rs = cn.OpenResultset(SQL, rdOpenStatic, rdConcurRowVer, rdExecDirect)
    rs.AddNew
    rs!id = 300
    rs!Name = "Insert1"
    rs.Update
    rs.Close

    'rs insert
    SQL = "select * from my_rdo"
    Set rs = cn.OpenResultset(SQL, rdOpenStatic, rdConcurRowVer, rdExecDirect)
    rs.AddNew
    rs!id = 400
    rs!Name = "Insert 2"
    rs.Update
    rs.Close

    'rs update
    SQL = "select * from my_rdo"
    Set rs = cn.OpenResultset(SQL, rdOpenStatic, rdConcurRowVer, rdExecDirect)
    rs.Edit
    rs!id = 999
    rs!Name = "updated"
    rs.Update
    rs.Close 

    'fetch back...
    SQL = "select * from my_rdo"
    Set rs = cn.OpenResultset(SQL, rdOpenStatic, rdConcurRowVer, rdExecDirect)
    Do Until rs.EOF
    For Each cl In rs.rdoColumns
                Debug.Print cl.Value,
      Next
      rs.MoveNext
      Debug.Print
               Loop
    Debug.Print "Row count="; rs.RowCount

    'close
    rs.Close
    cn.Close

End Sub
@end example


@node MyODBC with .NET, MyODBC Credits, MyODBC With VB, ODBC Connector
@subsection MyODBC with Microsoft .NET

This section contains simple examples that demonstrate the use 
of MyODBC drivers with ODBC.NET.

@menu
* ODBC.NET(C-sharp)::           ODBC.NET: CSHARP(C#)
* ODBC.NET(VB)::                ODBC.NET: VB
@end menu

@node ODBC.NET(C-sharp), ODBC.NET(VB), MyODBC with .NET, MyODBC with .NET
@subsubsection ODBC.NET: CSHARP(C#)

The following sample creates a table @code{my_odbc_net} and 
demonstrates the use in C#.

@example

 /**
 * @@sample    : mycon.cs
 * @@purpose   : Demo sample for ODBC.NET using MyODBC
 * @@author    : Venu, @email{venu@@mysql.com}
 *
 * (C) Copyright MySQL AB, 1995-2004
 *
 **/

 /* build command
  * 
  *  csc /t:exe 
  *      /out:mycon.exe mycon.cs 
  *      /r:Microsoft.Data.Odbc.dll 
  */ 

 using Console = System.Console;
 using Microsoft.Data.Odbc;

 namespace myodbc3
 @{
  class mycon
  @{
    static void Main(string[] args)
    @{
      try
      @{ 
        //Connection string for MyODBC 2.50
        /*string MyConString = "DRIVER=@{MySQL@};" + 
                             "SERVER=localhost;" +
                             "DATABASE=test;" +
                             "UID=venu;" +
                             "PASSWORD=venu;" +
                             "OPTION=3";
        */
        //Connection string for MyODBC 3.51
        string MyConString = "DRIVER=@{MySQL ODBC 3.51 Driver@};" + 
                             "SERVER=localhost;" +
                             "DATABASE=test;" +
                             "UID=venu;" +
                             "PASSWORD=venu;" +
                             "OPTION=3";

        //Connect to MySQL using MyODBC
        OdbcConnection MyConnection = new OdbcConnection(MyConString);    
        MyConnection.Open();

        Console.WriteLine("\n !!! success, connected successfully !!!\n");    

        //Display connection information
        Console.WriteLine("Connection Information:");   
        Console.WriteLine("\tConnection String:" + MyConnection.ConnectionString);    
        Console.WriteLine("\tConnection Timeout:" + MyConnection.ConnectionTimeout);    
        Console.WriteLine("\tDatabase:" + MyConnection.Database);   
        Console.WriteLine("\tDataSource:" + MyConnection.DataSource);
        Console.WriteLine("\tDriver:" + MyConnection.Driver);
        Console.WriteLine("\tServerVersion:" + MyConnection.ServerVersion);

        //Create a sample table
        OdbcCommand MyCommand = new OdbcCommand("DROP TABLE IF EXISTS my_odbc_net",MyConnection);
        MyCommand.ExecuteNonQuery();
        MyCommand.CommandText = "CREATE TABLE my_odbc_net(id int, name varchar(20), idb bigint)";
        MyCommand.ExecuteNonQuery();

        //Insert
        MyCommand.CommandText = "INSERT INTO my_odbc_net VALUES(10,'venu', 300)";        
        Console.WriteLine("INSERT, Total rows affected:" + MyCommand.ExecuteNonQuery());;

        //Insert
        MyCommand.CommandText = "INSERT INTO my_odbc_net VALUES(20,'mysql',400)";        
        Console.WriteLine("INSERT, Total rows affected:" + MyCommand.ExecuteNonQuery());

        //Insert
        MyCommand.CommandText = "INSERT INTO my_odbc_net VALUES(20,'mysql',500)";        
        Console.WriteLine("INSERT, Total rows affected:" + MyCommand.ExecuteNonQuery());

        //Update
        MyCommand.CommandText = "UPDATE my_odbc_net SET id=999 WHERE id=20";        
        Console.WriteLine("Update, Total rows affected:" + MyCommand.ExecuteNonQuery());

        //COUNT(*)        
        MyCommand.CommandText = "SELECT COUNT(*) as TRows FROM my_odbc_net";        
        Console.WriteLine("Total Rows:" + MyCommand.ExecuteScalar());

        //Fetch
        MyCommand.CommandText = "SELECT * FROM my_odbc_net";                
        OdbcDataReader MyDataReader;
        MyDataReader =  MyCommand.ExecuteReader();
        while (MyDataReader.Read())
        @{
         if(string.Compare(MyConnection.Driver,"myodbc3.dll") == 0) @{
           Console.WriteLine("Data:" + MyDataReader.GetInt32(0) + " " +
                                       MyDataReader.GetString(1) + " " +
                                       MyDataReader.GetInt64(2)); //Supported only by MyODBC 3.51
         @}
         else @{            
           Console.WriteLine("Data:" + MyDataReader.GetInt32(0) + " " +
                                       MyDataReader.GetString(1) + " " +                                         
                                       MyDataReader.GetInt32(2)); //BIGINTs not supported by MyODBC
         @}
        @}

        //Close all resources
        MyDataReader.Close();
        MyConnection.Close();
      @}
      catch (OdbcException MyOdbcException)//Catch any ODBC exception ..
      @{
        for (int i=0; i < MyOdbcException.Errors.Count; i++)
        @{
          Console.Write("ERROR #" + i + "\n" +
            "Message: " + MyOdbcException.Errors[i].Message + "\n" +
            "Native: " + MyOdbcException.Errors[i].NativeError.ToString() + "\n" +
            "Source: " + MyOdbcException.Errors[i].Source + "\n" +
            "SQL: " + MyOdbcException.Errors[i].SQLState + "\n");
        @}
      @}
    @}
  @}
 @}
@end example


@node ODBC.NET(VB),  , ODBC.NET(C-sharp), MyODBC with .NET
@subsubsection ODBC.NET: VB

The following sample creates a table @code{my_vb_net} and 
demonstrates the use in VB.

@example
' @@sample    : myvb.vb
' @@purpose   : Demo sample for ODBC.NET using MyODBC
' @@author    : Venu, @email{venu@@mysql.com}
'
' (C) Copyright MySQL AB, 1995-2004
'
'

' 
' build command
'
' vbc /target:exe 
'     /out:myvb.exe 
'     /r:Microsoft.Data.Odbc.dll 
'     /r:System.dll 
'     /r:System.Data.dll 
'

Imports Microsoft.Data.Odbc
Imports System

Module myvb
    Sub Main()
        Try

            'MyODBC 3.51 connection string
            Dim MyConString As String = "DRIVER=@{MySQL ODBC 3.51 Driver@};" & _
                           "SERVER=localhost;" & _
                           "DATABASE=test;" & _
                           "UID=venu;" & _
                           "PASSWORD=venu;" & _
                           "OPTION=3;"

            'Connection
            Dim MyConnection As New OdbcConnection(MyConString)
            MyConnection.Open()

            Console.WriteLine ("Connection State::" & MyConnection.State.ToString)

            'Drop
            Console.WriteLine ("Dropping table")
            Dim MyCommand As New OdbcCommand()
            MyCommand.Connection = MyConnection
            MyCommand.CommandText = "DROP TABLE IF EXISTS my_vb_net"
            MyCommand.ExecuteNonQuery()

            'Create
            Console.WriteLine ("Creating....")
            MyCommand.CommandText = "CREATE TABLE my_vb_net(id int, name varchar(30))"
            MyCommand.ExecuteNonQuery()

            'Insert
            MyCommand.CommandText = "INSERT INTO my_vb_net VALUES(10,'venu')"    
            Console.WriteLine("INSERT, Total rows affected:" & MyCommand.ExecuteNonQuery())

            'Insert
            MyCommand.CommandText = "INSERT INTO my_vb_net VALUES(20,'mysql')"
            Console.WriteLine("INSERT, Total rows affected:" & MyCommand.ExecuteNonQuery())

            'Insert
            MyCommand.CommandText = "INSERT INTO my_vb_net VALUES(20,'mysql')"
            Console.WriteLine("INSERT, Total rows affected:" & MyCommand.ExecuteNonQuery())

            'Insert
            MyCommand.CommandText = "INSERT INTO my_vb_net(id) VALUES(30)"
            Console.WriteLine("INSERT, Total rows affected:" & MyCommand.ExecuteNonQuery())

            'Update
            MyCommand.CommandText = "UPDATE my_vb_net SET id=999 WHERE id=20"
            Console.WriteLine("Update, Total rows affected:" & MyCommand.ExecuteNonQuery())

            'COUNT(*)        
            MyCommand.CommandText = "SELECT COUNT(*) as TRows FROM my_vb_net"
            Console.WriteLine("Total Rows:" & MyCommand.ExecuteScalar())

            'Select              
            Console.WriteLine ("Select * FROM my_vb_net")
            MyCommand.CommandText = "SELECT * FROM my_vb_net"
            Dim MyDataReader As OdbcDataReader
            MyDataReader = MyCommand.ExecuteReader
            While MyDataReader.Read
                If MyDataReader("name") Is DBNull.Value Then
                    Console.WriteLine ("id = " & CStr(MyDataReader("id")) & "  name = " & _
                      "NULL")
                Else
                    Console.WriteLine ("id = " & CStr(MyDataReader("id")) & "  name = " & _
                                          CStr(MyDataReader("name")))
                End If
            End While

        'Catch ODBC Exception
        Catch MyOdbcException As OdbcException 
            Dim i As Integer
            Console.WriteLine (MyOdbcException.ToString)

        'Catch program exception
        Catch MyException As Exception
            Console.WriteLine (MyException.ToString)
    End Try
    End Sub
End Module
@end example


@node MyODBC Credits,  , MyODBC with .NET, ODBC Connector
@subsection Credits

These are the developers that have worked on the MyODBC 
and MyODBC 3.51 Drivers from MySQL AB.

@itemize @bullet
@item
Micheal (Monty) Widenius
@item
Venu Anuganti
@item
Peter Harvey
@end itemize


@node Java Connector,  , ODBC Connector, MySQL Connectors
@section MySQL Java Connectivity (JDBC)

@cindex Java connectivity
@cindex Connector/J
@cindex JDBC

There are two supported JDBC drivers for MySQL:

@itemize @bullet
@item
@code{MySQL Connector/J} from MySQL AB, implemented in 100% native Java.
This product was formerly known as the @code{mm.mysql} driver.
You can download @code{MySQL Connector/J} from
@uref{http://dev.mysql.com/downloads/connector/j/}.
@item
The Resin JDBC driver, which can be found at
@uref{http://www.caucho.com/projects/jdbc-mysql/index.xtp}.
@end itemize

For more information, consult any general JDBC documentation, plus each
driver's own documentation for MySQL-specific features.

Documentation for @code{MySQL Connector/J} is available online at the
MySQL AB Web site at @uref{http://dev.mysql.com/doc/}.


@node Error-handling, Extending MySQL, MySQL Connectors, Top
@chapter Error Handling in MySQL

@c TODO: say something about SHOW WARNINGS, SHOW ERRORS, @@warning_count,
@c @@error_count.

This chapter lists the errors that may appear when you call MySQL from
any host language.  The first list displays server error messages.
The second list displays client program messages.

Server error information comes from the following files:

@itemize @bullet
@item
The Error values and the symbols in parentheses correspond to
definitions in the @file{include/mysqld_error.h} MySQL source file.

@item
The SQLSTATE values correspond to definitions
in the @file{include/sql_state.h} MySQL source file.

SQLSTATE error codes are displayed only if
you use MySQL version 4.1 and up. SQLSTATE codes
were added for compatibility with X/Open, ANSI, and ODBC
behavior.

@item
The Message values correspond to the error messages that are listed
in the @file{sql/share/english/errmsg.txt} file.  %d or %s represent numbers
or strings that are substituted into the messages %when they are displayed.

@end itemize

Because updates are frequent, it is possible that
these files will contain additional error information not listed here.

@c NOTE: To regenerate this list, run the make-errmsg-table.pl script.

@itemize @bullet

@item Error: @code{1000} SQLSTATE: @code{HY000} (@code{ER_HASHCHK})

Message: hashchk

@item Error: @code{1001} SQLSTATE: @code{HY000} (@code{ER_NISAMCHK})

Message: isamchk

@item Error: @code{1002} SQLSTATE: @code{HY000} (@code{ER_NO})

Message: NO

@item Error: @code{1003} SQLSTATE: @code{HY000} (@code{ER_YES})

Message: YES

@item Error: @code{1004} SQLSTATE: @code{HY000} (@code{ER_CANT_CREATE_FILE})

Message: Can't create file '%s' (errno: %d)

@item Error: @code{1005} SQLSTATE: @code{HY000} (@code{ER_CANT_CREATE_TABLE})

Message: Can't create table '%s' (errno: %d)

@item Error: @code{1006} SQLSTATE: @code{HY000} (@code{ER_CANT_CREATE_DB})

Message: Can't create database '%s' (errno: %d)

@item Error: @code{1007} SQLSTATE: @code{HY000} (@code{ER_DB_CREATE_EXISTS})

Message: Can't create database '%s'; database exists

@item Error: @code{1008} SQLSTATE: @code{HY000} (@code{ER_DB_DROP_EXISTS})

Message: Can't drop database '%s'; database doesn't exist

@item Error: @code{1009} SQLSTATE: @code{HY000} (@code{ER_DB_DROP_DELETE})

Message: Error dropping database (can't delete '%s', errno: %d)

@item Error: @code{1010} SQLSTATE: @code{HY000} (@code{ER_DB_DROP_RMDIR})

Message: Error dropping database (can't rmdir '%s', errno: %d)

@item Error: @code{1011} SQLSTATE: @code{HY000} (@code{ER_CANT_DELETE_FILE})

Message: Error on delete of '%s' (errno: %d)

@item Error: @code{1012} SQLSTATE: @code{HY000} (@code{ER_CANT_FIND_SYSTEM_REC})

Message: Can't read record in system table

@item Error: @code{1013} SQLSTATE: @code{HY000} (@code{ER_CANT_GET_STAT})

Message: Can't get status of '%s' (errno: %d)

@item Error: @code{1014} SQLSTATE: @code{HY000} (@code{ER_CANT_GET_WD})

Message: Can't get working directory (errno: %d)

@item Error: @code{1015} SQLSTATE: @code{HY000} (@code{ER_CANT_LOCK})

Message: Can't lock file (errno: %d)

@item Error: @code{1016} SQLSTATE: @code{HY000} (@code{ER_CANT_OPEN_FILE})

Message: Can't open file: '%s' (errno: %d)

@item Error: @code{1017} SQLSTATE: @code{HY000} (@code{ER_FILE_NOT_FOUND})

Message: Can't find file: '%s' (errno: %d)

@item Error: @code{1018} SQLSTATE: @code{HY000} (@code{ER_CANT_READ_DIR})

Message: Can't read dir of '%s' (errno: %d)

@item Error: @code{1019} SQLSTATE: @code{HY000} (@code{ER_CANT_SET_WD})

Message: Can't change dir to '%s' (errno: %d)

@item Error: @code{1020} SQLSTATE: @code{HY000} (@code{ER_CHECKREAD})

Message: Record has changed since last read in table '%s'

@item Error: @code{1021} SQLSTATE: @code{HY000} (@code{ER_DISK_FULL})

Message: Disk full (%s); waiting for someone to free some space...

@item Error: @code{1022} SQLSTATE: @code{23000} (@code{ER_DUP_KEY})

Message: Can't write; duplicate key in table '%s'

@item Error: @code{1023} SQLSTATE: @code{HY000} (@code{ER_ERROR_ON_CLOSE})

Message: Error on close of '%s' (errno: %d)

@item Error: @code{1024} SQLSTATE: @code{HY000} (@code{ER_ERROR_ON_READ})

Message: Error reading file '%s' (errno: %d)

@item Error: @code{1025} SQLSTATE: @code{HY000} (@code{ER_ERROR_ON_RENAME})

Message: Error on rename of '%s' to '%s' (errno: %d)

@item Error: @code{1026} SQLSTATE: @code{HY000} (@code{ER_ERROR_ON_WRITE})

Message: Error writing file '%s' (errno: %d)

@item Error: @code{1027} SQLSTATE: @code{HY000} (@code{ER_FILE_USED})

Message: '%s' is locked against change

@item Error: @code{1028} SQLSTATE: @code{HY000} (@code{ER_FILSORT_ABORT})

Message: Sort aborted

@item Error: @code{1029} SQLSTATE: @code{HY000} (@code{ER_FORM_NOT_FOUND})

Message: View '%s' doesn't exist for '%s'

@item Error: @code{1030} SQLSTATE: @code{HY000} (@code{ER_GET_ERRNO})

Message: Got error %d from storage engine

@item Error: @code{1031} SQLSTATE: @code{HY000} (@code{ER_ILLEGAL_HA})

Message: Table storage engine for '%s' doesn't have this option

@item Error: @code{1032} SQLSTATE: @code{HY000} (@code{ER_KEY_NOT_FOUND})

Message: Can't find record in '%s'

@item Error: @code{1033} SQLSTATE: @code{HY000} (@code{ER_NOT_FORM_FILE})

Message: Incorrect information in file: '%s'

@item Error: @code{1034} SQLSTATE: @code{HY000} (@code{ER_NOT_KEYFILE})

Message: Incorrect key file for table '%s'; try to repair it

@item Error: @code{1035} SQLSTATE: @code{HY000} (@code{ER_OLD_KEYFILE})

Message: Old key file for table '%s'; repair it!

@item Error: @code{1036} SQLSTATE: @code{HY000} (@code{ER_OPEN_AS_READONLY})

Message: Table '%s' is read only

@item Error: @code{1037} SQLSTATE: @code{HY001} (@code{ER_OUTOFMEMORY})

Message: Out of memory; restart server and try again (needed %d bytes)

@item Error: @code{1038} SQLSTATE: @code{HY001} (@code{ER_OUT_OF_SORTMEMORY})

Message: Out of sort memory; increase server sort buffer size

@item Error: @code{1039} SQLSTATE: @code{HY000} (@code{ER_UNEXPECTED_EOF})

Message: Unexpected EOF found when reading file '%s' (errno: %d)

@item Error: @code{1040} SQLSTATE: @code{08004} (@code{ER_CON_COUNT_ERROR})

Message: Too many connections

@item Error: @code{1041} SQLSTATE: @code{HY000} (@code{ER_OUT_OF_RESOURCES})

Message: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space

@item Error: @code{1042} SQLSTATE: @code{08S01} (@code{ER_BAD_HOST_ERROR})

Message: Can't get hostname for your address

@item Error: @code{1043} SQLSTATE: @code{08S01} (@code{ER_HANDSHAKE_ERROR})

Message: Bad handshake

@item Error: @code{1044} SQLSTATE: @code{42000} (@code{ER_DBACCESS_DENIED_ERROR})

Message: Access denied for user '%s'@@'%s' to database '%s'

@item Error: @code{1045} SQLSTATE: @code{28000} (@code{ER_ACCESS_DENIED_ERROR})

Message: Access denied for user '%s'@@'%s' (using password: %s)

@item Error: @code{1046} SQLSTATE: @code{3D000} (@code{ER_NO_DB_ERROR})

Message: No database selected

@item Error: @code{1047} SQLSTATE: @code{08S01} (@code{ER_UNKNOWN_COM_ERROR})

Message: Unknown command

@item Error: @code{1048} SQLSTATE: @code{23000} (@code{ER_BAD_NULL_ERROR})

Message: Column '%s' cannot be null

@item Error: @code{1049} SQLSTATE: @code{42000} (@code{ER_BAD_DB_ERROR})

Message: Unknown database '%s'

@item Error: @code{1050} SQLSTATE: @code{42S01} (@code{ER_TABLE_EXISTS_ERROR})

Message: Table '%s' already exists

@item Error: @code{1051} SQLSTATE: @code{42S02} (@code{ER_BAD_TABLE_ERROR})

Message: Unknown table '%s'

@item Error: @code{1052} SQLSTATE: @code{23000} (@code{ER_NON_UNIQ_ERROR})

Message: Column '%s' in %s is ambiguous

@item Error: @code{1053} SQLSTATE: @code{08S01} (@code{ER_SERVER_SHUTDOWN})

Message: Server shutdown in progress

@item Error: @code{1054} SQLSTATE: @code{42S22} (@code{ER_BAD_FIELD_ERROR})

Message: Unknown column '%s' in '%s'

@item Error: @code{1055} SQLSTATE: @code{42000} (@code{ER_WRONG_FIELD_WITH_GROUP})

Message: '%s' isn't in GROUP BY

@item Error: @code{1056} SQLSTATE: @code{42000} (@code{ER_WRONG_GROUP_FIELD})

Message: Can't group on '%s'

@item Error: @code{1057} SQLSTATE: @code{42000} (@code{ER_WRONG_SUM_SELECT})

Message: Statement has sum functions and columns in same statement

@item Error: @code{1058} SQLSTATE: @code{21S01} (@code{ER_WRONG_VALUE_COUNT})

Message: Column count doesn't match value count

@item Error: @code{1059} SQLSTATE: @code{42000} (@code{ER_TOO_LONG_IDENT})

Message: Identifier name '%s' is too long

@item Error: @code{1060} SQLSTATE: @code{42S21} (@code{ER_DUP_FIELDNAME})

Message: Duplicate column name '%s'

@item Error: @code{1061} SQLSTATE: @code{42000} (@code{ER_DUP_KEYNAME})

Message: Duplicate key name '%s'

@item Error: @code{1062} SQLSTATE: @code{23000} (@code{ER_DUP_ENTRY})

Message: Duplicate entry '%s' for key %d

@item Error: @code{1063} SQLSTATE: @code{42000} (@code{ER_WRONG_FIELD_SPEC})

Message: Incorrect column specifier for column '%s'

@item Error: @code{1064} SQLSTATE: @code{42000} (@code{ER_PARSE_ERROR})

Message: %s near '%s' at line %d

@item Error: @code{1065} SQLSTATE: @code{HY000} (@code{ER_EMPTY_QUERY})

Message: Query was empty

@item Error: @code{1066} SQLSTATE: @code{42000} (@code{ER_NONUNIQ_TABLE})

Message: Not unique table/alias: '%s'

@item Error: @code{1067} SQLSTATE: @code{42000} (@code{ER_INVALID_DEFAULT})

Message: Invalid default value for '%s'

@item Error: @code{1068} SQLSTATE: @code{42000} (@code{ER_MULTIPLE_PRI_KEY})

Message: Multiple primary key defined

@item Error: @code{1069} SQLSTATE: @code{42000} (@code{ER_TOO_MANY_KEYS})

Message: Too many keys specified; max %d keys allowed

@item Error: @code{1070} SQLSTATE: @code{42000} (@code{ER_TOO_MANY_KEY_PARTS})

Message: Too many key parts specified; max %d parts allowed

@item Error: @code{1071} SQLSTATE: @code{42000} (@code{ER_TOO_LONG_KEY})

Message: Specified key was too long; max key length is %d bytes

@item Error: @code{1072} SQLSTATE: @code{42000} (@code{ER_KEY_COLUMN_DOES_NOT_EXITS})

Message: Key column '%s' doesn't exist in table

@item Error: @code{1073} SQLSTATE: @code{42000} (@code{ER_BLOB_USED_AS_KEY})

Message: BLOB column '%s' can't be used in key specification with the used table type

@item Error: @code{1074} SQLSTATE: @code{42000} (@code{ER_TOO_BIG_FIELDLENGTH})

Message: Column length too big for column '%s' (max = %d); use BLOB instead

@item Error: @code{1075} SQLSTATE: @code{42000} (@code{ER_WRONG_AUTO_KEY})

Message: Incorrect table definition; there can be only one auto column and it must be defined as a key

@item Error: @code{1076} SQLSTATE: @code{HY000} (@code{ER_READY})

Message: %s: ready for connections. Version: '%s'  socket: '%s'  port: %d

@item Error: @code{1077} SQLSTATE: @code{HY000} (@code{ER_NORMAL_SHUTDOWN})

Message: %s: Normal shutdown

@item Error: @code{1078} SQLSTATE: @code{HY000} (@code{ER_GOT_SIGNAL})

Message: %s: Got signal %d. Aborting!

@item Error: @code{1079} SQLSTATE: @code{HY000} (@code{ER_SHUTDOWN_COMPLETE})

Message: %s: Shutdown complete

@item Error: @code{1080} SQLSTATE: @code{08S01} (@code{ER_FORCING_CLOSE})

Message: %s: Forcing close of thread %ld  user: '%s'

@item Error: @code{1081} SQLSTATE: @code{08S01} (@code{ER_IPSOCK_ERROR})

Message: Can't create IP socket

@item Error: @code{1082} SQLSTATE: @code{42S12} (@code{ER_NO_SUCH_INDEX})

Message: Table '%s' has no index like the one used in CREATE INDEX; recreate the table

@item Error: @code{1083} SQLSTATE: @code{42000} (@code{ER_WRONG_FIELD_TERMINATORS})

Message: Field separator argument is not what is expected; check the manual

@item Error: @code{1084} SQLSTATE: @code{42000} (@code{ER_BLOBS_AND_NO_TERMINATED})

Message: You can't use fixed rowlength with BLOBs; please use 'fields terminated by'

@item Error: @code{1085} SQLSTATE: @code{HY000} (@code{ER_TEXTFILE_NOT_READABLE})

Message: The file '%s' must be in the database directory or be readable by all

@item Error: @code{1086} SQLSTATE: @code{HY000} (@code{ER_FILE_EXISTS_ERROR})

Message: File '%s' already exists

@item Error: @code{1087} SQLSTATE: @code{HY000} (@code{ER_LOAD_INFO})

Message: Records: %ld  Deleted: %ld  Skipped: %ld  Warnings: %ld

@item Error: @code{1088} SQLSTATE: @code{HY000} (@code{ER_ALTER_INFO})

Message: Records: %ld  Duplicates: %ld

@item Error: @code{1089} SQLSTATE: @code{HY000} (@code{ER_WRONG_SUB_KEY})

Message: Incorrect sub part key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique sub keys

@item Error: @code{1090} SQLSTATE: @code{42000} (@code{ER_CANT_REMOVE_ALL_FIELDS})

Message: You can't delete all columns with ALTER TABLE; use DROP TABLE instead

@item Error: @code{1091} SQLSTATE: @code{42000} (@code{ER_CANT_DROP_FIELD_OR_KEY})

Message: Can't DROP '%s'; check that column/key exists

@item Error: @code{1092} SQLSTATE: @code{HY000} (@code{ER_INSERT_INFO})

Message: Records: %ld  Duplicates: %ld  Warnings: %ld

@item Error: @code{1093} SQLSTATE: @code{HY000} (@code{ER_UPDATE_TABLE_USED})

Message: You can't specify target table '%s' for update in FROM clause

@item Error: @code{1094} SQLSTATE: @code{HY000} (@code{ER_NO_SUCH_THREAD})

Message: Unknown thread id: %lu

@item Error: @code{1095} SQLSTATE: @code{HY000} (@code{ER_KILL_DENIED_ERROR})

Message: You are not owner of thread %lu

@item Error: @code{1096} SQLSTATE: @code{HY000} (@code{ER_NO_TABLES_USED})

Message: No tables used

@item Error: @code{1097} SQLSTATE: @code{HY000} (@code{ER_TOO_BIG_SET})

Message: Too many strings for column %s and SET

@item Error: @code{1098} SQLSTATE: @code{HY000} (@code{ER_NO_UNIQUE_LOGFILE})

Message: Can't generate a unique log-filename %s.(1-999)

@item Error: @code{1099} SQLSTATE: @code{HY000} (@code{ER_TABLE_NOT_LOCKED_FOR_WRITE})

Message: Table '%s' was locked with a READ lock and can't be updated

@item Error: @code{1100} SQLSTATE: @code{HY000} (@code{ER_TABLE_NOT_LOCKED})

Message: Table '%s' was not locked with LOCK TABLES

@item Error: @code{1101} SQLSTATE: @code{42000} (@code{ER_BLOB_CANT_HAVE_DEFAULT})

Message: BLOB/TEXT column '%s' can't have a default value

@item Error: @code{1102} SQLSTATE: @code{42000} (@code{ER_WRONG_DB_NAME})

Message: Incorrect database name '%s'

@item Error: @code{1103} SQLSTATE: @code{42000} (@code{ER_WRONG_TABLE_NAME})

Message: Incorrect table name '%s'

@item Error: @code{1104} SQLSTATE: @code{42000} (@code{ER_TOO_BIG_SELECT})

Message: The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is okay

@item Error: @code{1105} SQLSTATE: @code{HY000} (@code{ER_UNKNOWN_ERROR})

Message: Unknown error

@item Error: @code{1106} SQLSTATE: @code{42000} (@code{ER_UNKNOWN_PROCEDURE})

Message: Unknown procedure '%s'

@item Error: @code{1107} SQLSTATE: @code{42000} (@code{ER_WRONG_PARAMCOUNT_TO_PROCEDURE})

Message: Incorrect parameter count to procedure '%s'

@item Error: @code{1108} SQLSTATE: @code{HY000} (@code{ER_WRONG_PARAMETERS_TO_PROCEDURE})

Message: Incorrect parameters to procedure '%s'

@item Error: @code{1109} SQLSTATE: @code{42S02} (@code{ER_UNKNOWN_TABLE})

Message: Unknown table '%s' in %s

@item Error: @code{1110} SQLSTATE: @code{42000} (@code{ER_FIELD_SPECIFIED_TWICE})

Message: Column '%s' specified twice

@item Error: @code{1111} SQLSTATE: @code{HY000} (@code{ER_INVALID_GROUP_FUNC_USE})

Message: Invalid use of group function

@item Error: @code{1112} SQLSTATE: @code{42000} (@code{ER_UNSUPPORTED_EXTENSION})

Message: Table '%s' uses an extension that doesn't exist in this MySQL version

@item Error: @code{1113} SQLSTATE: @code{42000} (@code{ER_TABLE_MUST_HAVE_COLUMNS})

Message: A table must have at least 1 column

@item Error: @code{1114} SQLSTATE: @code{HY000} (@code{ER_RECORD_FILE_FULL})

Message: The table '%s' is full

@item Error: @code{1115} SQLSTATE: @code{42000} (@code{ER_UNKNOWN_CHARACTER_SET})

Message: Unknown character set: '%s'

@item Error: @code{1116} SQLSTATE: @code{HY000} (@code{ER_TOO_MANY_TABLES})

Message: Too many tables; MySQL can only use %d tables in a join

@item Error: @code{1117} SQLSTATE: @code{HY000} (@code{ER_TOO_MANY_FIELDS})

Message: Too many columns

@item Error: @code{1118} SQLSTATE: @code{42000} (@code{ER_TOO_BIG_ROWSIZE})

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

@item Error: @code{1119} SQLSTATE: @code{HY000} (@code{ER_STACK_OVERRUN})

Message: Thread stack overrun:  Used: %ld of a %ld stack.  Use 'mysqld -O thread_stack=#' to specify a bigger stack if needed

@item Error: @code{1120} SQLSTATE: @code{42000} (@code{ER_WRONG_OUTER_JOIN})

Message: Cross dependency found in OUTER JOIN; examine your ON conditions

@item Error: @code{1121} SQLSTATE: @code{42000} (@code{ER_NULL_COLUMN_IN_INDEX})

Message: Column '%s' is used with UNIQUE or INDEX but is not defined as NOT NULL

@item Error: @code{1122} SQLSTATE: @code{HY000} (@code{ER_CANT_FIND_UDF})

Message: Can't load function '%s'

@item Error: @code{1123} SQLSTATE: @code{HY000} (@code{ER_CANT_INITIALIZE_UDF})

Message: Can't initialize function '%s'; %s

@item Error: @code{1124} SQLSTATE: @code{HY000} (@code{ER_UDF_NO_PATHS})

Message: No paths allowed for shared library

@item Error: @code{1125} SQLSTATE: @code{HY000} (@code{ER_UDF_EXISTS})

Message: Function '%s' already exists

@item Error: @code{1126} SQLSTATE: @code{HY000} (@code{ER_CANT_OPEN_LIBRARY})

Message: Can't open shared library '%s' (errno: %d %s)

@item Error: @code{1127} SQLSTATE: @code{HY000} (@code{ER_CANT_FIND_DL_ENTRY})

Message: Can't find function '%s' in library'

@item Error: @code{1128} SQLSTATE: @code{HY000} (@code{ER_FUNCTION_NOT_DEFINED})

Message: Function '%s' is not defined

@item Error: @code{1129} SQLSTATE: @code{HY000} (@code{ER_HOST_IS_BLOCKED})

Message: Host '%s' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'

@item Error: @code{1130} SQLSTATE: @code{HY000} (@code{ER_HOST_NOT_PRIVILEGED})

Message: Host '%s' is not allowed to connect to this MySQL server

@item Error: @code{1131} SQLSTATE: @code{42000} (@code{ER_PASSWORD_ANONYMOUS_USER})

Message: You are using MySQL as an anonymous user and anonymous users are not allowed to change passwords

@item Error: @code{1132} SQLSTATE: @code{42000} (@code{ER_PASSWORD_NOT_ALLOWED})

Message: You must have privileges to update tables in the mysql database to be able to change passwords for others

@item Error: @code{1133} SQLSTATE: @code{42000} (@code{ER_PASSWORD_NO_MATCH})

Message: Can't find any matching row in the user table

@item Error: @code{1134} SQLSTATE: @code{HY000} (@code{ER_UPDATE_INFO})

Message: Rows matched: %ld  Changed: %ld  Warnings: %ld

@item Error: @code{1135} SQLSTATE: @code{HY000} (@code{ER_CANT_CREATE_THREAD})

Message: Can't create a new thread (errno %d); if you are not out of available memory, you can consult the manual for a possible OS-dependent bug

@item Error: @code{1136} SQLSTATE: @code{21S01} (@code{ER_WRONG_VALUE_COUNT_ON_ROW})

Message: Column count doesn't match value count at row %ld

@item Error: @code{1137} SQLSTATE: @code{HY000} (@code{ER_CANT_REOPEN_TABLE})

Message: Can't reopen table: '%s'

@item Error: @code{1138} SQLSTATE: @code{22004} (@code{ER_INVALID_USE_OF_NULL})

Message: Invalid use of NULL value

@item Error: @code{1139} SQLSTATE: @code{42000} (@code{ER_REGEXP_ERROR})

Message: Got error '%s' from regexp

@item Error: @code{1140} SQLSTATE: @code{42000} (@code{ER_MIX_OF_GROUP_FUNC_AND_FIELDS})

Message: Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause

@item Error: @code{1141} SQLSTATE: @code{42000} (@code{ER_NONEXISTING_GRANT})

Message: There is no such grant defined for user '%s' on host '%s'

@item Error: @code{1142} SQLSTATE: @code{42000} (@code{ER_TABLEACCESS_DENIED_ERROR})

Message: %s command denied to user '%s'@@'%s' for table '%s'

@item Error: @code{1143} SQLSTATE: @code{42000} (@code{ER_COLUMNACCESS_DENIED_ERROR})

Message: %s command denied to user '%s'@@'%s' for column '%s' in table '%s'

@item Error: @code{1144} SQLSTATE: @code{42000} (@code{ER_ILLEGAL_GRANT_FOR_TABLE})

Message: Illegal GRANT/REVOKE command; please consult the manual to see which privileges can be used

@item Error: @code{1145} SQLSTATE: @code{42000} (@code{ER_GRANT_WRONG_HOST_OR_USER})

Message: The host or user argument to GRANT is too long

@item Error: @code{1146} SQLSTATE: @code{42S02} (@code{ER_NO_SUCH_TABLE})

Message: Table '%s.%s' doesn't exist

@item Error: @code{1147} SQLSTATE: @code{42000} (@code{ER_NONEXISTING_TABLE_GRANT})

Message: There is no such grant defined for user '%s' on host '%s' on table '%s'

@item Error: @code{1148} SQLSTATE: @code{42000} (@code{ER_NOT_ALLOWED_COMMAND})

Message: The used command is not allowed with this MySQL version

@item Error: @code{1149} SQLSTATE: @code{42000} (@code{ER_SYNTAX_ERROR})

Message: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use

@item Error: @code{1150} SQLSTATE: @code{HY000} (@code{ER_DELAYED_CANT_CHANGE_LOCK})

Message: Delayed insert thread couldn't get requested lock for table %s

@item Error: @code{1151} SQLSTATE: @code{HY000} (@code{ER_TOO_MANY_DELAYED_THREADS})

Message: Too many delayed threads in use

@item Error: @code{1152} SQLSTATE: @code{08S01} (@code{ER_ABORTING_CONNECTION})

Message: Aborted connection %ld to db: '%s' user: '%s' (%s)

@item Error: @code{1153} SQLSTATE: @code{08S01} (@code{ER_NET_PACKET_TOO_LARGE})

Message: Got a packet bigger than 'max_allowed_packet' bytes

@item Error: @code{1154} SQLSTATE: @code{08S01} (@code{ER_NET_READ_ERROR_FROM_PIPE})

Message: Got a read error from the connection pipe

@item Error: @code{1155} SQLSTATE: @code{08S01} (@code{ER_NET_FCNTL_ERROR})

Message: Got an error from fcntl()

@item Error: @code{1156} SQLSTATE: @code{08S01} (@code{ER_NET_PACKETS_OUT_OF_ORDER})

Message: Got packets out of order

@item Error: @code{1157} SQLSTATE: @code{08S01} (@code{ER_NET_UNCOMPRESS_ERROR})

Message: Couldn't uncompress communication packet

@item Error: @code{1158} SQLSTATE: @code{08S01} (@code{ER_NET_READ_ERROR})

Message: Got an error reading communication packets

@item Error: @code{1159} SQLSTATE: @code{08S01} (@code{ER_NET_READ_INTERRUPTED})

Message: Got timeout reading communication packets

@item Error: @code{1160} SQLSTATE: @code{08S01} (@code{ER_NET_ERROR_ON_WRITE})

Message: Got an error writing communication packets

@item Error: @code{1161} SQLSTATE: @code{08S01} (@code{ER_NET_WRITE_INTERRUPTED})

Message: Got timeout writing communication packets

@item Error: @code{1162} SQLSTATE: @code{42000} (@code{ER_TOO_LONG_STRING})

Message: Result string is longer than 'max_allowed_packet' bytes

@item Error: @code{1163} SQLSTATE: @code{42000} (@code{ER_TABLE_CANT_HANDLE_BLOB})

Message: The used table type doesn't support BLOB/TEXT columns

@item Error: @code{1164} SQLSTATE: @code{42000} (@code{ER_TABLE_CANT_HANDLE_AUTO_INCREMENT})

Message: The used table type doesn't support AUTO_INCREMENT columns

@item Error: @code{1165} SQLSTATE: @code{HY000} (@code{ER_DELAYED_INSERT_TABLE_LOCKED})

Message: INSERT DELAYED can't be used with table '%s' because it is locked with LOCK TABLES

@item Error: @code{1166} SQLSTATE: @code{42000} (@code{ER_WRONG_COLUMN_NAME})

Message: Incorrect column name '%s'

@item Error: @code{1167} SQLSTATE: @code{42000} (@code{ER_WRONG_KEY_COLUMN})

Message: The used storage engine can't index column '%s'

@item Error: @code{1168} SQLSTATE: @code{HY000} (@code{ER_WRONG_MRG_TABLE})

Message: All tables in the MERGE table are not identically defined

@item Error: @code{1169} SQLSTATE: @code{23000} (@code{ER_DUP_UNIQUE})

Message: Can't write, because of unique constraint, to table '%s'

@item Error: @code{1170} SQLSTATE: @code{42000} (@code{ER_BLOB_KEY_WITHOUT_LENGTH})

Message: BLOB/TEXT column '%s' used in key specification without a key length

@item Error: @code{1171} SQLSTATE: @code{42000} (@code{ER_PRIMARY_CANT_HAVE_NULL})

Message: All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead

@item Error: @code{1172} SQLSTATE: @code{42000} (@code{ER_TOO_MANY_ROWS})

Message: Result consisted of more than one row

@item Error: @code{1173} SQLSTATE: @code{42000} (@code{ER_REQUIRES_PRIMARY_KEY})

Message: This table type requires a primary key

@item Error: @code{1174} SQLSTATE: @code{HY000} (@code{ER_NO_RAID_COMPILED})

Message: This version of MySQL is not compiled with RAID support

@item Error: @code{1175} SQLSTATE: @code{HY000} (@code{ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE})

Message: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column

@item Error: @code{1176} SQLSTATE: @code{HY000} (@code{ER_KEY_DOES_NOT_EXITS})

Message: Key '%s' doesn't exist in table '%s'

@item Error: @code{1177} SQLSTATE: @code{42000} (@code{ER_CHECK_NO_SUCH_TABLE})

Message: Can't open table

@item Error: @code{1178} SQLSTATE: @code{42000} (@code{ER_CHECK_NOT_IMPLEMENTED})

Message: The storage engine for the table doesn't support %s

@item Error: @code{1179} SQLSTATE: @code{25000} (@code{ER_CANT_DO_THIS_DURING_AN_TRANSACTION})

Message: You are not allowed to execute this command in a transaction

@item Error: @code{1180} SQLSTATE: @code{HY000} (@code{ER_ERROR_DURING_COMMIT})

Message: Got error %d during COMMIT

@item Error: @code{1181} SQLSTATE: @code{HY000} (@code{ER_ERROR_DURING_ROLLBACK})

Message: Got error %d during ROLLBACK

@item Error: @code{1182} SQLSTATE: @code{HY000} (@code{ER_ERROR_DURING_FLUSH_LOGS})

Message: Got error %d during FLUSH_LOGS

@item Error: @code{1183} SQLSTATE: @code{HY000} (@code{ER_ERROR_DURING_CHECKPOINT})

Message: Got error %d during CHECKPOINT

@item Error: @code{1184} SQLSTATE: @code{08S01} (@code{ER_NEW_ABORTING_CONNECTION})

Message: Aborted connection %ld to db: '%s' user: '%s' host: `%s' (%s)

@item Error: @code{1185} SQLSTATE: @code{HY000} (@code{ER_DUMP_NOT_IMPLEMENTED})

Message: The storage engine for the table does not support binary table dump

@item Error: @code{1186} SQLSTATE: @code{HY000} (@code{ER_FLUSH_MASTER_BINLOG_CLOSED})

Message: Binlog closed, cannot RESET MASTER

@item Error: @code{1187} SQLSTATE: @code{HY000} (@code{ER_INDEX_REBUILD})

Message: Failed rebuilding the index of  dumped table '%s'

@item Error: @code{1188} SQLSTATE: @code{HY000} (@code{ER_MASTER})

Message: Error from master: '%s'

@item Error: @code{1189} SQLSTATE: @code{08S01} (@code{ER_MASTER_NET_READ})

Message: Net error reading from master

@item Error: @code{1190} SQLSTATE: @code{08S01} (@code{ER_MASTER_NET_WRITE})

Message: Net error writing to master

@item Error: @code{1191} SQLSTATE: @code{HY000} (@code{ER_FT_MATCHING_KEY_NOT_FOUND})

Message: Can't find FULLTEXT index matching the column list

@item Error: @code{1192} SQLSTATE: @code{HY000} (@code{ER_LOCK_OR_ACTIVE_TRANSACTION})

Message: Can't execute the given command because you have active locked tables or an active transaction

@item Error: @code{1193} SQLSTATE: @code{HY000} (@code{ER_UNKNOWN_SYSTEM_VARIABLE})

Message: Unknown system variable '%s'

@item Error: @code{1194} SQLSTATE: @code{HY000} (@code{ER_CRASHED_ON_USAGE})

Message: Table '%s' is marked as crashed and should be repaired

@item Error: @code{1195} SQLSTATE: @code{HY000} (@code{ER_CRASHED_ON_REPAIR})

Message: Table '%s' is marked as crashed and last (automatic?) repair failed

@item Error: @code{1196} SQLSTATE: @code{HY000} (@code{ER_WARNING_NOT_COMPLETE_ROLLBACK})

Message: Some non-transactional changed tables couldn't be rolled back

@item Error: @code{1197} SQLSTATE: @code{HY000} (@code{ER_TRANS_CACHE_FULL})

Message: Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage; increase this mysqld variable and try again

@item Error: @code{1198} SQLSTATE: @code{HY000} (@code{ER_SLAVE_MUST_STOP})

Message: This operation cannot be performed with a running slave; run STOP SLAVE first

@item Error: @code{1199} SQLSTATE: @code{HY000} (@code{ER_SLAVE_NOT_RUNNING})

Message: This operation requires a running slave; configure slave and do START SLAVE

@item Error: @code{1200} SQLSTATE: @code{HY000} (@code{ER_BAD_SLAVE})

Message: The server is not configured as slave; fix in config file or with CHANGE MASTER TO

@item Error: @code{1201} SQLSTATE: @code{HY000} (@code{ER_MASTER_INFO})

Message: Could not initialize master info structure; more error messages can be found in the MySQL error log

@item Error: @code{1202} SQLSTATE: @code{HY000} (@code{ER_SLAVE_THREAD})

Message: Could not create slave thread; check system resources

@item Error: @code{1203} SQLSTATE: @code{42000} (@code{ER_TOO_MANY_USER_CONNECTIONS})

Message: User %s has already more than 'max_user_connections' active connections

@item Error: @code{1204} SQLSTATE: @code{HY000} (@code{ER_SET_CONSTANTS_ONLY})

Message: You may only use constant expressions with SET

@item Error: @code{1205} SQLSTATE: @code{HY000} (@code{ER_LOCK_WAIT_TIMEOUT})

Message: Lock wait timeout exceeded; try restarting transaction

@item Error: @code{1206} SQLSTATE: @code{HY000} (@code{ER_LOCK_TABLE_FULL})

Message: The total number of locks exceeds the lock table size

@item Error: @code{1207} SQLSTATE: @code{25000} (@code{ER_READ_ONLY_TRANSACTION})

Message: Update locks cannot be acquired during a READ UNCOMMITTED transaction

@item Error: @code{1208} SQLSTATE: @code{HY000} (@code{ER_DROP_DB_WITH_READ_LOCK})

Message: DROP DATABASE not allowed while thread is holding global read lock

@item Error: @code{1209} SQLSTATE: @code{HY000} (@code{ER_CREATE_DB_WITH_READ_LOCK})

Message: CREATE DATABASE not allowed while thread is holding global read lock

@item Error: @code{1210} SQLSTATE: @code{HY000} (@code{ER_WRONG_ARGUMENTS})

Message: Incorrect arguments to %s

@item Error: @code{1211} SQLSTATE: @code{42000} (@code{ER_NO_PERMISSION_TO_CREATE_USER})

Message: '%s'@@'%s' is not allowed to create new users

@item Error: @code{1212} SQLSTATE: @code{HY000} (@code{ER_UNION_TABLES_IN_DIFFERENT_DIR})

Message: Incorrect table definition; all MERGE tables must be in the same database

@item Error: @code{1213} SQLSTATE: @code{40001} (@code{ER_LOCK_DEADLOCK})

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

@item Error: @code{1214} SQLSTATE: @code{HY000} (@code{ER_TABLE_CANT_HANDLE_FT})

Message: The used table type doesn't support FULLTEXT indexes

@item Error: @code{1215} SQLSTATE: @code{HY000} (@code{ER_CANNOT_ADD_FOREIGN})

Message: Cannot add foreign key constraint

@item Error: @code{1216} SQLSTATE: @code{23000} (@code{ER_NO_REFERENCED_ROW})

Message: Cannot add or update a child row: a foreign key constraint fails

@item Error: @code{1217} SQLSTATE: @code{23000} (@code{ER_ROW_IS_REFERENCED})

Message: Cannot delete or update a parent row: a foreign key constraint fails

@item Error: @code{1218} SQLSTATE: @code{08S01} (@code{ER_CONNECT_TO_MASTER})

Message: Error connecting to master: %s

@item Error: @code{1219} SQLSTATE: @code{HY000} (@code{ER_QUERY_ON_MASTER})

Message: Error running query on master: %s

@item Error: @code{1220} SQLSTATE: @code{HY000} (@code{ER_ERROR_WHEN_EXECUTING_COMMAND})

Message: Error when executing command %s: %s

@item Error: @code{1221} SQLSTATE: @code{HY000} (@code{ER_WRONG_USAGE})

Message: Incorrect usage of %s and %s

@item Error: @code{1222} SQLSTATE: @code{21000} (@code{ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT})

Message: The used SELECT statements have a different number of columns

@item Error: @code{1223} SQLSTATE: @code{HY000} (@code{ER_CANT_UPDATE_WITH_READLOCK})

Message: Can't execute the query because you have a conflicting read lock

@item Error: @code{1224} SQLSTATE: @code{HY000} (@code{ER_MIXING_NOT_ALLOWED})

Message: Mixing of transactional and non-transactional tables is disabled

@item Error: @code{1225} SQLSTATE: @code{HY000} (@code{ER_DUP_ARGUMENT})

Message: Option '%s' used twice in statement

@item Error: @code{1226} SQLSTATE: @code{42000} (@code{ER_USER_LIMIT_REACHED})

Message: User '%s' has exceeded the '%s' resource (current value: %ld)

@item Error: @code{1227} SQLSTATE: @code{HY000} (@code{ER_SPECIFIC_ACCESS_DENIED_ERROR})

Message: Access denied; you need the %s privilege for this operation

@item Error: @code{1228} SQLSTATE: @code{HY000} (@code{ER_LOCAL_VARIABLE})

Message: Variable '%s' is a SESSION variable and can't be used with SET GLOBAL

@item Error: @code{1229} SQLSTATE: @code{HY000} (@code{ER_GLOBAL_VARIABLE})

Message: Variable '%s' is a GLOBAL variable and should be set with SET GLOBAL

@item Error: @code{1230} SQLSTATE: @code{42000} (@code{ER_NO_DEFAULT})

Message: Variable '%s' doesn't have a default value

@item Error: @code{1231} SQLSTATE: @code{42000} (@code{ER_WRONG_VALUE_FOR_VAR})

Message: Variable '%s' can't be set to the value of '%s'

@item Error: @code{1232} SQLSTATE: @code{42000} (@code{ER_WRONG_TYPE_FOR_VAR})

Message: Incorrect argument type to variable '%s'

@item Error: @code{1233} SQLSTATE: @code{HY000} (@code{ER_VAR_CANT_BE_READ})

Message: Variable '%s' can only be set, not read

@item Error: @code{1234} SQLSTATE: @code{42000} (@code{ER_CANT_USE_OPTION_HERE})

Message: Incorrect usage/placement of '%s'

@item Error: @code{1235} SQLSTATE: @code{42000} (@code{ER_NOT_SUPPORTED_YET})

Message: This version of MySQL doesn't yet support '%s'

@item Error: @code{1236} SQLSTATE: @code{HY000} (@code{ER_MASTER_FATAL_ERROR_READING_BINLOG})

Message: Got fatal error %d: '%s' from master when reading data from binary log

@item Error: @code{1237} SQLSTATE: @code{HY000} (@code{ER_SLAVE_IGNORED_TABLE})

Message: Slave SQL thread ignored the query because of replicate-*-table rules

@item Error: @code{1238} SQLSTATE: @code{HY000} (@code{ER_INCORRECT_GLOBAL_LOCAL_VAR})

Message: Variable '%s' is a %s variable

@item Error: @code{1239} SQLSTATE: @code{42000} (@code{ER_WRONG_FK_DEF})

Message: Incorrect foreign key definition for '%s': %s

@item Error: @code{1240} SQLSTATE: @code{HY000} (@code{ER_KEY_REF_DO_NOT_MATCH_TABLE_REF})

Message: Key reference and table reference don't match

@item Error: @code{1241} SQLSTATE: @code{21000} (@code{ER_OPERAND_COLUMNS})

Message: Operand should contain %d column(s)

@item Error: @code{1242} SQLSTATE: @code{21000} (@code{ER_SUBQUERY_NO_1_ROW})

Message: Subquery returns more than 1 row

@item Error: @code{1243} SQLSTATE: @code{HY000} (@code{ER_UNKNOWN_STMT_HANDLER})

Message: Unknown prepared statement handler (%.*s) given to %s

@item Error: @code{1244} SQLSTATE: @code{HY000} (@code{ER_CORRUPT_HELP_DB})

Message: Help database is corrupt or does not exist

@item Error: @code{1245} SQLSTATE: @code{HY000} (@code{ER_CYCLIC_REFERENCE})

Message: Cyclic reference on subqueries

@item Error: @code{1246} SQLSTATE: @code{HY000} (@code{ER_AUTO_CONVERT})

Message: Converting column '%s' from %s to %s

@item Error: @code{1247} SQLSTATE: @code{42S22} (@code{ER_ILLEGAL_REFERENCE})

Message: Reference '%s' not supported (%s)

@item Error: @code{1248} SQLSTATE: @code{42000} (@code{ER_DERIVED_MUST_HAVE_ALIAS})

Message: Every derived table must have its own alias

@item Error: @code{1249} SQLSTATE: @code{01000} (@code{ER_SELECT_REDUCED})

Message: Select %u was reduced during optimization

@item Error: @code{1250} SQLSTATE: @code{42000} (@code{ER_TABLENAME_NOT_ALLOWED_HERE})

Message: Table '%s' from one of the SELECTs cannot be used in %s

@item Error: @code{1251} SQLSTATE: @code{08004} (@code{ER_NOT_SUPPORTED_AUTH_MODE})

Message: Client does not support authentication protocol requested by server; consider upgrading MySQL client

@item Error: @code{1252} SQLSTATE: @code{42000} (@code{ER_SPATIAL_CANT_HAVE_NULL})

Message: All parts of a SPATIAL index must be NOT NULL

@item Error: @code{1253} SQLSTATE: @code{42000} (@code{ER_COLLATION_CHARSET_MISMATCH})

Message: COLLATION '%s' is not valid for CHARACTER SET '%s'

@item Error: @code{1254} SQLSTATE: @code{HY000} (@code{ER_SLAVE_WAS_RUNNING})

Message: Slave is already running

@item Error: @code{1255} SQLSTATE: @code{HY000} (@code{ER_SLAVE_WAS_NOT_RUNNING})

Message: Slave has already been stopped

@item Error: @code{1256} SQLSTATE: @code{HY000} (@code{ER_TOO_BIG_FOR_UNCOMPRESS})

Message: Uncompressed data size too large; the maximum size is %d (probably, length of uncompressed data was corrupted)

@item Error: @code{1257} SQLSTATE: @code{HY000} (@code{ER_ZLIB_Z_MEM_ERROR})

Message: ZLIB: Not enough memory

@item Error: @code{1258} SQLSTATE: @code{HY000} (@code{ER_ZLIB_Z_BUF_ERROR})

Message: ZLIB: Not enough room in the output buffer (probably, length of uncompressed data was corrupted)

@item Error: @code{1259} SQLSTATE: @code{HY000} (@code{ER_ZLIB_Z_DATA_ERROR})

Message: ZLIB: Input data corrupted

@item Error: @code{1260} SQLSTATE: @code{HY000} (@code{ER_CUT_VALUE_GROUP_CONCAT})

Message: %d line(s) were cut by GROUP_CONCAT()

@item Error: @code{1261} SQLSTATE: @code{01000} (@code{ER_WARN_TOO_FEW_RECORDS})

Message: Row %ld doesn't contain data for all columns

@item Error: @code{1262} SQLSTATE: @code{01000} (@code{ER_WARN_TOO_MANY_RECORDS})

Message: Row %ld was truncated; it contained more data than there were input columns

@item Error: @code{1263} SQLSTATE: @code{22004} (@code{ER_WARN_NULL_TO_NOTNULL})

Message: Column set to default value; NULL supplied to NOT NULL column '%s' at row %ld

@item Error: @code{1264} SQLSTATE: @code{22003} (@code{ER_WARN_DATA_OUT_OF_RANGE})

Message: Out of range value adjusted for column '%s' at row %ld

@item Error: @code{1265} SQLSTATE: @code{01000} (@code{ER_WARN_DATA_TRUNCATED})

Message: Data truncated for column '%s' at row %ld

@item Error: @code{1266} SQLSTATE: @code{HY000} (@code{ER_WARN_USING_OTHER_HANDLER})

Message: Using storage engine %s for table '%s'

@item Error: @code{1267} SQLSTATE: @code{HY000} (@code{ER_CANT_AGGREGATE_2COLLATIONS})

Message: Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'

@item Error: @code{1268} SQLSTATE: @code{HY000} (@code{ER_DROP_USER})

Message: Can't drop one or more of the requested users

@item Error: @code{1269} SQLSTATE: @code{HY000} (@code{ER_REVOKE_GRANTS})

Message: Can't revoke all privileges, grant for one or more of the requested users

@item Error: @code{1270} SQLSTATE: @code{HY000} (@code{ER_CANT_AGGREGATE_3COLLATIONS})

Message: Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'

@item Error: @code{1271} SQLSTATE: @code{HY000} (@code{ER_CANT_AGGREGATE_NCOLLATIONS})

Message: Illegal mix of collations for operation '%s'

@item Error: @code{1272} SQLSTATE: @code{HY000} (@code{ER_VARIABLE_IS_NOT_STRUCT})

Message: Variable '%s' is not a variable component (can't be used as XXXX.variable_name)

@item Error: @code{1273} SQLSTATE: @code{HY000} (@code{ER_UNKNOWN_COLLATION})

Message: Unknown collation: '%s'

@item Error: @code{1274} SQLSTATE: @code{HY000} (@code{ER_SLAVE_IGNORED_SSL_PARAMS})

Message: SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support; they can be used later if MySQL slave with SSL is started

@item Error: @code{1275} SQLSTATE: @code{HY000} (@code{ER_SERVER_IS_IN_SECURE_AUTH_MODE})

Message: Server is running in --secure-auth mode, but '%s'@@'%s' has a password in the old format; please change the password to the new format

@item Error: @code{1276} SQLSTATE: @code{HY000} (@code{ER_WARN_FIELD_RESOLVED})

Message: Field or reference '%s%s%s%s%s' of SELECT #%d was resolved in SELECT #%d

@item Error: @code{1277} SQLSTATE: @code{HY000} (@code{ER_BAD_SLAVE_UNTIL_COND})

Message: Incorrect parameter or combination of parameters for START SLAVE UNTIL

@item Error: @code{1278} SQLSTATE: @code{HY000} (@code{ER_MISSING_SKIP_SLAVE})

Message: It is recommended to use --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL; otherwise, you will get problems if you get an unexpected slave's mysqld restart

@item Error: @code{1279} SQLSTATE: @code{HY000} (@code{ER_UNTIL_COND_IGNORED})

Message: SQL thread is not to be started so UNTIL options are ignored

@item Error: @code{1280} SQLSTATE: @code{42000} (@code{ER_WRONG_NAME_FOR_INDEX})

Message: Incorrect index name '%s'

@item Error: @code{1281} SQLSTATE: @code{42000} (@code{ER_WRONG_NAME_FOR_CATALOG})

Message: Incorrect catalog name '%s'

@item Error: @code{1282} SQLSTATE: @code{HY000} (@code{ER_WARN_QC_RESIZE})

Message: Query cache failed to set size %lu; new query cache size is %lu

@item Error: @code{1283} SQLSTATE: @code{HY000} (@code{ER_BAD_FT_COLUMN})

Message: Column '%s' cannot be part of FULLTEXT index

@item Error: @code{1284} SQLSTATE: @code{HY000} (@code{ER_UNKNOWN_KEY_CACHE})

Message: Unknown key cache '%s'

@item Error: @code{1285} SQLSTATE: @code{HY000} (@code{ER_WARN_HOSTNAME_WONT_WORK})

Message: MySQL is started in --skip-name-resolve mode; you must restart it without this switch for this grant to work

@item Error: @code{1286} SQLSTATE: @code{42000} (@code{ER_UNKNOWN_STORAGE_ENGINE})

Message: Unknown table engine '%s'

@item Error: @code{1287} SQLSTATE: @code{HY000} (@code{ER_WARN_DEPRECATED_SYNTAX})

Message: '%s' is deprecated; use '%s' instead

@item Error: @code{1288} SQLSTATE: @code{HY000} (@code{ER_NON_UPDATABLE_TABLE})

Message: The target table %s of the %s is not updatable

@item Error: @code{1289} SQLSTATE: @code{HY000} (@code{ER_FEATURE_DISABLED})

Message: The '%s' feature is disabled; you need MySQL built with '%s' to have it working

@item Error: @code{1290} SQLSTATE: @code{HY000} (@code{ER_OPTION_PREVENTS_STATEMENT})

Message: The MySQL server is running with the %s option so it cannot execute this statement

@item Error: @code{1291} SQLSTATE: @code{HY000} (@code{ER_DUPLICATED_VALUE_IN_TYPE})

Message: Column '%s' has duplicated value '%s' in %s

@item Error: @code{1292} SQLSTATE: @code{22007} (@code{ER_TRUNCATED_WRONG_VALUE})

Message: Truncated incorrect %s value: '%s'

@item Error: @code{1293} SQLSTATE: @code{HY000} (@code{ER_TOO_MUCH_AUTO_TIMESTAMP_COLS})

Message: Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause

@item Error: @code{1294} SQLSTATE: @code{HY000} (@code{ER_INVALID_ON_UPDATE})

Message: Invalid ON UPDATE clause for '%s' column

@item Error: @code{1295} SQLSTATE: @code{HY000} (@code{ER_UNSUPPORTED_PS})

Message: This command is not supported in the prepared statement protocol yet

@item Error: @code{1296} SQLSTATE: @code{HY000} (@code{ER_GET_ERRMSG})

Message: Got error %d '%s' from %s

@item Error: @code{1297} SQLSTATE: @code{HY000} (@code{ER_GET_TEMPORARY_ERRMSG})

Message: Got temporary error %d '%s' from %s

@item Error: @code{1298} SQLSTATE: @code{HY000} (@code{ER_UNKNOWN_TIME_ZONE})

Message: Unknown or incorrect time zone: '%s'

@item Error: @code{1299} SQLSTATE: @code{HY000} (@code{ER_WARN_INVALID_TIMESTAMP})

Message: Invalid TIMESTAMP value in column '%s' at row %ld

@item Error: @code{1300} SQLSTATE: @code{HY000} (@code{ER_INVALID_CHARACTER_STRING})

Message: Invalid %s character string: '%s'

@item Error: @code{1301} SQLSTATE: @code{HY000} (@code{ER_WARN_ALLOWED_PACKET_OVERFLOWED})

Message: Result of %s() was larger than max_allowed_packet (%ld) - truncated

@item Error: @code{1302} SQLSTATE: @code{HY000} (@code{ER_CONFLICTING_DECLARATIONS})

Message: Conflicting declarations: '%s%s' and '%s%s'

@item Error: @code{1303} SQLSTATE: @code{2F003} (@code{ER_SP_NO_RECURSIVE_CREATE})

Message: Can't create a %s from within another stored routine

@item Error: @code{1304} SQLSTATE: @code{42000} (@code{ER_SP_ALREADY_EXISTS})

Message: %s %s already exists

@item Error: @code{1305} SQLSTATE: @code{42000} (@code{ER_SP_DOES_NOT_EXIST})

Message: %s %s does not exist

@item Error: @code{1306} SQLSTATE: @code{HY000} (@code{ER_SP_DROP_FAILED})

Message: Failed to DROP %s %s

@item Error: @code{1307} SQLSTATE: @code{HY000} (@code{ER_SP_STORE_FAILED})

Message: Failed to CREATE %s %s

@item Error: @code{1308} SQLSTATE: @code{42000} (@code{ER_SP_LILABEL_MISMATCH})

Message: %s with no matching label: %s

@item Error: @code{1309} SQLSTATE: @code{42000} (@code{ER_SP_LABEL_REDEFINE})

Message: Redefining label %s

@item Error: @code{1310} SQLSTATE: @code{42000} (@code{ER_SP_LABEL_MISMATCH})

Message: End-label %s without match

@item Error: @code{1311} SQLSTATE: @code{01000} (@code{ER_SP_UNINIT_VAR})

Message: Referring to uninitialized variable %s

@item Error: @code{1312} SQLSTATE: @code{0A000} (@code{ER_SP_BADSELECT})

Message: SELECT in a stored procedure must have INTO

@item Error: @code{1313} SQLSTATE: @code{42000} (@code{ER_SP_BADRETURN})

Message: RETURN is only allowed in a FUNCTION

@item Error: @code{1314} SQLSTATE: @code{0A000} (@code{ER_SP_BADSTATEMENT})

Message: Statements like SELECT, INSERT, UPDATE (and others) are not allowed in a FUNCTION

@item Error: @code{1315} SQLSTATE: @code{42000} (@code{ER_UPDATE_LOG_DEPRECATED_IGNORED})

Message: The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been ignored

@item Error: @code{1316} SQLSTATE: @code{42000} (@code{ER_UPDATE_LOG_DEPRECATED_TRANSLATED})

Message: The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN

@item Error: @code{1317} SQLSTATE: @code{70100} (@code{ER_QUERY_INTERRUPTED})

Message: Query execution was interrupted

@item Error: @code{1318} SQLSTATE: @code{42000} (@code{ER_SP_WRONG_NO_OF_ARGS})

Message: Incorrect number of arguments for %s %s; expected %u, got %u

@item Error: @code{1319} SQLSTATE: @code{42000} (@code{ER_SP_COND_MISMATCH})

Message: Undefined CONDITION: %s

@item Error: @code{1320} SQLSTATE: @code{42000} (@code{ER_SP_NORETURN})

Message: No RETURN found in FUNCTION %s

@item Error: @code{1321} SQLSTATE: @code{2F005} (@code{ER_SP_NORETURNEND})

Message: FUNCTION %s ended without RETURN

@item Error: @code{1322} SQLSTATE: @code{42000} (@code{ER_SP_BAD_CURSOR_QUERY})

Message: Cursor statement must be a SELECT

@item Error: @code{1323} SQLSTATE: @code{42000} (@code{ER_SP_BAD_CURSOR_SELECT})

Message: Cursor SELECT must not have INTO

@item Error: @code{1324} SQLSTATE: @code{42000} (@code{ER_SP_CURSOR_MISMATCH})

Message: Undefined CURSOR: %s

@item Error: @code{1325} SQLSTATE: @code{24000} (@code{ER_SP_CURSOR_ALREADY_OPEN})

Message: Cursor is already open

@item Error: @code{1326} SQLSTATE: @code{24000} (@code{ER_SP_CURSOR_NOT_OPEN})

Message: Cursor is not open

@item Error: @code{1327} SQLSTATE: @code{42000} (@code{ER_SP_UNDECLARED_VAR})

Message: Undeclared variable: %s

@item Error: @code{1328} SQLSTATE: @code{HY000} (@code{ER_SP_WRONG_NO_OF_FETCH_ARGS})

Message: Incorrect number of FETCH variables

@item Error: @code{1329} SQLSTATE: @code{02000} (@code{ER_SP_FETCH_NO_DATA})

Message: No data to FETCH

@item Error: @code{1330} SQLSTATE: @code{42000} (@code{ER_SP_DUP_PARAM})

Message: Duplicate parameter: %s

@item Error: @code{1331} SQLSTATE: @code{42000} (@code{ER_SP_DUP_VAR})

Message: Duplicate variable: %s

@item Error: @code{1332} SQLSTATE: @code{42000} (@code{ER_SP_DUP_COND})

Message: Duplicate condition: %s

@item Error: @code{1333} SQLSTATE: @code{42000} (@code{ER_SP_DUP_CURS})

Message: Duplicate cursor: %s

@item Error: @code{1334} SQLSTATE: @code{HY000} (@code{ER_SP_CANT_ALTER})

Message: Failed to ALTER %s %s

@item Error: @code{1335} SQLSTATE: @code{0A000} (@code{ER_SP_SUBSELECT_NYI})

Message: Subselect value not supported

@item Error: @code{1336} SQLSTATE: @code{42000} (@code{ER_SP_NO_USE})

Message: USE is not allowed in a stored procedure

@item Error: @code{1337} SQLSTATE: @code{42000} (@code{ER_SP_VARCOND_AFTER_CURSHNDLR})

Message: Variable or condition declaration after cursor or handler declaration

@item Error: @code{1338} SQLSTATE: @code{42000} (@code{ER_SP_CURSOR_AFTER_HANDLER})

Message: Cursor declaration after handler declaration

@item Error: @code{1339} SQLSTATE: @code{20000} (@code{ER_SP_CASE_NOT_FOUND})

Message: Case not found for CASE statement

@item Error: @code{1340} SQLSTATE: @code{HY000} (@code{ER_FPARSER_TOO_BIG_FILE})

Message: Configuration file '%s' is too big

@item Error: @code{1341} SQLSTATE: @code{HY000} (@code{ER_FPARSER_BAD_HEADER})

Message: Malformed file type header in file '%s'

@item Error: @code{1342} SQLSTATE: @code{HY000} (@code{ER_FPARSER_EOF_IN_COMMENT})

Message: Unexpected end of file while parsing comment '%s'

@item Error: @code{1343} SQLSTATE: @code{HY000} (@code{ER_FPARSER_ERROR_IN_PARAMETER})

Message: Error while parsing parameter '%s' (line: '%s')

@item Error: @code{1344} SQLSTATE: @code{HY000} (@code{ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER})

Message: Unexpected end of file while skipping unknown parameter '%s'

@item Error: @code{1345} SQLSTATE: @code{HY000} (@code{ER_VIEW_NO_EXPLAIN})

Message: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table

@item Error: @code{1346} SQLSTATE: @code{HY000} (@code{ER_FRM_UNKNOWN_TYPE})

Message: File '%s' has unknown type '%s' in its header

@item Error: @code{1347} SQLSTATE: @code{HY000} (@code{ER_WRONG_OBJECT})

Message: '%s.%s' is not %s

@item Error: @code{1348} SQLSTATE: @code{HY000} (@code{ER_NONUPDATEABLE_COLUMN})

Message: Column '%s' is not updatable

@item Error: @code{1349} SQLSTATE: @code{HY000} (@code{ER_VIEW_SELECT_DERIVED})

Message: View's SELECT contains a subquery in the FROM clause

@item Error: @code{1350} SQLSTATE: @code{HY000} (@code{ER_VIEW_SELECT_CLAUSE})

Message: View's SELECT contains a '%s' clause

@item Error: @code{1351} SQLSTATE: @code{HY000} (@code{ER_VIEW_SELECT_VARIABLE})

Message: View's SELECT contains a variable or parameter

@item Error: @code{1352} SQLSTATE: @code{HY000} (@code{ER_VIEW_SELECT_TMPTABLE})

Message: View's SELECT contains a temporary table '%s'

@item Error: @code{1353} SQLSTATE: @code{HY000} (@code{ER_VIEW_WRONG_LIST})

Message: View's SELECT and view's field list have different column counts

@item Error: @code{1354} SQLSTATE: @code{HY000} (@code{ER_WARN_VIEW_MERGE})

Message: View merge algorithm can't be used here for now (assumed undefined algorithm)

@item Error: @code{1355} SQLSTATE: @code{HY000} (@code{ER_WARN_VIEW_WITHOUT_KEY})

Message: View being updated does not have complete key of underlying table in it

@item Error: @code{1356} SQLSTATE: @code{HY000} (@code{ER_VIEW_INVALID})

Message: View '%s.%s' references invalid table(s) or column(s)

@item Error: @code{1357} SQLSTATE: @code{HY000} (@code{ER_SP_NO_DROP_SP})

Message: Can't drop a %s from within another stored routine

@item Error: @code{1358} SQLSTATE: @code{HY000} (@code{ER_SP_GOTO_IN_HNDLR})

Message: GOTO is not allowed in a stored procedure handler

@item Error: @code{1359} SQLSTATE: @code{HY000} (@code{ER_TRG_ALREADY_EXISTS})

Message: Trigger already exists

@item Error: @code{1360} SQLSTATE: @code{HY000} (@code{ER_TRG_DOES_NOT_EXIST})

Message: Trigger does not exist

@item Error: @code{1361} SQLSTATE: @code{HY000} (@code{ER_TRG_ON_VIEW_OR_TEMP_TABLE})

Message: Trigger's '%s' is view or temporary table

@item Error: @code{1362} SQLSTATE: @code{HY000} (@code{ER_TRG_CANT_CHANGE_ROW})

Message: Updating of %s row is not allowed in %strigger

@item Error: @code{1363} SQLSTATE: @code{HY000} (@code{ER_TRG_NO_SUCH_ROW_IN_TRG})

Message: There is no %s row in %s trigger

@item Error: @code{1364} SQLSTATE: @code{HY000} (@code{ER_NO_DEFAULT_FOR_FIELD})

Message: Field '%s' doesn't have a default value

@item Error: @code{1365} SQLSTATE: @code{22012} (@code{ER_DIVISION_BY_ZERO})

Message: Division by 0

@item Error: @code{1366} SQLSTATE: @code{HY000} (@code{ER_TRUNCATED_WRONG_VALUE_FOR_FIELD})

Message: Incorrect %s value: '%s' for column '%s' at row %ld

@item Error: @code{1367} SQLSTATE: @code{22007} (@code{ER_ILLEGAL_VALUE_FOR_TYPE})

Message: Illegal %s '%s' value found during parsing

@item Error: @code{1368} SQLSTATE: @code{HY000} (@code{ER_VIEW_NONUPD_CHECK})

Message: CHECK OPTION on non-updatable view '%s.%s'

@item Error: @code{1369} SQLSTATE: @code{HY000} (@code{ER_VIEW_CHECK_FAILED})

Message: CHECK OPTION failed '%s.%s'

@end itemize

Client error information comes from the following files:

@itemize @bullet
@item
The Error values and the symbols in parentheses correspond to
definitions in the @file{include/errmsg.h} MySQL source file.

@item
The Message values correspond to the error messages that are listed
in the @file{libmysql/errmsg.c} file.  %d or %s represent numbers
or strings that are substituted into the messages %when they are displayed.

@end itemize

Because updates are frequent, it is possible that
these files will contain additional error information not listed here.

@c NOTE: To regenerate this list, run the make-cl-errmsg-table.pl script.

@itemize @bullet

@item Error: @code{2000} (@code{CR_UNKNOWN_ERROR})

Message: Unknown MySQL error

@item Error: @code{2001} (@code{CR_SOCKET_CREATE_ERROR})

Message: Can't create UNIX socket (%d)

@item Error: @code{2002} (@code{CR_CONNECTION_ERROR})

Message: Can't connect to local MySQL server through socket '%s' (%d)

@item Error: @code{2003} (@code{CR_CONN_HOST_ERROR})

Message: Can't connect to MySQL server on '%s' (%d)

@item Error: @code{2004} (@code{CR_IPSOCK_ERROR})

Message: Can't create TCP/IP socket (%d)

@item Error: @code{2005} (@code{CR_UNKNOWN_HOST})

Message: Unknown MySQL server host '%s' (%d)

@item Error: @code{2006} (@code{CR_SERVER_GONE_ERROR})

Message: MySQL server has gone away

@item Error: @code{2007} (@code{CR_VERSION_ERROR})

Message: Protocol mismatch; server version = %d, client version = %d

@item Error: @code{2008} (@code{CR_OUT_OF_MEMORY})

Message: MySQL client ran out of memory

@item Error: @code{2009} (@code{CR_WRONG_HOST_INFO})

Message: Wrong host info

@item Error: @code{2010} (@code{CR_LOCALHOST_CONNECTION})

Message: Localhost via UNIX socket

@item Error: @code{2011} (@code{CR_TCP_CONNECTION})

Message: %s via TCP/IP

@item Error: @code{2012} (@code{CR_SERVER_HANDSHAKE_ERR})

Message: Error in server handshake

@item Error: @code{2013} (@code{CR_SERVER_LOST})

Message: Lost connection to MySQL server during query

@item Error: @code{2014} (@code{CR_COMMANDS_OUT_OF_SYNC})

Message: Commands out of sync; you can't run this command now

@item Error: @code{2015} (@code{CR_NAMEDPIPE_CONNECTION})

Message: %s via named pipe

@item Error: @code{2016} (@code{CR_NAMEDPIPEWAIT_ERROR})

Message: Can't wait for named pipe to host: %s  pipe: %s (%lu)

@item Error: @code{2017} (@code{CR_NAMEDPIPEOPEN_ERROR})

Message: Can't open named pipe to host: %s  pipe: %s (%lu)

@item Error: @code{2018} (@code{CR_NAMEDPIPESETSTATE_ERROR})

Message: Can't set state of named pipe to host: %s  pipe: %s (%lu)

@item Error: @code{2019} (@code{CR_CANT_READ_CHARSET})

Message: Can't initialize character set %s (path: %s)

@item Error: @code{2020} (@code{CR_NET_PACKET_TOO_LARGE})

Message: Got packet bigger than 'max_allowed_packet' bytes

@item Error: @code{2021} (@code{CR_EMBEDDED_CONNECTION})

Message: Embedded server

@item Error: @code{2022} (@code{CR_PROBE_SLAVE_STATUS})

Message: Error on SHOW SLAVE STATUS:

@item Error: @code{2023} (@code{CR_PROBE_SLAVE_HOSTS})

Message: Error on SHOW SLAVE HOSTS:

@item Error: @code{2024} (@code{CR_PROBE_SLAVE_CONNECT})

Message: Error connecting to slave:

@item Error: @code{2025} (@code{CR_PROBE_MASTER_CONNECT})

Message: Error connecting to master:

@item Error: @code{2026} (@code{CR_SSL_CONNECTION_ERROR})

Message: SSL connection error

@item Error: @code{2027} (@code{CR_MALFORMED_PACKET})

Message: Malformed packet

@item Error: @code{2028} (@code{CR_WRONG_LICENSE})

Message: This client library is licensed only for use with MySQL servers having '%s' license

@item Error: @code{2029} (@code{CR_NULL_POINTER})

Message: Invalid use of null pointer

@item Error: @code{2030} (@code{CR_NO_PREPARE_STMT})

Message: Statement not prepared

@item Error: @code{2031} (@code{CR_PARAMS_NOT_BOUND})

Message: No data supplied for parameters in prepared statement

@item Error: @code{2032} (@code{CR_DATA_TRUNCATED})

Message: Data truncated

@item Error: @code{2033} (@code{CR_NO_PARAMETERS_EXISTS})

Message: No parameters exist in the statement

@item Error: @code{2034} (@code{CR_INVALID_PARAMETER_NO})

Message: Invalid parameter number

@item Error: @code{2035} (@code{CR_INVALID_BUFFER_USE})

Message: Can't send long data for non-string/non-binary data types (parameter: %d)

@item Error: @code{2036} (@code{CR_UNSUPPORTED_PARAM_TYPE})

Message: Using unsupported buffer type: %d  (parameter: %d)

@item Error: @code{2037} (@code{CR_SHARED_MEMORY_CONNECTION})

Message: Shared memory (%lu)

@item Error: @code{2038} (@code{CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR})

Message: Can't open shared memory; client could not create request event (%lu)

@item Error: @code{2039} (@code{CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR})

Message: Can't open shared memory; no answer event received from server (%lu)

@item Error: @code{2040} (@code{CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR})

Message: Can't open shared memory; server could not allocate file mapping (%lu)

@item Error: @code{2041} (@code{CR_SHARED_MEMORY_CONNECT_MAP_ERROR})

Message: Can't open shared memory; server could not get pointer to file mapping (%lu)

@item Error: @code{2042} (@code{CR_SHARED_MEMORY_FILE_MAP_ERROR})

Message: Can't open shared memory; client could not allocate file mapping (%lu)

@item Error: @code{2043} (@code{CR_SHARED_MEMORY_MAP_ERROR})

Message: Can't open shared memory; client could not get pointer to file mapping (%lu)

@item Error: @code{2044} (@code{CR_SHARED_MEMORY_EVENT_ERROR})

Message: Can't open shared memory; client could not create %s event (%lu)

@item Error: @code{2045} (@code{CR_SHARED_MEMORY_CONNECT_ABANDONED_ERROR})

Message: Can't open shared memory; no answer from server (%lu)

@item Error: @code{2046} (@code{CR_SHARED_MEMORY_CONNECT_SET_ERROR})

Message: Can't open shared memory; cannot send request event to server (%lu)

@item Error: @code{2047} (@code{CR_CONN_UNKNOW_PROTOCOL})

Message: Wrong or unknown protocol

@item Error: @code{2048} (@code{CR_INVALID_CONN_HANDLE})

Message: Invalid connection handle

@item Error: @code{2049} (@code{CR_SECURE_AUTH})

Message: Connection using old (pre-4.1.1) authentication protocol refused (client option 'secure_auth' enabled)

@item Error: @code{2050} (@code{CR_FETCH_CANCELED})

Message: Row retrieval was canceled by mysql_stmt_close() call

@item Error: @code{2051} (@code{CR_NO_DATA})

Message: Attempt to read column without prior row fetch

@end itemize


@node Extending MySQL, Problems, Error-handling, Top
@chapter Extending MySQL

@menu
* MySQL internals::             MySQL Internals
* Adding functions::            Adding New Functions to MySQL
* Adding procedures::           Adding New Procedures to MySQL
@end menu


@node MySQL internals, Adding functions, Extending MySQL, Extending MySQL
@section MySQL Internals

@cindex internals
@cindex threads

This chapter describes a lot of things that you need to know when
working on the MySQL code. If you plan to contribute to MySQL
development, want to have access to the bleeding-edge in-between
versions code, or just want to keep track of development, follow the
instructions in @ref{Installing source tree}.
If you are interested in MySQL internals, you should also subscribe
to our @code{internals} mailing list. This list is relatively low
traffic. For details on how to subscribe, please see
@ref{Mailing-list}.
All developers at MySQL AB are on the @code{internals} list and we
help other people who are working on the MySQL code. Feel free to
use this list both to ask questions about the code and to send
patches that you would like to contribute to the MySQL project!

@menu
* MySQL threads::               MySQL Threads
* MySQL test suite::            MySQL Test Suite
@end menu


@node MySQL threads, MySQL test suite, MySQL internals, MySQL internals
@subsection MySQL Threads

The MySQL server creates the following threads:

@itemize @bullet

@item
The TCP/IP connection thread handles all connection requests and
creates a new dedicated thread to handle the authentication and
SQL query processing for each connection.

@item
On Windows NT there is a named pipe handler thread that does the same work as
the TCP/IP connection thread on named pipe connect requests.

@item
The signal thread handles all signals.  This thread also normally handles
alarms and calls @code{process_alarm()} to force timeouts on connections
that have been idle too long.

@item
If @command{mysqld} is compiled with @code{-DUSE_ALARM_THREAD}, a dedicated
thread that handles alarms is created.  This is only used on some systems where
there are problems with @code{sigwait()} or if you want to use the
@code{thr_alarm()} code in your application without a dedicated signal
handling thread.

@item
If one uses the @code{--flush_time=#} option, a dedicated thread is created
to flush all tables at the given interval.

@item
Every connection has its own thread.

@item
Every different table on which one uses @code{INSERT DELAYED} gets its
own thread.

@item
If you use @code{--master-host}, a slave replication thread will be
started to read and apply updates from the master.
@end itemize

@command{mysqladmin processlist} only shows the connection, @code{INSERT DELAYED},
and replication threads.


@node MySQL test suite,  , MySQL threads, MySQL internals
@subsection MySQL Test Suite

@cindex mysqltest, MySQL Test Suite
@cindex testing mysqld, mysqltest

Until recently, our main full-coverage test suite was based on proprietary
customer data and for that reason has not been publicly available. The only
publicly available part of our testing process consisted of the @code{crash-me}
test, a Perl DBI/DBD benchmark found in the @code{sql-bench} directory, and
miscellaneous tests located in @code{tests} directory. The lack of a
standardized publicly available test suite has made it difficult for our users,
as well developers, to do regression tests on the MySQL code. To address
this problem, we have created a new test system that is included in
Unix source distributions and binary distributions starting with Version
3.23.29.  The tests can be run under Unix, or on Windows in the Cygwin
environment if the server has been compiled under Cygwin. They cannot be
run in a native Windows environment currently.

The current set of test cases doesn't test everything in MySQL, but it
should catch most obvious bugs in the SQL processing code, OS/library
issues, and is quite thorough in testing replication.  Our eventual goal
is to have the tests cover 100% of the code.  We welcome contributions
to our test suite.  You may especially want to contribute tests that
examine the functionality critical to your system, because this will ensure
that all future MySQL releases will work well with your
applications.

@menu
* running mysqltest::           Running the MySQL Test Suite
* extending mysqltest::         Extending the MySQL Test Suite
* Reporting mysqltest bugs::    Reporting Bugs in the MySQL Test Suite
@end menu


@node running mysqltest, extending mysqltest, MySQL test suite, MySQL test suite
@subsubsection Running the MySQL Test Suite

The test system consist of a test language interpreter
(@command{mysqltest}), a shell script to run all
tests(@command{mysql-test-run}), the actual test cases written in a special
test language, and their expected results.  To run the test suite on
your system after a build, type @command{make test} or
@code{mysql-test/mysql-test-run} from the source root.  If you have
installed a binary distribution, @code{cd} to the install root
(eg. @code{/usr/local/mysql}), and do @code{scripts/mysql-test-run}.
All tests should succeed.  If not, you should try to find out why and
report the problem if this is a bug in MySQL.
@xref{Reporting mysqltest bugs}.

From MySQL 4.1 on,
if you have a copy of @command{mysqld} running on the machine where you want to
run the test suite you do not have to stop it, as long as it is not using
ports @code{9306} and @code{9307}.  If one of those ports is taken, you should
edit @command{mysql-test-run} and change the values of the master and/or slave
port to one that is available.

Before MySQL 4.1, @command{mysql-test-run} does not try to run its own server
by default but tries to use your currently running server. To override this
and cause @command{mysql-test-run} to start its own server, run it with with
the @code{--local} option.

You can run one individual test case with
@code{mysql-test/mysql-test-run test_name}.

If one test fails, you should test running @command{mysql-test-run} with
the @code{--force} option to check whether any other tests fail.


@node extending mysqltest, Reporting mysqltest bugs, running mysqltest, MySQL test suite
@subsubsection Extending the MySQL Test Suite

You can use the @command{mysqltest} language to write your own test cases.
Unfortunately, we have not yet written full documentation for it.
You can, however, look at our current test cases and use
them as an example.  The following points should help you get started:

@itemize @bullet
@item
The tests are located in @file{mysql-test/t/*.test}

@item
A test case consists of @code{;} terminated statements and is similar to the
input of @command{mysql} command-line client.  A statement by default is a query
to be sent to MySQL server, unless it is recognized as internal
command (eg. @command{sleep}).

@item
All queries that produce results---for example, @code{SELECT}, @code{SHOW},
@code{EXPLAIN}, etc., must be preceded with @var{@@/path/to/result/file}.  The
file must contain the expected results.  An easy way to generate the result
file is to run @command{mysqltest -r < t/test-case-name.test} from the
@file{mysql-test} directory, and then edit the generated result files, if
needed, to adjust them to the expected output.  In that case, be very careful
about not adding or deleting any invisible characters --- make sure to only
change the text and/or delete lines.  If you have to insert a line, make sure
that the fields are separated by a hard tab, and that there is a hard tab at the end.
You may want to use @command{od -c} to make sure that your text editor has not messed
anything up during edit.  We hope that you will never have to edit the output
of @command{mysqltest -r} as you only have to do it when you find a bug.

@item
To be consistent with our setup, you should put your result files in the
@file{mysql-test/r} directory and name them @file{test_name.result}.  If the
test produces more than one result, you should use @file{test_name.a.result},
@file{test_name.b.result}, etc.

@item
If a statement returns an error, you should specify it with
@code{--error error-number} on the line before the statement.
The error number can be
a list of possible error numbers separated by @samp{,}.

@item
If you are writing a replication test case, you should on the first line of
the test file, put @code{source include/master-slave.inc;}.  To switch between
master and slave, use @code{connection master;} and @code{connection slave;}.
If you need to do something on an alternate connection, you can do
@code{connection master1;} for the master, and @code{connection slave1;} for
the slave.

@item
If you need to do something in a loop, you can use something like this:
@example
let $1=1000;
while ($1)
@{
 # do your queries here
 dec $1;
@}
@end example

@item
To sleep between queries, use the @command{sleep} command. It supports fractions
of a second, so you can use @command{sleep 1.3;}, for example, to sleep 1.3
seconds.

@item
To run the slave with additional options for your test case, put them
in the command-line format in @file{mysql-test/t/test_name-slave.opt}. For
the master, put them in @file{mysql-test/t/test_name-master.opt}.

@item
If you have a question about the test suite, or have a test case to contribute,
send an email message to the MySQL @code{internals} mailing list.
@xref{Mailing-list}.
As this list does not accept
attachments, you should ftp all the relevant files to:
@uref{ftp://ftp.mysql.com/pub/mysql/upload/}

@end itemize


@node Reporting mysqltest bugs,  , extending mysqltest, MySQL test suite
@subsubsection Reporting Bugs in the MySQL Test Suite

If your MySQL version doesn't pass the test suite you should
do the following:

@itemize @bullet
@item
Don't send a bug report before you have found out as much as possible of
what when wrong!  When you do it, please use the @command{mysqlbug} script
so that we can get information about your system and MySQL
version. @xref{Bug reports}.
@item
Make sure to include the output of @command{mysql-test-run}, as well as
contents of all @file{.reject} files in @file{mysql-test/r} directory.
@item
If a test in the test suite fails, check whether the test fails also when run
by its own:

@example
cd mysql-test
mysql-test-run --local test-name
@end example

If this fails, then you should configure MySQL with
@code{--with-debug} and run @command{mysql-test-run} with the
@code{--debug} option. If this also fails send the trace file
@file{var/tmp/master.trace} to @uref{ftp://ftp.mysql.com/pub/mysql/upload/}
so that we can examine it. Please remember to also include a full
description of your system, the version of the mysqld binary and how you
compiled it.

@item
Try also to run @command{mysql-test-run} with the @code{--force} option to
see whether there is any other test that fails.

@item
If you have compiled MySQL yourself, check our manual for how
to compile MySQL on your platform or, preferable, use one of
the binaries we have compiled for you at
@uref{http://dev.mysql.com/downloads/}.  All our standard binaries should
pass the test suite !

@item
If you get an error, like @code{Result length mismatch} or @code{Result
content mismatch} it means that the output of the test didn't match
exactly the expected output. This could be a bug in MySQL or
that your mysqld version produces slight different results under some
circumstances.

Failed test results are put in a file with the same base name as the
result file with the @code{.reject} extension.  If your test case is
failing, you should do a diff on the two files.  If you cannot see how
they are different, examine both with @code{od -c} and also check their
lengths.

@item
If a test fails totally, you should check the logs file in the
@file{mysql-test/var/log} directory for hints of what went wrong.

@item
If you have compiled MySQL with debugging you can try to debug this
by running @command{mysql-test-run} with the @code{--gdb} and/or @code{--debug}
options.
@xref{Making trace files}.

If you have not compiled MySQL for debugging you should probably
do that.  Just specify the @code{--with-debug} options to @command{configure}!
@xref{Installing source}.
@end itemize


@node Adding functions, Adding procedures, MySQL internals, Extending MySQL
@section Adding New Functions to MySQL

@cindex functions, new
@cindex adding, new functions
@cindex user-defined functions, adding
@cindex UDFs, defined
@cindex functions, user-defined

There are two ways to add new functions to MySQL:

@itemize @bullet
@item You can add the function through the user-defined function (UDF)
interface.  User-defined functions are added and removed dynamically using
the @code{CREATE FUNCTION} and @code{DROP FUNCTION} statements.
@xref{CREATE FUNCTION, , @code{CREATE FUNCTION}}.

@item You can add the function as a native (built in) MySQL function.
Native functions are compiled into the @command{mysqld} server and become
available on a permanent basis.
@end itemize

Each method has advantages and disadvantages:

@itemize @bullet
@item
If you write a user-defined function, you must install the object file
in addition to the server itself.  If you compile your function into the
server, you don't need to do that.
@item
You can add UDFs to a binary MySQL distribution.  Native functions
require you to modify a source distribution.
@item
If you upgrade your MySQL distribution, you can continue to use your
previously installed UDFs.  For native functions, you must repeat your
modifications each time you upgrade.
@end itemize

Whichever method you use to add new functions, they may be used just like
native functions such as @code{ABS()} or @code{SOUNDEX()}.

@menu
* CREATE FUNCTION::             @code{CREATE FUNCTION/DROP FUNCTION} Syntax
* Adding UDF::                  Adding a New User-defined Function
* Adding native function::      Adding a New Native Function
@end menu


@node CREATE FUNCTION, Adding UDF, Adding functions, Adding functions
@subsection @code{CREATE FUNCTION/DROP FUNCTION} Syntax

@findex CREATE FUNCTION
@findex DROP FUNCTION
@cindex deleting, function
@cindex function, deleting
@findex UDF functions
@findex User-defined functions
@findex Functions, user-defined

@c help_category Functions
@c example_for_help_topic FUNCTION
@example
CREATE [AGGREGATE] FUNCTION function_name RETURNS @{STRING|REAL|INTEGER@}
       SONAME shared_library_name

DROP FUNCTION function_name
@end example
@c help_category Functions
@c description_for_help_topic FUNCTION  AGGREGATE CREATE FUNCTION DROP STRING REAL INTEGER RETURNS SONAME
A user-defined function (UDF) is a way to extend MySQL with a new
function that works like native (built in) MySQL function such as
@code{ABS()} and @code{CONCAT()}.

@code{AGGREGATE} is a new option for MySQL 3.23.  An
@code{AGGREGATE} function works exactly like a native MySQL
@code{GROUP} function like @code{SUM} or @code{COUNT()}.

@code{CREATE FUNCTION} saves the function's name, type, and shared library
name in the @code{mysql.func} system table.  You must have the
@code{INSERT} and @code{DELETE} privileges for the @code{mysql} database
to create and drop functions.
@c end_description_for_help_topic

All active functions are reloaded each time the server starts, unless
you start @command{mysqld} with the @code{--skip-grant-tables} option.  In
this case, UDF initialization is skipped and UDFs are unavailable.
(An active function is one that has been loaded with @code{CREATE FUNCTION}
and not removed with @code{DROP FUNCTION}.)

For instructions on writing user-defined functions, see @ref{Adding UDF}.
For the UDF mechanism to work, functions must be written in C or
C++, your operating system must support dynamic loading and you must have
compiled @command{mysqld} dynamically (not statically).

Note that to make @code{AGGREGATE} work, you must have a
@code{mysql.func} table that contains the column @code{type}.  If you do not
have this table, you should run the script
@command{mysql_fix_privilege_tables} to create it.


@node Adding UDF, Adding native function, CREATE FUNCTION, Adding functions
@subsection Adding a New User-defined Function

@cindex adding, user-defined functions
@cindex user-defined functions, adding
@cindex functions, user-defined, adding

@menu
* UDF calling::                 UDF Calling Sequences for simple functions
* UDF aggr. calling::           UDF Calling Sequences for aggregate functions
* UDF arguments::               Argument Processing
* UDF return values::           Return Values and Error Handling
* UDF compiling::               Compiling and Installing User-defined Functions
@end menu


For the UDF mechanism to work, functions must be written in C or C++ and
your operating system must support dynamic loading.  The MySQL source
distribution includes a file @file{sql/udf_example.cc} that defines 5 new
functions.  Consult this file to see how UDF calling conventions work.

For @command{mysqld} to be able to use UDF functions, you should configure MySQL
with @code{--with-mysqld-ldflags=-rdynamic} The reason is that to on
many platforms (including Linux) you can load a dynamic library (with
@code{dlopen()}) from a static linked program, which you would get if
you are using @code{--with-mysqld-ldflags=-all-static} If you want to
use an UDF that needs to access symbols from @command{mysqld} (like the
@code{metaphone} example in @file{sql/udf_example.cc} that uses
@code{default_charset_info}), you must link the program with
@code{-rdynamic} (see @code{man dlopen}).

If you are using a precompiled version of the server, use MySQL-Max,
which supports dynamic loading.

For each function that you want to use in SQL statements, you should define
corresponding C (or C++) functions.  In the following discussion, the name
``xxx'' is used for an example function name.  To distinguish between SQL and
C/C++ usage, @code{XXX()} (uppercase) indicates an SQL function call, and
@code{xxx()} (lowercase) indicates a C/C++ function call.

The C/C++ functions that you write to implement the interface for
@code{XXX()} are:

@table @asis
@item @code{xxx()} (required)
The main function.  This is where the function result is computed.
The correspondence between the SQL type and return type of your C/C++
function is shown here:

@multitable @columnfractions .15 .15
@item @strong{SQL Type} @tab @strong{C/C++ Type}
@item @code{STRING}     @tab @code{char *}
@item @code{INTEGER}    @tab @code{long long}
@item @code{REAL}       @tab @code{double}
@end multitable

@item @code{xxx_init()} (optional)
The initialization function for @code{xxx()}.  It can be used to:

@itemize @bullet
@item
Check the number of arguments to @code{XXX()}.
@item
Check that the arguments are of a required type or, alternatively,
tell MySQL to coerce arguments to the types you want when
the main function is called.
@item
Allocate any memory required by the main function.
@item
Specify the maximum length of the result.
@item
Specify (for @code{REAL} functions) the maximum number of decimals.
@item
Specify whether the result can be @code{NULL}.
@end itemize

@item @code{xxx_deinit()} (optional)
The deinitialization function for @code{xxx()}.  It should deallocate any
memory allocated by the initialization function.
@end table

When an SQL statement invokes @code{XXX()}, MySQL calls the
initialization function @code{xxx_init()} to let it perform any required
setup, such as argument checking or memory allocation.  If @code{xxx_init()}
returns an error, the SQL statement is aborted with an error message and the
main and deinitialization functions are not called.  Otherwise, the main
function @code{xxx()} is called once for each row.  After all rows have been
processed, the deinitialization function @code{xxx_deinit()} is called so it
can perform any required cleanup.

For aggregate functions (like @code{SUM()}), you must also provide the
following functions:

@table @asis
@item @code{xxx_reset()} (required)
Reset sum and insert the argument as the initial value for a new group.
@item @code{xxx_add()} (required)
Add the argument to the old sum.
@end table

When using aggregate UDFs, MySQL works the following way:

@enumerate
@item
Call @code{xxx_init()} to let the aggregate function allocate the memory it
will need to store results.
@item
Sort the table according to the @code{GROUP BY} expression.
@item
For the first row in a new group, call the @code{xxx_reset()} function.
@item
For each new row that belongs in the same group, call the
@code{xxx_add()} function.
@item
When the group changes or after the last row has been processed,
call @code{xxx()} to get the result for the aggregate.
@item
Repeat 3-5 until all rows has been processed
@item
Call @code{xxx_deinit()} to let the UDF free any memory it has allocated.
@end enumerate

All functions must be thread-safe (not just the main function,
but the initialization and deinitialization functions as well). This means
that you are not allowed to allocate any global or static variables that
change!  If you need memory, you should allocate it in @code{xxx_init()}
and free it in @code{xxx_deinit()}.


@node UDF calling, UDF aggr. calling, Adding UDF, Adding UDF
@subsubsection UDF Calling Sequences for simple functions

@cindex calling sequences for simple functions, UDF

The main function should be declared as shown here.  Note that the return
type and parameters differ, depending on whether you will declare the SQL
function @code{XXX()} to return @code{STRING}, @code{INTEGER}, or @code{REAL}
in the @code{CREATE FUNCTION} statement:

@noindent
For @code{STRING} functions:

@example
char *xxx(UDF_INIT *initid, UDF_ARGS *args,
          char *result, unsigned long *length,
          char *is_null, char *error);
@end example

@noindent
For @code{INTEGER} functions:

@example
long long xxx(UDF_INIT *initid, UDF_ARGS *args,
              char *is_null, char *error);
@end example

@noindent
For @code{REAL} functions:

@example
double xxx(UDF_INIT *initid, UDF_ARGS *args,
              char *is_null, char *error);
@end example

The initialization and deinitialization functions are declared like this:

@example
my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message);

void xxx_deinit(UDF_INIT *initid);
@end example

The @code{initid} parameter is passed to all three functions.  It points to a
@code{UDF_INIT} structure that is used to communicate information between
functions.  The @code{UDF_INIT} structure members follow.  The
initialization function should fill in any members that it wishes to change.
(To use the default for a member, leave it unchanged.):

@table @code
@item my_bool maybe_null
@code{xxx_init()} should set @code{maybe_null} to @code{1} if @code{xxx()}
can return @code{NULL}.  The default value is @code{1} if any of the
arguments are declared @code{maybe_null}.

@item unsigned int decimals
The number of decimals.  The default value is the maximum number of decimals in
the arguments passed to the main function.  (For example, if the function is
passed @code{1.34}, @code{1.345}, and @code{1.3}, the default would be 3,
because @code{1.345} has 3 decimals.

@item unsigned int max_length
The maximum length of the string result.  The default value differs depending
on the result type of the function.  For string functions, the default is the
length of the longest argument.  For integer functions, the default is 21
digits.  For real functions, the default is 13 plus the number of decimals
indicated by @code{initid->decimals}.  (For numeric functions, the length
includes any sign or decimal point characters.)

If you want to return a blob, you can set this to 65KB or 16MB; this
memory is not allocated but used to decide which column type to use if
there is a need to temporary store the data.

@item char *ptr
A pointer that the function can use for its own purposes.  For example,
functions can use @code{initid->ptr} to communicate allocated memory
between functions.  In @code{xxx_init()}, allocate the memory and assign it
to this pointer:

@example
initid->ptr = allocated_memory;
@end example

In @code{xxx()} and @code{xxx_deinit()}, refer to @code{initid->ptr} to use
or deallocate the memory.
@end table


@node UDF aggr. calling, UDF arguments, UDF calling, Adding UDF
@subsubsection UDF Calling Sequences for aggregate functions

@cindex calling sequences for aggregate functions, UDF

Here follows a description of the different functions you need to define
when you want to create an aggregate UDF function.

Note that the following function is NOT needed or used by MySQL 4.1.1.
You can keep still have define this function if you want to have your
code work with both MySQL 4.0 and MySQL 4.1.1

@example
char *xxx_reset(UDF_INIT *initid, UDF_ARGS *args,
                char *is_null, char *error);
@end example

This function is called when MySQL finds the first row in a new group.
In the function you should reset any internal summary variables and then set
the given argument as the first argument in the group.

In many cases this is implemented internally by reseting all variables
(for example by calling @code{xxx_clear()} and then calling
@code{xxx_add()}.

The following function is only required by MySQL 4.1.1 and above:

@example
char *xxx_clear(UDF_INIT *initid, char *is_null, char *error);
@end example

This function is called when MySQL needs to reset the summary results.
This will be called at the beginning for each new group but can also be
called to reset the values for a query where there was no matching rows.
@code{is_null} will be set to point to @code{CHAR(0)} before calling
@code{xxx_clear()}.

You can use the @code{error} pointer to store a byte if something went
wrong .

@example
char *xxx_add(UDF_INIT *initid, UDF_ARGS *args,
              char *is_null, char *error);
@end example

This function is called for all rows that belongs to the same group,
except for the first row. In this you should add the value in UDF_ARGS
to your internal summary variable.

The @code{xxx()} function should be declared identical as when you
define a simple UDF function. @xref{UDF calling}.

This function is called when all rows in the group has been processed.
You should normally never access the @code{args} variable here but
return your value based on your internal summary variables.

All argument processing in @code{xxx_reset()} and @code{xxx_add()}
should be done identically as for normal UDFs. @xref{UDF arguments}.

The return value handling in @code{xxx()} should be done identically as
for a normal UDF. @xref{UDF return values}.

The pointer argument to @code{is_null} and @code{error} is the same for
all calls to @code{xxx_reset()}, @code{xxx_clear()}, @code{xxx_add()} and
@code{xxx()}.
You can use this to remember that you got an error or if the @code{xxx()}
function should return @code{NULL}. Note that you should not store a string
into @code{*error}!  This is just a 1 byte flag!

@code{is_null} is reset for each group (before calling @code{xxx_clear()}).
@code{error} is never reset.

If @code{is_null} or @code{error} are set after @code{xxx()}, then MySQL
will return @code{NULL} as the result for the group function.

@node UDF arguments, UDF return values, UDF aggr. calling, Adding UDF
@subsubsection Argument Processing

@cindex argument processing
@cindex processing, arguments

The @code{args} parameter points to a @code{UDF_ARGS} structure that has the
members listed here:

@table @code
@item unsigned int arg_count
The number of arguments.  Check this value in the initialization function
if you want your function to be called with a particular number of arguments.
For example:

@example
if (args->arg_count != 2)
@{
    strcpy(message,"XXX() requires two arguments");
    return 1;
@}
@end example


@item enum Item_result *arg_type
The types for each argument.  The possible type values are
@code{STRING_RESULT}, @code{INT_RESULT}, and @code{REAL_RESULT}.

To make sure that arguments are of a given type and return an
error if they are not, check the @code{arg_type} array in the initialization
function.  For example:

@example
if (args->arg_type[0] != STRING_RESULT ||
    args->arg_type[1] != INT_RESULT)
@{
    strcpy(message,"XXX() requires a string and an integer");
    return 1;
@}
@end example

As an alternative to requiring your function's arguments to be of particular
types, you can use the initialization function to set the @code{arg_type}
elements to the types you want.  This causes MySQL to coerce
arguments to those types for each call to @code{xxx()}.  For example, to
specify coercion of the first two arguments to string and integer, do this in
@code{xxx_init()}:

@example
args->arg_type[0] = STRING_RESULT;
args->arg_type[1] = INT_RESULT;
@end example

@item char **args
@code{args->args} communicates information to the initialization function
about the general nature of the arguments your function was called with.  For a
constant argument @code{i}, @code{args->args[i]} points to the argument
value.  (See below for instructions on how to access the value properly.)
For a non-constant argument, @code{args->args[i]} is @code{0}.
A constant argument is an expression that uses only constants, such as
@code{3} or @code{4*7-2} or @code{SIN(3.14)}.  A non-constant argument is an
expression that refers to values that may change from row to row, such as
column names or functions that are called with non-constant arguments.

For each invocation of the main function, @code{args->args} contains the
actual arguments that are passed for the row currently being processed.

Functions can refer to an argument @code{i} as follows:

@itemize @bullet
@item
An argument of type @code{STRING_RESULT} is given as a string pointer plus a
length, to allow handling of binary data or data of arbitrary length.  The
string contents are available as @code{args->args[i]} and the string length
is @code{args->lengths[i]}.  You should not assume that strings are
null-terminated.

@item
For an argument of type @code{INT_RESULT}, you must cast
@code{args->args[i]} to a @code{long long} value:

@example
long long int_val;
int_val = *((long long*) args->args[i]);
@end example

@item
For an argument of type @code{REAL_RESULT}, you must cast
@code{args->args[i]} to a @code{double} value:

@example
double    real_val;
real_val = *((double*) args->args[i]);
@end example
@end itemize

@item unsigned long *lengths
For the initialization function, the @code{lengths} array indicates the
maximum string length for each argument. You should not change these.
For each invocation of the main function, @code{lengths} contains the
actual lengths of any string arguments that are passed for the row
currently being processed.  For arguments of types @code{INT_RESULT} or
@code{REAL_RESULT}, @code{lengths} still contains the maximum length of
the argument (as for the initialization function).
@end table


@node UDF return values, UDF compiling, UDF arguments, Adding UDF
@subsubsection Return Values and Error Handling

@cindex UDFs, return values
@cindex return values, UDFs
@cindex errors, handling for UDFs
@cindex handling, errors

The initialization function should return @code{0} if no error occurred and
@code{1} otherwise.  If an error occurs, @code{xxx_init()} should store a
null-terminated error message in the @code{message} parameter.  The message
will be returned to the client.  The message buffer is
@code{MYSQL_ERRMSG_SIZE} characters long, but you should try to keep the
message to less than 80 characters so that it fits the width of a standard
terminal screen.

The return value of the main function @code{xxx()} is the function value, for
@code{long long} and @code{double} functions.  A string functions should
return a pointer to the result and store the length of the string in the
@code{length} arguments.

Set these to the contents and length of the return value.  For example:

@example
memcpy(result, "result string", 13);
*length = 13;
@end example

The @code{result} buffer that is passed to the calc function is 255 byte
big. If your result fits in this, you don't have to worry about memory
allocation for results.

If your string function needs to return a string longer than 255 bytes,
you must allocate the space for it with @code{malloc()} in your
@code{xxx_init()} function or your @code{xxx()} function and free it in
your @code{xxx_deinit()} function.  You can store the allocated memory
in the @code{ptr} slot in the @code{UDF_INIT} structure for reuse by
future @code{xxx()} calls.  @xref{UDF calling}.

To indicate a return value of @code{NULL} in the main function, set
@code{is_null} to @code{1}:

@example
*is_null = 1;
@end example

To indicate an error return in the main function, set the @code{error}
parameter to @code{1}:

@example
*error = 1;
@end example

If @code{xxx()} sets @code{*error} to @code{1} for any row, the function
value is @code{NULL} for the current row and for any subsequent rows
processed by the statement in which @code{XXX()} was invoked.  (@code{xxx()}
will not even be called for subsequent rows.) @strong{Note}: In
MySQL versions prior to 3.22.10, you should set both @code{*error}
and @code{*is_null}:

@example
*error = 1;
*is_null = 1;
@end example


@node UDF compiling,  , UDF return values, Adding UDF
@subsubsection Compiling and Installing User-defined Functions

@cindex compiling, user-defined functions
@cindex UDFs, compiling
@cindex installing, user-defined functions

Files implementing UDFs must be compiled and installed on the host where
the server runs.  This process is described below for the example UDF
file @file{udf_example.cc} that is included in the MySQL source distribution.

The immediately following instructions are for Unix. Instructions for
Windows are given later in this section.

The @file{udf_example.cc} file contains the following functions:

@itemize @bullet
@item
@code{metaphon()} returns a metaphon string of the string argument.
This is something like a soundex string, but it's more tuned for English.
@item
@code{myfunc_double()} returns the sum of the ASCII values of the
characters in its arguments, divided by the sum of the length of its arguments.
@item
@code{myfunc_int()} returns the sum of the length of its arguments.
@item
@code{sequence([const int])} returns an sequence starting from the given
number or 1 if no number has been given.
@item
@code{lookup()} returns the IP number for a hostname.
@item
@code{reverse_lookup()} returns the hostname for an IP number.
The function may be called with a string @code{'xxx.xxx.xxx.xxx'} or
four numbers.
@end itemize

A dynamically loadable file should be compiled as a sharable object file,
using a command something like this:

@example
shell> gcc -shared -o udf_example.so udf_example.cc
@end example

If you are using @command{gcc}, you should be able to create
@file{udf_example.so} with a simpler command:

@example
shell> make udf_example.so
@end example

You can easily find out the correct compiler options for your system by
running this command in the @file{sql} directory of your MySQL
source tree:

@example
shell> make udf_example.o
@end example

You should run a compile command similar to the one that @command{make} displays,
except that you should remove the @code{-c} option near the end of the line
and add @code{-o udf_example.so} to the end of the line.  (On some systems,
you may need to leave  the @code{-c} on the command.)

Once you compile a shared object containing UDFs, you must install it and
tell MySQL about it. Compiling a shared object from @file{udf_example.cc}
produces a file named something like @file{udf_example.so} (the exact name
may vary from platform to platform). Copy this file to some directory
searched by the dynamic linker @code{ld}, such as @file{/usr/lib} or add the
directory in which you placed the shared object to the linker configuration
file (for example, @file{/etc/ld.so.conf}).

On many systems, you can also set the @code{LD_LIBRARY} or
@code{LD_LIBRARY_PATH} environment variable to point at the directory where
you have your UDF function files. The @code{dlopen} manual page tells you
which variable you should use on your system. You should set this in
@command{mysql.server} or @command{mysqld_safe} startup scripts and restart
@command{mysqld}.

On some systems, the @command{ldconfig} program that configures the dynamic
linker will not recognize shared objects unless their name begins with
@code{lib}. In this case you should rename a file such as
@file{udf_example.so} to @file{libudf_example.so}.

On Windows, you can compile user-defined functions by using the following
procedure:

@enumerate

@item
You will need to obtain the BitKeeper source repository for MySQL 4.0 or
higher.
@xref{Installing source tree}.

@item
In the source repository, look in the @file{VC++Files/examples/udf_example}
directory. You will find files named @file{udf_example.def},
@file{udf_example.dsp}, and @file{udf_example.dsw} there.

@item
In the source repository, look in the @file{sql} directory. Copy
the @file{udf_example.cc} from this directory to the
@file{VC++Files/examples/udf_example} directory and rename the file to
@file{udf_example.cpp}.

@item
Open the @file{udf_example.dsw} file with Visual Studio VC++ and use it
to compile the UDFs as a normal project.

@end enumerate

After the library is installed, notify @command{mysqld} about the new
functions with these commands:

@example
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so';
mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME 'udf_example.so';
mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME 'udf_example.so';
mysql> CREATE FUNCTION lookup RETURNS STRING SONAME 'udf_example.so';
mysql> CREATE FUNCTION reverse_lookup
    ->        RETURNS STRING SONAME 'udf_example.so';
mysql> CREATE AGGREGATE FUNCTION avgcost
    ->        RETURNS REAL SONAME 'udf_example.so';
@end example

Functions can be deleted using @code{DROP FUNCTION}:

@example
mysql> DROP FUNCTION metaphon;
mysql> DROP FUNCTION myfunc_double;
mysql> DROP FUNCTION myfunc_int;
mysql> DROP FUNCTION lookup;
mysql> DROP FUNCTION reverse_lookup;
mysql> DROP FUNCTION avgcost;
@end example

The @code{CREATE FUNCTION} and @code{DROP FUNCTION} statements update the
system table @code{func} in the @code{mysql} database.  The function's name,
type and shared library name are saved in the table.  You must have the
@code{INSERT} and @code{DELETE} privileges for the @code{mysql} database
to create and drop functions.

You should not use @code{CREATE FUNCTION} to add a function that has already
been created.  If you need to reinstall a function, you should remove it with
@code{DROP FUNCTION} and then reinstall it with @code{CREATE FUNCTION}.  You
would need to do this, for example, if you recompile a new version of your
function, so that @command{mysqld} gets the new version.  Otherwise, the server
will continue to use the old version.

Active functions are reloaded each time the server starts, unless you start
@command{mysqld} with the @code{--skip-grant-tables} option.  In this case, UDF
initialization is skipped and UDFs are unavailable.  (An active function is
one that has been loaded with @code{CREATE FUNCTION} and not removed with
@code{DROP FUNCTION}.)


@node Adding native function,  , Adding UDF, Adding functions
@subsection Adding a New Native Function

@cindex adding, native functions
@cindex native functions, adding
@cindex functions, native, adding

The procedure for adding a new native function is described here.  Note
that you cannot add native functions to a binary distribution because
the procedure involves modifying MySQL source code.  You must
compile MySQL yourself from a source distribution.  Also note
that if you migrate to another version of MySQL (for example,
when a new version is released), you will need to repeat the procedure
with the new version.

To add a new native MySQL function, follow these steps:

@enumerate
@item
Add one line to @file{lex.h} that defines the function name in the
@code{sql_functions[]} array.
@item
If the function prototype is simple (just takes zero, one, two or three
arguments), you should in lex.h specify SYM(FUNC_ARG#) (where # is the
number of arguments) as the second argument in the
@code{sql_functions[]} array and add a function that creates a function
object in @file{item_create.cc}.  Take a look at @code{"ABS"} and
@code{create_funcs_abs()} for an example of this.

If the function prototype is complicated (for example takes a variable number
of arguments), you should add two lines to @file{sql_yacc.yy}. One
indicates the preprocessor symbol that @command{yacc} should define (this
should be added at the beginning of the file). Then define the function
parameters and add an ``item'' with these parameters to the
@code{simple_expr} parsing rule.  For an example, check all occurrences
of @code{ATAN} in @file{sql_yacc.yy} to see how this is done.
@item
In @file{item_func.h}, declare a class inheriting from @code{Item_num_func} or
@code{Item_str_func}, depending on whether your function returns a number or a
string.
@item
In @file{item_func.cc}, add one of the following declarations, depending
on whether you are defining a numeric or string function:
@example
double   Item_func_newname::val()
longlong Item_func_newname::val_int()
String  *Item_func_newname::Str(String *str)
@end example

If you inherit your object from any of the standard items (like
@code{Item_num_func}), you probably only have to define one of these
functions and let the parent object take care of the other functions.
For example, the @code{Item_str_func} class defines a @code{val()} function
that executes @code{atof()} on the value returned by @code{::str()}.

@item
You should probably also define the following object function:
@example
void Item_func_newname::fix_length_and_dec()
@end example
This function should at least calculate @code{max_length} based on the
given arguments. @code{max_length} is the maximum number of characters
the function may return.  This function should also set @code{maybe_null
= 0} if the main function can't return a @code{NULL} value.  The
function can check whether any of the function arguments can return
@code{NULL} by checking the arguments' @code{maybe_null} variable. You
can take a look at @code{Item_func_mod::fix_length_and_dec} for a
typical example of how to do this.
@end enumerate

All functions must be thread-safe (in other words, don't use any global or
static variables in the functions without protecting them with mutexes).

If you want to return @code{NULL}, from @code{::val()}, @code{::val_int()}
or @code{::str()} you should set @code{null_value} to 1 and return 0.

For @code{::str()} object functions, there are some additional
considerations to be aware of:

@itemize @bullet
@item
The @code{String *str} argument provides a string buffer that may be
used to hold the result. (For more information about the @code{String} type,
take a look at the @file{sql_string.h} file.)
@item
The @code{::str()} function should return the string that holds the result or
@code{(char*) 0} if the result is @code{NULL}.
@item
All current string functions try to avoid allocating any memory unless
absolutely necessary!
@end itemize


@node Adding procedures,  , Adding functions, Extending MySQL
@section Adding New Procedures to MySQL

@cindex procedures, adding
@cindex adding, procedures
@cindex new procedures, adding

In MySQL, you can define a procedure in C++ that can access and
modify the data in a query before it is sent to the client.  The modification
can be done on a row-by-row or @code{GROUP BY} level.

We have created an example procedure in MySQL 3.23 to
show you what can be done.

Additionally we recommend you to take a look at @code{mylua}.
With this you can use the LUA language to load a procedure at
runtime into @command{mysqld}.

@menu
* procedure analyse::           Procedure Analyse
* Writing a procedure::         Writing a Procedure
@end menu


@node procedure analyse, Writing a procedure, Adding procedures, Adding procedures
@subsection Procedure Analyse

@code{analyse([max elements,[max memory]])}

This procedure is defined in the @file{sql/sql_analyse.cc}.  This
examines the result from your query and returns an analysis of the
results:

@itemize @bullet
@item
@code{max elements} (default 256) is the maximum number of distinct values
@code{analyse} will notice per column.  This is used by @code{analyse} to
check whether
the optimal column type should be of type @code{ENUM}.
@item
@code{max memory} (default 8192) is the maximum memory @code{analyse} should
allocate per column while trying to find all distinct values.
@end itemize

@example
SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max elements,[max memory]])
@end example


@node Writing a procedure,  , procedure analyse, Adding procedures
@subsection Writing a Procedure

For the moment, the only documentation for this is the source.

You can find all information about procedures by examining the following files:

@itemize @bullet
@item @file{sql/sql_analyse.cc}
@item @file{sql/procedure.h}
@item @file{sql/procedure.cc}
@item @file{sql/sql_select.cc}
@end itemize


@node Problems, Credits, Extending MySQL, Top
@appendix Problems and Common Errors

@cindex problems, common errors
@cindex errors, common

@menu
* What is crashing::            How to Determine What Is Causing a Problem
* Common errors::               Common Errors When Using MySQL Programs
* Installation Issues::         Installation-Related Issues
* Administration Issues::       Administration-Related Issues
* Query Issues::                Query-Related Issues
* Optimizer Issues::            Optimizer-Related Issues
* Table Definition Issues::     Table Definition-Related Issues
@end menu

This appendix 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.


@node What is crashing, Common errors, Problems, Problems
@appendixsec 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:

@itemize @bullet
@item
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:
@itemize @minus
@item
The keyboard doesn't work.  This can normally be checked by pressing
the Caps Lock key. If the Caps Lock light doesn't change, you have to replace
your keyboard.  (Before doing this, you should try to restart
your computer and check all cables to the keyboard.)
@item
The mouse pointer doesn't move.
@item
The machine doesn't answer to a remote machine's pings.
@item
Other programs that are not related to MySQL don't behave correctly.
@item
Your system restarted unexpectedly. (A faulty user-level program should
never be able to take down your system.)
@end itemize

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 @code{glibc}) are up to date.

It's always good to use a machine with ECC memory to discover
memory problems early.
@item
If your keyboard is locked up, you may be able to recover by
logging in to your machine from another machine and executing
@code{kbd_mode -a}.

@item
Please examine your system log file (@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. @xref{Log Files}.

@item
If you don't think you have hardware problems, you should try to find
out which program is causing problems.
Try using @command{top}, @command{ps}, Task Manager, or some similar program,
to check which program is taking all CPU or is locking the machine.

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

@item
If the problem is some runaway process, you can always try to kill it. If it
doesn't want to die, there is probably a bug in the operating system.
@end itemize

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:

@itemize @bullet
@item
Has the program in question made a segmentation fault (did it dump core)?
@item
Is the program taking up all available CPU time? Check with @command{top}. Let
the program run for a while, it may simply be evaluating something
computationally intensive.
@item
If the @command{mysqld} server is causing problems, can you get any response
from it with @command{mysqladmin -u root ping} or @command{mysqladmin -u root
processlist}?
@item
What does a client program say when you try to connect to the MySQL server?
(Try with @command{mysql}, for example.) Does the client jam?  Do you get any
output from the program?
@end itemize

When sending a bug report, you should follow the outline
described in @ref{Asking questions}.


@node Common errors, Installation Issues, What is crashing, Problems
@appendixsec Common Errors When Using MySQL Programs

@cindex errors, list of

@menu
* Error Access denied::         @code{Access denied}
* Can not connect to server::   @code{Can't connect to [local] MySQL server}
* Old client::                  @code{Client does not support authentication protocol}
* Password too long::           Password Fails When Entered Interactively
* Blocked host::                @code{Host '@var{host_name}' is blocked}
* Too many connections::        @code{Too many connections}
* Out of memory::               @code{Out of memory}
* Gone away::                   @code{MySQL server has gone away}
* Packet too large::            @code{Packet too large}
* Communication errors::        Communication Errors and Aborted Connections
* Full table::                  @code{The table is full}
* Cannot create::               @code{Can't create/write to file}
* Commands out of sync::        @code{Commands out of sync}
* Ignoring user::               @code{Ignoring user}
* Cannot find table::           @code{Table '@var{tbl_name}' doesn't exist}
* Cannot initialize character set::  @code{Can't initialize character set}
* Not enough file handles::     File Not Found
@end menu


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.


@node Error Access denied, Can not connect to server, Common errors, Common errors
@appendixsubsec @code{Access denied}

@cindex errors, access denied
@cindex problems, access denied errors
@cindex access denied errors

An @code{Access denied} error can have many causes.  Often the problem is
related to the MySQL accounts that the server allows client programs to
use when connecting.
@xref{Access denied}.
@xref{Privileges}.


@node Can not connect to server, Old client, Error Access denied, Common errors
@appendixsubsec @code{Can't connect to [local] MySQL server}

A MySQL client on Unix can connect to the @command{mysqld} server in two
different ways: By using a Unix socket file to connect through a file in the
filesystem (default @file{/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 @code{localhost}.

If the MySQL server is running on Windows 9x or Me, you can connect
only via TCP/IP. If the server is running on Windows NT, 2000, XP, or 2003
and is started with the @code{--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 @code{MySQL} by default.
If you don't give a hostname when connecting to @command{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 @code{.} as the hostname.

The error (2002) @code{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
server.

Start by checking whether there is a process named @command{mysqld} running on
your server host.
(Use @command{ps xa | grep mysqld} on Unix or the Task Manager on Windows.)
If there is no such process, you should start the server.
@xref{Starting server}.

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

@example
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
@end example

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

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

@itemize @bullet
@item
@command{mysqld} is not running. Check your operating system's process list to
ensure the @command{mysqld} process is present.

@item
You are running on a system that uses MIT-pthreads.
If you are running on a system that doesn't have native threads,
@command{mysqld} uses the MIT-pthreads package.  @xref{Which OS}.  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:

@example
shell> mysqladmin -h `hostname` version
@end example

@item
Someone has removed the Unix socket file that @command{mysqld} uses
(@file{/tmp/mysql.sock} by default).  For example, you might have a @command{cron} job that
removes old files from the @file{/tmp} directory.  You can always run
@command{mysqladmin version} to check whether the Unix socket file that
@command{mysqladmin} is trying to use really exists.  The fix in this case is
to change the @command{cron} job to not remove @file{mysql.sock} or to place
the socket file somewhere else.
@xref{Problems with mysql.sock,  , Problems with @file{mysql.sock}}.

@item
You have started the @command{mysqld} server with
the @code{--socket=/path/to/socket} option, 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 @code{--socket} option when you run
client programs. You also need to ensure that clients have permission to access
the @file{mysql.sock} file.
To find out where the mysql server socket is, you can do:

@example
shell> netstat -l | grep mysql
@end example

@xref{Problems with mysql.sock,  , Problems with @file{mysql.sock}}.

@item
You are using Linux and one server thread has died (dumped core).  In this case,
you must kill the other @command{mysqld} threads (for example, with @code{kill}
or with the @code{mysql_zap} script) before you can restart the MySQL
server.  @xref{Crashing}.
@item
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
@command{mysqld} with a @code{--socket} option that specifies a socket filename
in a directory where the server can create it and where client programs can
access it.
@end itemize

If you get the error message @code{Can't connect to MySQL server on
some_host}, you can try the following things to find out what the
problem is:

@itemize @bullet

@item
Check whether the server is running on that host by executing @code{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 @code{telnet: Unable to connect to remote host:
Connection refused}, then there is no server running on the given port.

@item
If the server is running on the local host, try using @command{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 @code{port} variable.)

@item
Make sure that your @command{mysqld} server was not started with the
@code{--skip-networking} option. If it was, you will not be able to connect
to it using TCP/IP.

@item
Check to make sure that there is no firewall blocking access to MySQL. 
Applications such as ZoneAlarm and the Windows XP personal firewall may need
to be configured to allow external access to a MySQL server. 

@end itemize


@node Old client, Password too long, Can not connect to server, Common errors
@appendixsubsec @code{Client does not support authentication protocol}

MySQL 4.1 and up uses an authentication protocol 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:

@example
shell> mysql
Client does not support authentication protocol requested
by server; consider upgrading MySQL client
@end example

To solve this problem, you should use one of the following approaches:

@itemize @bullet
@item
Upgrade all client programs to use a 4.1.1 or newer client library.
@item
When connecting to the server with a pre-4.1 client program, use an account
that still has a pre-4.1-style password.
@item
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 @code{SET PASSWORD}
statement and the @code{OLD_PASSWORD()} function:

@example
mysql> SET PASSWORD FOR
    -> '@var{some_user}'@@'@var{some_host}' = OLD_PASSWORD('@var{newpwd}');
@end example

Alternatively, use @code{UPDATE} and @code{FLUSH PRIVILEGES}:

@example
mysql> UPDATE mysql.user SET Password = OLD_PASSWORD('@var{newpwd}')
    -> WHERE Host = '@var{some_host}' AND User = '@var{some_user}';
mysql> FLUSH PRIVILEGES;
@end example

Substitute the password you want to use for ``@var{newpwd}'' in the preceding
examples.  MySQL cannot tell you what the original password was, so you'll
need to pick a new one.

@item
Tell the server to use the older password hashing algorithm:
@enumerate
@item
Start @command{mysqld} with the @code{--old-passwords} option.
@item
Assign an old-format password to each account that has had its password
updated to the longer 4.1 format. You can identify these accounts with the
following query:

@example
mysql> SELECT Host, User, Password FROM mysql.user
    -> WHERE LENGTH(Password) > 16;
@end example

For each account record displayed by the query, use the @code{Host} and @code{User} values and assign
a password using the @code{OLD_PASSWORD()} function and either @code{SET PASSWORD} or @code{UPDATE}, as described
earlier.
@end enumerate
@end itemize

For additional background on password hashing and authentication, see
@ref{Password hashing}.


@node Password too long, Blocked host, Old client, Common errors
@appendixsubsec Password Fails When Entered Interactively

MySQL client programs prompt for a password when invoked with a
@code{--password} or @code{-p} option that has no following password value:

@example
shell> mysql -u @var{user_name} -p
Enter password:
@end example

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 @code{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.


@node Blocked host, Too many connections, Password too long, Common errors
@appendixsubsec @code{Host '@var{host_name}' is blocked}

If you get the following error, it means that @command{mysqld} has received many
connect requests from the host @code{'@var{host_name}'} that have been
interrupted in the middle:

@example
Host '@var{host_name}' is blocked because of many connection errors.
Unblock with 'mysqladmin flush-hosts'
@end example

The number of interrupted connect requests allowed is determined by the
value of the @code{max_connect_errors} system variable.  After
@code{max_connect_errors} failed requests, @command{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
@command{mysqladmin flush-hosts} command or issue a @code{FLUSH HOSTS}
statement.
@xref{Server system variables}.

By default, @command{mysqld} blocks a host after 10 connection errors.
You can adjust the value by starting the server like this:

@example
shell> mysqld_safe --max_connect_errors=10000 &
@end example

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 will do you no good to
increase the value of the @code{max_connect_errors} variable.


@node Too many connections, Out of memory, Blocked host, Common errors
@appendixsubsec @code{Too many connections}

If you get a @code{Too many connections} error when you try to connect to the
@command{mysqld} server, this means that that all available connections already
are used by other clients.

The number of connections allowed is controlled by the @code{max_connections}
system variable. Its default value is 100.  If you need to support more
connections, you should restart @command{mysqld} with a larger value for this
variable.

@command{mysqld} actually allows @code{max_connections+1} clients to
connect.  The extra connection is reserved for use by accounts that have the
@code{SUPER} privilege.  By granting the @code{SUPER} privilege to
administrators and not to normal users (who should not need it), an
administrator can connect to the server and use @code{SHOW PROCESSLIST} to
diagnose problems even if the maximum number of unprivileged clients
already are connected.
@xref{SHOW PROCESSLIST,  , @code{SHOW PROCESSLIST}}.

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. Static Linux binaries provided
by MySQL AB can support up to 4000 connections.


@node Out of memory, Gone away, Too many connections, Common errors
@appendixsubsec @code{Out of memory}

If you issue a query using the @command{mysql} client program and receive an
error like the following one, it means that @command{mysql} does not
have enough memory to store the entire query result:

@example
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
@end example

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 @command{mysql} with the @code{--quick}
option. This causes it to use the @code{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).


@node Gone away, Packet too large, Out of memory, Common errors
@appendixsubsec @code{MySQL server has gone away}

@findex CR_SERVER_GONE_ERROR
@findex CR_SERVER_LOST_ERROR

This section also covers the related @code{Lost connection to server
during query} error.

The most common reason for the @code{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):

@multitable @columnfractions .35 .65
@item @strong{Error Code} @tab @strong{Description}
@item @code{CR_SERVER_GONE_ERROR} @tab The client couldn't send a question to the
server.
@item @code{CR_SERVER_LOST} @tab 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.
@end multitable

By default, the
server closes the connection after eight hours if nothing has happened. You
can change the time limit by setting the @code{wait_timeout} variable when
you start @command{mysqld}.
@xref{Server system variables}.

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 @code{mysql}
command-line client).

Some other common reasons for the @code{MySQL server has gone away} error are:

@itemize @bullet
@item
You (or the db administrator) has killed the running thread with a
@code{KILL} statement or a @command{mysqladmin kill} command.
@item
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.
@item
You got a timeout from the TCP/IP connection on the client side.
This may happens if you have been using the commands:
@code{mysql_options(..., MYSQL_OPT_READ_TIMEOUT,...)} or
@code{mysql_options(..., MYSQL_OPT_WRITE_TIMEOUT,...)}. In this case
increasing the timeout may help solve the problem.
@item
You have encountered a timeout on the server side and the
automatic reconnection in the client is disabled (the @code{reconnect} flag
in the @code{MYSQL} structure is equal to 0).
@item
You are using a windows client and the server had dropped the connection
(probably because @code{wait_timeout} expired) before the command was
issued.

The problem on windows is that in some cases MySQL doesn't 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 connection.

In this case, even if the @code{reconnect} flag in the @code{MYSQL} structure
is equal to 1, MySQL will not automatically reconnect and re-issue the query as
it doesn't know if the server did get the original query or not.

The solution to this is to either do a @code{mysql_ping} on the
connection if there has been a long time since the last query (this is
what @code{MyODBC} does) or set @code{wait_timeout} on the @code{mysqld}
server so high that it will in practice never time out.
@item
You can also get these errors if you send a query to the server that is
incorrect or too large. If @command{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 @code{BLOB} columns), you can increase the query limit by
setting the server's @code{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
@ref{Packet too large}.

@item
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.

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

@item
You have encountered a bug where the server died while executing the query.
@end itemize

You can check whether the MySQL server died and restarted by executing
@command{mysqladmin version} and examining the server's uptime.  If the
client connection was broken because @command{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.
@xref{Crashing}.

You can get more information about the lost connections by starting
mysqld with the @code{--log-warnings=2} option.  This will log some of the
disconnected errors in the @code{hostname.err} file. @xref{Error log}.

If you want to create a bug report regarding this problem, be sure that
you include the following information:

@itemize @bullet
@item
Indicate whether or not the MySQL server died. You can find information
about this in the server error log.
@xref{Crashing}.
@item
If a specific query kills @command{mysqld} and the tables involved were
checked with @code{CHECK TABLE} before you ran the query, can you provide a
reproducible test case?
@xref{Reproduceable test case}.
@item
What is the value of the @code{wait_timeout} system variable in the MySQL
server?  (@command{mysqladmin variables} gives you the value of this variable.)
@item
Have you tried to run @command{mysqld} with the @code{--log} option to
determine whether the problem query appears in the log?
@end itemize

See also @xref{Communication errors}.

@xref{Asking questions}.

@node Packet too large, Communication errors, Gone away, Common errors
@appendixsubsec @code{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.

@c commented out: too vague
@c In MySQL 4.0.1 and up, this is only limited by
@c the amount on memory you have on your server (up to a theoretical
@c maximum of 2GB).

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

Both the client and the server have their own
@code{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.

If you are using the @command{mysql} client program, its default
@code{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 @command{mysql} like
this:

@example
mysql> mysql --max_allowed_packet=32M
@end example

That sets the packet size to 32MB.

The server's default @code{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 @code{BLOB} columns).  For example, to set the variable to
16MB, start the server like this:

@example
mysql> mysqld --max_allowed_packet=16M
@end example

Before MySQL 4.0, use this syntax instead:

@example
mysql> mysqld --set-variable=max_allowed_packet=16M
@end example

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

@example
[mysqld]
max_allowed_packet=16M
@end example

Before MySQL 4.0, use this syntax instead:

@example
[mysqld]
set-variable = max_allowed_packet=16M
@end example

It's safe to increase the value of this variable because the extra memory is
allocated only when needed.  For example, @command{mysqld} allocates more
memory only when you issue a long query or when @command{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 don't run out of memory by using large packets
accidentally.

You can also get strange problems with large packets if you are using large
@code{BLOB} values but have not given @command{mysqld} access to enough memory
to handle the query.  If you suspect this is the case, try adding
@command{ulimit -d 256000} to the beginning of the @command{mysqld_safe} script
and restarting @command{mysqld}.


@node Communication errors, Full table, Packet too large, Common errors
@appendixsubsec Communication Errors and Aborted Connections

@cindex aborted clients
@cindex aborted connection
@cindex connection, aborted

The server error log can be a useful source of information about connection
problems.
@xref{Error log}.
Starting with MySQL 3.23.40, if you start the server with the
@code{--warnings} option (or @code{--log-warnings} from MySQL 4.0.3 on), you
might find messages like this in your error log:

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

If @code{Aborted connections} messages appear in the error log, the cause
can be any of the following:

@itemize @bullet
@item
The client program did not call @code{mysql_close()} before exiting.
@item
The client had been sleeping more than @code{wait_timeout} or
@code{interactive_timeout} seconds without issuing any requests to the server.
@xref{Server system variables}.
@item
The client program ended abruptly in the middle of a data transfer.
@end itemize

When any of these things happen, the server increments the
@code{Aborted_clients} status variable.

The server increments the @code{Aborted_connects} status variable when the
following things happen:

@itemize @bullet
@item
A client doesn't have privileges to connect to a database.
@item
A client uses an incorrect password.
@item
A connection packet doesn't contain the right information.
@item
It takes more than @code{connect_timeout} seconds to get
a connect packet.
@xref{Server system variables}.
@end itemize

If these kinds of things happen, it might indicate that someone is
trying to break into your server!

Other reasons for problems with aborted clients or aborted connections:

@itemize @bullet
@item
Use of Ethernet protocol with Linux, both half and full duplex.
Many Linux Ethernet drivers have this bug. You should test for this
bug by transferring a huge file via FTP between the client and server machines.
If a transfer goes in burst-pause-burst-pause mode, you are
experiencing a Linux duplex syndrome.
The only solution is switching the duplex mode for both your network card
and hub/switch to either full duplex or to half duplex and testing the
results to determine the best setting.
@item
Some problem with the thread library that causes interrupts on reads.
@item
Badly configured TCP/IP.
@item
Faulty Ethernets, hubs, switches, cables, and so forth. This can be diagnosed
properly only by replacing hardware.
@item
The @code{max_allowed_packet} variable value is too small or queries require
more memory than you have allocated for @command{mysqld}.
@xref{Packet too large}.
@end itemize

See also @xref{Gone away}.

@node Full table, Cannot create, Communication errors, Common errors
@appendixsubsec @code{The table is full}

@cindex table is full

There are several ways a full-table error can occur:

@itemize @bullet
@item
You are using a MySQL server older than 3.23 and an in-memory
temporary table becomes larger than @code{tmp_table_size} bytes.
To avoid this problem, you can use the @code{-O tmp_table_size=#} option
to make @command{mysqld} increase the temporary table size or use the SQL
option @code{SQL_BIG_TABLES} before you issue the problematic query.
@xref{SET OPTION, ,@code{SET}}.

You can also start @command{mysqld} with the @code{--big-tables} option.
This is exactly the same as using @code{SQL_BIG_TABLES} for all queries.

As of MySQL 3.23, this problem should not occur. If an in-memory temporary
table becomes larger than @code{tmp_table_size}, the server automatically
converts it to a disk-based @code{MyISAM} table.
@item
You are using @code{InnoDB} tables and run out of room in the
@code{InnoDB} tablespace. In this case, the solution is to extend the
@code{InnoDB} tablespace.
@xref{Adding and removing}.
@item
You are using @code{ISAM} or @code{MyISAM} tables 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.
@item
You are using a @code{MyISAM} table and the space required for the table
exceeds what is allowed by the internal pointer size.  (If you don't specify
the @code{MAX_ROWS} table option when you create a table, MySQL
uses the @code{myisam_data_pointer_size} system variable. Its default value of
4 bytes is enough to allow only 4GB of data.)
@xref{Server system variables, @code{myisam_data_pointer_size}}.

You can check the maximum data/index sizes by using this statement:
@example
SHOW TABLE STATUS FROM database LIKE '@var{tbl_name}';
@end example

You also can use @command{myisamchk -dv /path/to/table-index-file}.

If the pointer size is too small, you can fix the problem by using @code{ALTER
TABLE}:

@example
ALTER TABLE @var{tbl_name} MAX_ROWS=1000000000 AVG_ROW_LENGTH=@var{nnn};
@end example

You have to specify @code{AVG_ROW_LENGTH} only for tables with @code{BLOB}
or @code{TEXT} columns; in this case, MySQL can't optimize the space
required based only on the number of rows.

@end itemize


@node Cannot create, Commands out of sync, Full table, Common errors
@appendixsubsec @code{Can't create/write to file}

@cindex 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:

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

The preceding error is a
typical message for Windows; the Unix message is similar.

One fix is to start @command{mysqld} with the @code{--tmpdir} option or to
add the option to the @code{[mysqld]} section of your option file.
For example, to specify a directory of @file{C:\temp}, use these lines:

@example
[mysqld]
tmpdir=C:/temp
@end example

The @file{C:\temp} directory must already exist and have sufficient space for the
MySQL server to write to. @xref{Option files}.

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

Check also the error code that you get with @command{perror}. One reason
the server cannot write to a table is that the filesystem is full:

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


@node Commands out of sync, Ignoring user, Cannot create, Common errors
@appendixsubsec @code{Commands out of sync}

@cindex commands out of sync

If you get @code{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 @code{mysql_use_result()} and
try to execute a new query before you have called @code{mysql_free_result()}.
It can also happen if you try to execute two queries that return data without
calling @code{mysql_use_result()} or @code{mysql_store_result()} in between.


@node Ignoring user, Cannot find table, Commands out of sync, Common errors
@appendixsubsec @code{Ignoring user}

If you get the following error, it means that when @command{mysqld} was started
or when it reloaded the grant tables, it found an account in the @code{user}
table that had an invalid password.

@code{Found wrong password for user '@var{some_user}'@@'@var{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:

@itemize @bullet
@item
You may be running a new version of @command{mysqld} with an old @code{user}
table.  You can check this by executing @command{mysqlshow mysql user} to see
whether the @code{Password} column is shorter than 16 characters. If so, you
can correct this condition by running the @code{scripts/add_long_password}
script.

@item
The account has an old password (eight characters long) and you didn't start
@command{mysqld} with the @code{--old-protocol} option.
Update the account in the @code{user} table to have a new password or
restart @command{mysqld} with the @code{--old-protocol} option.

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

@example
mysql> UPDATE user SET Password=PASSWORD('@var{newpwd}')
    -> WHERE User='@var{some_user}' AND Host='@var{some_host}';
@end example

@end itemize


@node Cannot find table, Cannot initialize character set, Ignoring user, Common errors
@appendixsubsec @code{Table '@var{tbl_name}' doesn't exist}

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

@example
Table '@var{tbl_name}' doesn't exist
Can't find file: '@var{tbl_name}' (errno: 2)
@end example

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

@itemize @bullet
@item
Because MySQL uses directories and files to store databases and
tables, database and table names are case sensitive if they are located on
a filesystem that has case-sensitive filenames.

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

@end itemize


You can check which tables are in the current database with
@code{SHOW TABLES}. @xref{SHOW, , @code{SHOW}}.


@node Cannot initialize character set, Not enough file handles, Cannot find table, Common errors
@appendixsubsec @code{Can't initialize character set}

@cindex multi-byte character sets

You might see an error like this if you have character set problems:

@example
MySQL Connection Failed: Can't initialize character set charset_name
@end example

This error can have any of the following causes:

@itemize @bullet
@item
The character set is a multi-byte character set and you have no support
for the character set in the client.
In this case, you need to recompile the client by running @command{configure}
with the @code{--with-charset=@var{charset_name}} or
@code{--with-extra-charsets=@var{charset_name}}
option.
@xref{configure options,  , @command{configure} options}.

All standard MySQL binaries are compiled with
@code{--with-extra-character-sets=complex}, which enables support for
all multi-byte character sets. @xref{Character sets}.

@item
The character set is a simple character set that is not compiled into
@command{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:

@itemize @bullet
@item
Recompile the client with support for the character set.
@xref{configure options,  , @command{configure} options}.
@item
Specify to the client the directory where the character set definition files
are located. For many clients, you can do this with the
@code{--character-sets-dir} option.
@item
Copy the character definition files to the path where the client expects them
to be.
@end itemize
@end itemize


@node Not enough file handles,  , Cannot initialize character set, Common errors
@appendixsubsec File Not Found

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

@example
shell> perror 23
Error code  23:  File table overflow
shell> perror 24
Error code  24:  Too many open files
shell> perror 11
Error code  11:  Resource temporarily unavailable
@end example

The problem here is that @command{mysqld} is trying to keep open too many
files simultaneously.  You can either tell @command{mysqld} not to open so
many files at once or increase the number of file descriptors
available to @command{mysqld}.

To tell @command{mysqld} to keep open fewer files at a time, you can make the
table cache smaller by reducing the value of the @code{table_cache} system
variable (the default value is 64). Reducing the value of
@code{max_connections} also will reduce the number of open files (the
default value is 100).

@tindex ulimit
To change the number of file descriptors available to @command{mysqld}, you can
use the @code{--open-files-limit} option to @command{mysqld_safe} or (as of
MySQL 3.23.30) set the @code{open_files_limit} system variable.
@xref{Server system variables}.
The easiest way to set these values is to add an option to your option file.
@xref{Option files}.  If you have an old version of @command{mysqld} that
doesn't support setting the open files limit, you can edit the
@command{mysqld_safe} script.  There is a commented-out line @command{ulimit -n
256} in the script.  You can remove the @samp{#} character to uncomment
this line, and change the number @code{256} to set the number of file
descriptors to be made available to @command{mysqld}.

@code{--open-files-limit} and @command{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
@command{mysqld_safe} or @command{mysqld} as @code{root} (just remember that you
also need to start the server with the @code{--user} option in this case so
that it does not continue to run as @code{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.

@strong{Note}: If you run the @command{tcsh} shell, @command{ulimit} will not work!
@command{tcsh} will also report incorrect values when you ask for the current
limits.  In this case, you should start @command{mysqld_safe} using @command{sh}.


@node Installation Issues, Administration Issues, Common errors, Problems
@appendixsec Installation-Related Issues


@menu
* Link errors::                 Problems Linking to the MySQL Client Library
* Changing MySQL user::         How to Run MySQL as a Normal User
* File permissions::            Problems with File Permissions
@end menu

@node Link errors, Changing MySQL user, Installation Issues, Installation Issues
@appendixsubsec Problems Linking to the MySQL Client Library

@cindex linking, errors
@cindex errors, linking
@cindex problems, linking

When you are linking an application program to use the MySQL client library,
you might get undefined reference errors for symbols that start with @code{mysql_},
such as those shown here:

@example
/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'
@end example

You should be able to solve this problem by adding @code{-Ldir_path
-lmysqlclient} at the end of your link command, where @code{dir_path}
represents the pathname of the directory where the client library is
located. To determine the correct directory, try this command:

@example
shell> mysql_config --libs
@end example

The output from @command{mysql_config} might indicate other libraries that
should be specified on the link command as well.

If you get @code{undefined reference} errors for the @code{uncompress}
or @code{compress} function, add @code{-lz} to the end of your
link command and try again.

If you get @code{undefined reference} errors for a function that should
exist on your system, such as @code{connect}, check the manual page for the
function in question to determine which libraries you should add to the link
command.

You might get @code{undefined reference} errors such as the following for
functions that don't exist on your system:

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

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.
@xref{Installing source}.

You might get undefined reference errors at runtime when you try to execute a
MySQL program. If these errors specify symbols that start with @code{mysql_}
or indicate that the @code{mysqlclient} library can't be found, it means
that your system can't find the shared @file{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:

@itemize @bullet
@item
Add the path to the directory where @file{libmysqlclient.so} is located to the
@code{LD_LIBRARY_PATH} environment variable.
@item
Add the path to the directory where @file{libmysqlclient.so} is located to the
@code{LD_LIBRARY} environment variable.
@item
Copy @file{libmysqlclient.so} to some directory that is searched by your system,
such as @file{/lib}, and update the shared library information by executing
@code{ldconfig}.
@end itemize

Another way to solve this problem is by linking your program statically with
the @code{-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.


@node Changing MySQL user, File permissions, Link errors, Installation Issues
@appendixsubsec How to Run MySQL as a Normal User

@cindex starting, @command{mysqld}
@cindex @command{mysqld}, starting

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 @command{mysqld} can be started and run by any user.
However, you should avoid running the server as the Unix @code{root} user
for security reasons.  In order to change @command{mysqld} to run as a normal
unprivileged Unix user @var{user_name}, you must do the following:

@enumerate
@item
Stop the server if it's running (use @command{mysqladmin shutdown}).

@item
Change the database directories and files so that @var{user_name} has
privileges to read and write files in them (you might need to do this as
the Unix @code{root} user):

@example
shell> chown -R @var{user_name} @var{/path/to/mysql/datadir}
@end example

If you do not do this, the server will not be able to access databases or tables when it
runs as @var{user_name}.

If 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.  @code{chown -R} might not follow symbolic links for you.

@item
Start the server as user @var{user_name}. If you are using MySQL 3.22 or
later, another alternative is to start @command{mysqld} as the Unix @code{root}
user and use the @code{--user=@var{user_name}} option.  @command{mysqld} will start up,
then switch
to run as the Unix user @var{user_name} before accepting any connections.

@item
To start the server as the given user automatically at system
startup time, specify the username by adding a @code{user} option to
the @code{[mysqld]} group of the @file{/etc/my.cnf} option file or the
@file{my.cnf} option file in the server's data directory. For example:

@example
[mysqld]
user=@var{user_name}
@end example
@end enumerate

If your Unix machine itself isn't secured, you should assign passwords
to the MySQL @code{root} accounts in the grant tables.  Otherwise, any
user with a login account on that machine can run the @command{mysql} client with a
@code{--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.)
@xref{Post-installation}.


@node File permissions,  , Changing MySQL user, Installation Issues
@appendixsubsec Problems with File Permissions

@cindex files, permissions
@cindex error messages, can't find file
@cindex files, not found message

@tindex UMASK environment variable
@tindex Environment variable, UMASK
If you have problems with file permissions, the @code{UMASK} environment
variable might be set incorrectly when @command{mysqld} starts.  For example,
MySQL might issue the following error message when you create a table:

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

The default @code{UMASK} value is @code{0660}. You can change this behavior by
starting @command{mysqld_safe} as follows:

@example
shell> UMASK=384  # = 600 in octal
shell> export UMASK
shell> mysqld_safe &
@end example

@tindex UMASK_DIR environment variable
@tindex Environment variable, UMASK_DIR

By default, MySQL creates database and @code{RAID} directories
with an access permission value of @code{0700}.  You can modify this
behavior by setting the @code{UMASK_DIR} variable. If you set its value, new
directories are created with the combined @code{UMASK} and @code{UMASK_DIR}
values. For example, if you want to give group access to all new
directories, you can do this:

@example
shell> UMASK_DIR=504  # = 770 in octal
shell> export UMASK_DIR
shell> mysqld_safe &
@end example

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

@xref{Environment variables}.


@node Administration Issues, Query Issues, Installation Issues, Problems
@appendixsec Administration-Related Issues


@menu
* Resetting permissions::       How to Reset the Root Password
* Crashing::                    What to Do If MySQL Keeps Crashing
* Full disk::                   How MySQL Handles a Full Disk
* Temporary files::             Where MySQL Stores Temporary Files
* Problems with mysql.sock::    How to Protect or Change the MySQL Socket File @file{/tmp/mysql.sock}
* Timezone problems::           Time Zone Problems
@end menu


@node Resetting permissions, Crashing, Administration Issues, Administration Issues
@appendixsubsec How to Reset the Root Password

@cindex passwords, forgotten
@cindex passwords, lost
@cindex passwords, resetting
@cindex root user, password resetting

If you have never set a @code{root} password for MySQL, the server will
not require a password at all for connecting as @code{root}. However, it is
recommended to set a password for each account. @xref{Security guidelines}.

If you set a @code{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:

@enumerate
@item
Log on to your system as Administrator.
@item
Stop the MySQL server if it is running. For a server that is running as a
Windows service, go to the Services manager:
@example
Start Menu -> Control Panel -> Administrative Tools -> Services
@end example
Then 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.
@item
Open a console window to get to the DOS command prompt:
@example
Start Menu -> Run -> cmd
@end example
@item
We are assuming that you installed MySQL to @file{C:\mysql}. If you installed
MySQL to another location, adjust the following commands accordingly.

At the DOS command prompt, execute this command:
@example
C:\> C:\mysql\bin\mysqld-nt --skip-grant-tables
@end example
This starts the server in a special mode that does not check the grant
tables to control access.
@item
Keeping the first console window open, open a second console window and
execute the following commands (type each on a single line):
@example
C:\> C:\mysql\bin\mysqladmin -u root
         flush-privileges password "@var{newpwd}"
C:\> C:\mysql\bin\mysqladmin -u root -p shutdown
@end example
Replace ``@var{newpwd}'' with the actual @code{root} password 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.
@item
Stop the MySQL server, then restart it in normal mode again.
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.
@item
You should now be able to connect using the new password.
@end enumerate


In a Unix environment, the procedure for resetting the @code{root} password
is as follows:

@enumerate
@item
Log on to your system as either the Unix @code{root} user or as the
same user that the @command{mysqld} server runs as.
@item
Locate the @file{.pid} file that contains the server's process ID.
The exact location and name of this file depend on your distribution,
hostname, and configuration. Common locations are @file{/var/lib/mysql/},
@file{/var/run/mysqld/}, and @file{/usr/local/mysql/data/}. Generally, the
filename has the extension of @file{.pid} and begins with either
@file{mysqld} or your system's hostname.

Now you can stop the MySQL server by sending a normal @code{kill}
(not @code{kill -9}) to the @command{mysqld} process, using the pathname of the
@file{.pid} file in the following command:
@example
shell> kill `cat /mysql-data-directory/host_name.pid`
@end example
Note the use of backticks rather than forward quotes with the @code{cat}
command; these cause the output of @code{cat}
to be substituted into the @code{kill} command.
@item
Restart the MySQL server with the special @code{--skip-grant-tables} option:
@example
shell> mysqld_safe --skip-grant-tables &
@end example
@item
Set a new password for the @code{root@@localhost} MySQL account:
@example
shell> mysqladmin -u root flush-privileges password "@var{newpwd}"
@end example
Replace ``@var{newpwd}'' with the actual @code{root} password that you want
to use.
@item
You should now be able to connect using the new password.
@end enumerate

Alternatively, on any platform, you can set the new password using the @command{mysql} client:
@enumerate
@item
Stop @command{mysqld} and restart it with the @code{--skip-grant-tables}
option as described earlier.
@item
Connect to the @command{mysqld} server with this command:
@example
shell> mysql -u root
@end example
@item
Issue the following statements in the @command{mysql} client:
@example
mysql> UPDATE mysql.user SET Password=PASSWORD('@var{newpwd}')
    ->                   WHERE User='root';
mysql> FLUSH PRIVILEGES;
@end example

Replace ``@var{newpwd}'' with the actual @code{root} password that you want
to use.
@item
You should now be able to connect using the new password.
@end enumerate


@node Crashing, Full disk, Resetting permissions, Administration Issues
@appendixsubsec What to Do If MySQL Keeps Crashing

@cindex crash, repeated

Each MySQL version is tested on many platforms before it is
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, because 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 @command{mysqld} server dies or whether your problem has to do with your
client.  You can check how long your @command{mysqld} server has been up by
executing @command{mysqladmin version}.  If @command{mysqld} has died and
restarted, you may find the reason by looking in the server's error log.
@xref{Error log}.

On some systems, you can find in the error log a stack trace of where
@command{mysqld} died that you can resolve with the @code{resolve_stack_dump}
program.  @xref{Using 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 @code{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 @code{--delay-key-write}, in which case
data files are written but not index files.) This means that data file
contents are safe even
if @command{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 @command{mysqld} with the
@code{--flush} option.

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

@itemize @bullet
@item
The MySQL server or the server host was killed in the middle of an update.
@item
You have found a bug in @command{mysqld} that caused it to die in the
middle of an update.
@item
Some external program is manipulating data files or index files at the same
time as @command{mysqld} without locking the table properly.
@item
You are running many @command{mysqld} servers using the same data directory on
a system that doesn't support good filesystem locks (normally handled by the
@code{lockd} lock manager), or you are running multiple servers with the
@code{--skip-external-locking} option.
@item
You have a crashed data file or index file that contains very corrupt data that
confused @command{mysqld}.
@item
You have found a bug in the data storage code. This isn't likely, but it's
at least possible.  In this case, you can try to change the table type to
another storage engine by using @code{ALTER TABLE} on a repaired copy of the
table.
@end itemize

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:

@itemize @bullet
@item
Stop the @command{mysqld} server with @command{mysqladmin shutdown}, run
@command{myisamchk --silent --force */*.MYI} from the data directory to check
all @code{MyISAM} tables, and restart @command{mysqld}.  This will ensure that
you are running from a clean state.
@xref{MySQL Database Administration}.

@item
Start @command{mysqld} with the @code{--log} option 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.
@xref{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.
@xref{Bug reports}.

@item
Try to make a test case that we can use to repeat the problem.
@xref{Reproduceable test case}.

@item
Try running the tests in the @file{mysql-test} directory and the MySQL
benchmarks.  @xref{MySQL test suite}.  They should test MySQL
rather well.  You can also add code to the benchmarks that simulates
your application.  The benchmarks can be found in the @file{sql-bench}
directory in a source distribution or, for a binary distribution, in
the @file{sql-bench} directory under your MySQL installation
directory.

@item
Try the @code{fork_big.pl} script.  (It is located in the @file{tests}
directory of source distributions.)

@item
If you configure MySQL for debugging, it will be much easier to
gather information about possible errors if something goes wrong.
Configuring MySQL for debugging causes a safe memory allocator to be
included that can find some errors. It also provides a lot of output
about what is happening.  Reconfigure MySQL with the @code{--with-debug}
or @code{--with-debug=full} option to @command{configure} and then recompile.
@xref{Debugging server}.

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

@item
Use the @code{--skip-external-locking} option to @command{mysqld}.  On some
systems, the @code{lockd} lock manager does not work properly; the
@code{--skip-external-locking} option tells @command{mysqld} not to use external
locking.  (This means that you cannot run two @command{mysqld} servers on the same
data directory and that you must be careful if you use @command{myisamchk}.
Nevertheless, it may be instructive to try the option as a test.)

@item
Have you tried @command{mysqladmin -u root processlist} when @command{mysqld}
appears to be running but not responding?  Sometimes @command{mysqld} is 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.
@command{mysqladmin -u root processlist} usually 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.

@item
Run the command @command{mysqladmin -i 5 status} or @command{mysqladmin -i 5
-r status} in a separate window to produce statistics while you run
your other queries.

@item
Try the following:
@enumerate
@item
Start @command{mysqld} from @command{gdb} (or another debugger).
@xref{Using gdb on mysqld,  , Using @command{gdb} on @command{mysqld}}.

@item
Run your test scripts.

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

@example
backtrace
info local
up
info local
up
info local
@end example

With @command{gdb}, you can also examine which threads exist with @code{info
threads} and switch to a specific thread with @code{thread #}, where
@code{#} is the thread ID.
@end enumerate

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

@item
Send a normal bug report. @xref{Bug reports}. Be even more detailed
than usual.  Because MySQL works for many people, it may be that the
crash results from something that exists only on your computer (for example,
an error that is related to your particular system libraries).
@item
If you have a problem with tables containing dynamic-length rows and you are
using only @code{VARCHAR} columns (not @code{BLOB} or @code{TEXT} columns), you
can try to change all @code{VARCHAR} to @code{CHAR} with @code{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 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.

@item
Do not rule out your server hardware when diagnosing problems. Defective hardware
can be the cause of data corruption. Particular attention should be paid to both
RAMS and hard-drives when troubleshooting hardware.
@end itemize


@node Full disk, Temporary files, Crashing, Administration Issues
@appendixsubsec How MySQL Handles a Full Disk

@cindex full disk
@cindex disk full

@noindent
This paragraph is relevant only for MyISAM table writes.
It refers to disk-full ("no space left on device" etc) errors, but
also applies, starting from MySQL 4.0.22, to quota-exceeded errors ("write
failed, user block limit reached" etc).
When a disk-full condition occurs, MySQL does the following:

@itemize @bullet
@item
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.
@item
Every 10 minutes it writes an entry to the log file, warning about the
disk-full condition.
@end itemize

@noindent
To alleviate the problem, you can take the following actions:

@itemize @bullet
@item
To continue, you only have to free enough disk space to insert all records.
@item
To abort the thread, you must use @command{mysqladmin kill}.
The thread will be aborted the next time it checks the disk (in one minute).
@item
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 will allow the other threads to
continue.
@end itemize

Exceptions to the preceding behavior are when you use @code{REPAIR TABLE} or
@code{OPTIMIZE TABLE} or when the indexes are created in a batch after
@code{LOAD DATA INFILE} or after an @code{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 will remove the big temporary files and mark the table as crashed.
The exception is that for @code{ALTER TABLE}, the old table will be left
unchanged.


@node Temporary files, Problems with mysql.sock, Full disk, Administration Issues
@appendixsubsec Where MySQL Stores Temporary Files

MySQL uses the value of the @code{TMPDIR} environment variable as the
pathname of the directory in which to store temporary files.  If you don't
have @code{TMPDIR} set, MySQL uses the system default, which is normally
@file{/tmp}, @file{/var/tmp}, or @file{/usr/tmp}.  If the filesystem
containing your temporary file directory is too small, you can use the
@code{--tmpdir} option to @command{mysqld} to specify a directory in a
filesystem where you have enough space.

Starting from MySQL 4.1, the @code{--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 (@samp{:}) on Unix and semicolon characters
(@samp{;}) on Windows, NetWare, and OS/2.  @strong{Note}: To spread the load
effectively, these paths should be located on different
@emph{physical} disks, not different partitions of the same disk.

If the MySQL server is acting as a replication slave, you should not set
@code{--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 @code{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 @command{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
located.

When sorting (@code{ORDER BY} or @code{GROUP BY}), MySQL normally
uses one or two temporary files. The maximum disk space required is determined
by the following expression:

@example
(length of what is sorted + sizeof(row pointer))
* number of matched rows
* 2
@end example

The row pointer size is usually four bytes, but may grow in the future for
really big tables.

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

@code{ALTER TABLE} creates a temporary table in the same directory as
the original table.

@node Problems with mysql.sock, Timezone problems, Temporary files, Administration Issues
@appendixsubsec How to Protect or Change the MySQL Socket File @file{/tmp/mysql.sock}

@cindex @code{mysql.sock}, protection
@cindex deletion, @code{mysql.sock}

The default location for the Unix socket file that the server uses for
communication with local clients is @file{/tmp/mysql.sock}.  This might
cause problems, because on some versions of Unix, anyone can delete files
in the @file{/tmp} directory.

On most versions of Unix, you can protect your @file{/tmp} directory so that
files can be deleted only by their owners or the superuser (@code{root}).
To do this, set the @code{sticky} bit on the @file{/tmp} directory by
logging in as @code{root} and using the following command:

@example
shell> chmod +t /tmp
@end example

You can check whether the @code{sticky} bit is set by executing @code{ls -ld
/tmp}.  If the last permission character is @code{t}, the bit is set.

@cindex changing socket location

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:

@itemize @bullet
@item
Specify the path in a global or local option file.
For example, put the following lines in @code{/etc/my.cnf}:

@example
[mysqld]
socket=/path/to/socket

[client]
socket=/path/to/socket
@end example
@xref{Option files}.

@item
Specify a @code{--socket} option on the command line
to @command{mysqld_safe} and when you run client programs.

@item
Set the @code{MYSQL_UNIX_PORT} environment variable to the path of the Unix
socket file.

@item
Recompile MySQL from source to use a different default Unix socket
file location.  Define the path to the file with the
@code{--with-unix-socket-path}  option when you run @command{configure}.
@xref{configure options,  , @command{configure} options}.

@end itemize

You can test whether the new socket location works by attempting to connect to
the server with this command:

@example
shell> mysqladmin --socket=/path/to/socket version
@end example

@node Timezone problems,  , Problems with mysql.sock, Administration Issues
@appendixsubsec Time Zone Problems

@cindex time zone problems
@cindex problems, time zone

@tindex TZ environment variable
@tindex Environment variable, TZ

If you have a problem with @code{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 @code{UNIX_TIMESTAMP()} returns the wrong value.
This should be done for the environment in which the server runs; for
example, in @command{mysqld_safe} or @command{mysql.server}.
@xref{Environment variables}.

You can set the time zone for the server with the
@code{--timezone=timezone_name} option to @command{mysqld_safe}.  You can
also set it by setting the @code{TZ} environment variable before you
start @command{mysqld}.

The allowable values for @code{--timezone} or @code{TZ} are
system-dependent. Consult your operating system documentation to see
what values are acceptable.

@node Query Issues, Optimizer Issues, Administration Issues, Problems
@appendixsec Query-Related Issues


@menu
* Case sensitivity::            Case Sensitivity in Searches
* Using DATE::                  Problems Using @code{DATE} Columns
* Problems with NULL::          Problems with @code{NULL} Values
* Problems with alias::         Problems with Column Aliases
* Non-transactional tables::    Rollback Failure for Non-Transactional Tables
* Deleting from related tables::  Deleting Rows from Related Tables
* No matching rows::            Solving Problems with No Matching Rows
* Problems with float::         Problems with Floating-Point Comparisons
@end menu

@node Case sensitivity, Using DATE, Query Issues, Query Issues
@appendixsubsec Case Sensitivity in Searches

@cindex case sensitivity, in searches
@cindex searching, and case sensitivity
@cindex Chinese
@cindex Big5 Chinese character encoding

By default, MySQL searches are not case sensitive (although there are
some character sets that are never case insensitive, such as @code{czech}).
This means that if you search with @code{@var{col_name} LIKE 'a%'}, you will get all
column values that start with @code{A} or @code{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 @code{BINARY} operator. Write the condition as either
@code{BINARY @var{col_name} LIKE 'a%'} or @code{@var{col_name} LIKE BINARY 'a%'}.

If you want a column always to be treated in case-sensitive fashion,
declare it as @code{BINARY}. @xref{CREATE TABLE, , @code{CREATE TABLE}}.

Simple comparison operations (@code{>=, >, =, <, <=}, sorting, and grouping)
are based on each character's ``sort value.'' Characters with the same
sort value (such as @samp{E}, @samp{e}, and @samp{@'e}) are treated as the
same character.

If you are using Chinese data in the so-called @code{big5} encoding, you
want to make all character columns @code{BINARY}. This works because the
sorting order of @code{big5} encoding characters is based on the order of
ASCII codes. As of MySQL 4.1, you can explicitly declare that a column should
use the @code{big5} character set:

@example
CREATE TABLE t (name CHAR(40) CHARACTER SET big5);
@end example


@node Using DATE, Problems with NULL, Case sensitivity, Query Issues
@appendixsubsec Problems Using @code{DATE} Columns

@findex DATE

@cindex DATE columns, problems
@cindex problems, @code{DATE} columns

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

@example
mysql> SELECT * FROM @var{tbl_name} WHERE date >= '2003-05-05';
@end example

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 @code{WHERE}
clause that compares a date to a @code{TIMESTAMP}, @code{DATE}, or
@code{DATETIME} column.  (``Relaxed form'' means that any punctuation character
may be used as the separator between parts. For example, @code{'2004-08-15'}
and @code{'2004#08#15'} are equivalent.) MySQL can also convert a
string containing no separators (such as @code{'20040815'}), provided it
makes sense as a date.

The special date @code{'0000-00-00'} can be stored and retrieved as
@code{'0000-00-00'.} When using a @code{'0000-00-00'} date through
MyODBC, it is automatically converted to @code{NULL} in
MyODBC 2.50.12 and above, because ODBC can't handle this kind of
date.

Because MySQL performs the conversions described above, the following
statements work:

@example
mysql> INSERT INTO @var{tbl_name} (idate) VALUES (19970505);
mysql> INSERT INTO @var{tbl_name} (idate) VALUES ('19970505');
mysql> INSERT INTO @var{tbl_name} (idate) VALUES ('97-05-05');
mysql> INSERT INTO @var{tbl_name} (idate) VALUES ('1997.05.05');
mysql> INSERT INTO @var{tbl_name} (idate) VALUES ('1997 05 05');
mysql> INSERT INTO @var{tbl_name} (idate) VALUES ('0000-00-00');

mysql> SELECT idate FROM @var{tbl_name} WHERE idate >= '1997-05-05';
mysql> SELECT idate FROM @var{tbl_name} WHERE idate >= 19970505;
mysql> SELECT MOD(idate,100) FROM @var{tbl_name} WHERE idate >= 19970505;
mysql> SELECT idate FROM @var{tbl_name} WHERE idate >= '19970505';
@end example

@noindent
However, the following will not work:

@example
mysql> SELECT idate FROM @var{tbl_name} WHERE STRCMP(idate,'20030505')=0;
@end example

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

If you are using the @code{ALLOW_INVALID_DATES} SQL mode, MySQL allows you to
store dates that are given only limited checking: MySQL ensures 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).

If you are not using the @code{NO_ZERO_IN_DATE} SQL mode, the day or month
part can be zero.  This is convenient if you want to store a birthdate
in a @code{DATE} column and you know only part of the date.

If you are not using the @code{NO_ZERO_DATE} SQL mode, MySQL also allows
you to store @code{'0000-00-00'} as a ``dummy date.'' This is in some cases
more convenient than using @code{NULL} values.

If the date cannot be converted to any reasonable value, a @code{0} is
stored in the @code{DATE} column, which will be retrieved as
@code{'0000-00-00'}.  This is both a speed and a 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.

If you want MySQL to check all dates and accept only legal dates
(unless overriden by IGNORE), you should set @code{sql_mode} to
@code{"NO_ZERO_IN_DATE,NO_ZERO_DATE"}.

Date handling in MySQL 5.0.1 and earlier works like MySQL 5.0.2 with the
@code{ALLOW_INVALID_DATES} SQL mode enabled.


@node Problems with NULL, Problems with alias, Using DATE, Query Issues
@appendixsubsec Problems with @code{NULL} Values

@cindex @code{NULL} values, vs. empty values

@tindex NULL

The concept of the @code{NULL} value is a common source of confusion for
newcomers to SQL, who often think that @code{NULL} is the same thing as an
empty string @code{''}.  This is not the case. For example, the following
statements are completely different:

@example
mysql> INSERT INTO my_table (phone) VALUES (NULL);
mysql> INSERT INTO my_table (phone) VALUES ('');
@end example

Both statements insert a value into the @code{phone} column, but the first
inserts a @code{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 @code{NULL} handling, you can use the @code{IS NULL} and
@code{IS NOT NULL} operators and the @code{IFNULL()} function.

In SQL, the @code{NULL} value is never true in comparison to any
other value, even @code{NULL}.  An expression that contains @code{NULL}
always produces a @code{NULL} value unless otherwise indicated in
the documentation for the operators and functions involved in the
expression. All columns in the following example return @code{NULL}:

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

If you want to search for column values that are @code{NULL}, you
cannot use an @code{expr = NULL} test. The following statement returns no
rows, because @code{expr = NULL} is never true for any expression:

@example
mysql> SELECT * FROM my_table WHERE phone = NULL;
@end example

To look for @code{NULL} values, you must use the @code{IS NULL} test.
The following statements show how to find the @code{NULL} phone number and the
empty phone number:

@example
mysql> SELECT * FROM my_table WHERE phone IS NULL;
mysql> SELECT * FROM my_table WHERE phone = '';
@end example

You can add an index on a column that can have @code{NULL}
values if you are using MySQL 3.23.2 or newer and are using the
@code{MyISAM}, @code{InnoDB}, or @code{BDB} storage engine.
As of MySQL 4.0.2, the @code{MEMORY} storage engine also supports @code{NULL}
values in indexes.  Otherwise, you must declare an indexed column @code{NOT
NULL} and you cannot insert @code{NULL} into the column.

@findex LOAD DATA INFILE
When reading data with @code{LOAD DATA INFILE}, empty or missing columns
are updated with @code{''}. If you want a @code{NULL} value in a column,
you should use @code{\N} in the data file. The literal word ``@code{NULL}''
may also be used under some circumstances.
@xref{LOAD DATA, , @code{LOAD DATA}}.

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

When using @code{ORDER BY}, @code{NULL} values are presented first, or
last if you specify @code{DESC} to sort in descending order. Exception:
In MySQL 4.0.2 through 4.0.10, @code{NULL} values sort first
regardless of sort order.

Aggregate (summary) functions such as @code{COUNT()}, @code{MIN()}, and
@code{SUM()} ignore @code{NULL} values. The exception to this is
@code{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-@code{NULL} values in the @code{age}
column:

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

@cindex @code{TIMESTAMP}, and @code{NULL} values
@cindex @code{AUTO_INCREMENT}, and @code{NULL} values
@cindex @code{NULL} values, and @code{TIMESTAMP} columns
@cindex @code{NULL} values, and @code{AUTO_INCREMENT} columns

For some column types, MySQL handles @code{NULL} values specially.  If you
insert @code{NULL} into a @code{TIMESTAMP} column, the
current date and time is inserted.  If you insert @code{NULL} into an
integer column that has the @code{AUTO_INCREMENT} attribute, the next
number in the sequence is inserted.


@node Problems with alias, Non-transactional tables, Problems with NULL, Query Issues
@appendixsubsec Problems with Column Aliases

@tindex alias

You can use an alias to refer to a column in @code{GROUP BY},
@code{ORDER BY}, or @code{HAVING} clauses.  Aliases can also be used
to give columns better names:

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

Standard SQL doesn't allow you to refer to a column alias in a
@code{WHERE} clause.  This is because when the @code{WHERE} code is
executed, the column value may not yet be determined. For example, the
following query is illegal:

@example
SELECT id, COUNT(*) AS cnt FROM @var{tbl_name} WHERE cnt > 0 GROUP BY id;
@end example

The @code{WHERE} statement is executed to determine which rows should
be included in the @code{GROUP BY} part, whereas @code{HAVING} is used to
decide which rows from the result set should be used.


@node Non-transactional tables, Deleting from related tables, Problems with alias, Query Issues
@appendixsubsec Rollback Failure for Non-Transactional Tables

@cindex Non-transactional tables

If you receive the following message when trying to perform a
@code{ROLLBACK}, it means that one or more of the tables you used in the
transaction do not support transactions:

@example
Warning: Some non-transactional changed tables couldn't be rolled back
@end example

These non-transactional tables will not be affected by the @code{ROLLBACK}
statement.

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 @command{mysqld} server (or that was disabled with a
startup option).  If @command{mysqld} doesn't support a storage engine, it will
instead create the table as a @code{MyISAM} table, which is
non-transactional.

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

@example
SHOW TABLE STATUS LIKE '@var{tbl_name}';
SHOW CREATE TABLE @var{tbl_name};
@end example

See @ref{SHOW TABLE STATUS,  , @code{SHOW TABLE STATUS}} and
@ref{SHOW CREATE TABLE,  , @code{SHOW CREATE TABLE}}.

You can check which storage engines your @command{mysqld} server supports by
using this statement:

@example
SHOW ENGINES;
@end example

Before MySQL 4.1.2, @code{SHOW ENGINES} is unavailable. Use the following
statement instead and check the value of the variable that is associated
with the storage engine in which you are interested:

@example
SHOW VARIABLES LIKE 'have_%';
@end example

For example, to determine whether the @code{InnoDB} storage engine is
available, check the value of the @code{have_innodb} variable.

See @ref{SHOW ENGINES,  , @code{SHOW ENGINES}} and
@ref{SHOW VARIABLES,  , @code{SHOW VARIABLES}}.


@node Deleting from related tables, No matching rows, Non-transactional tables, Query Issues
@appendixsubsec Deleting Rows from Related Tables

@cindex deleting, rows
@cindex rows, deleting
@cindex tables, deleting rows

MySQL does not support subqueries prior to Version 4.1, or the use of more
than one table in the @code{DELETE} statement prior to Version 4.0. If your
version of MySQL does not support subqueries or multiple-table @code{DELETE}
statements, you can use the following approach to delete rows from two
related tables:

@enumerate
@item
@code{SELECT} the rows based on some @code{WHERE} condition in the main table.
@item
@code{DELETE} the rows in the main table based on the same condition.
@item
@code{DELETE FROM related_table WHERE related_column IN (selected_rows)}.
@end enumerate

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


@node No matching rows, Problems with float, Deleting from related tables, Query Issues
@appendixsubsec Solving Problems with No Matching Rows

@cindex no matching rows
@cindex rows, matching problems

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:

@enumerate
@item
Test the query with @code{EXPLAIN} to check whether you can find something
that is obviously wrong.
@xref{EXPLAIN, , @code{EXPLAIN}}.

@item
Select only those columns that are used in the @code{WHERE} clause.

@item
Remove one table at a time from the query until it returns some rows.
If the tables are large, it's a good idea to use @code{LIMIT 10} with the query.

@item
Issue a @code{SELECT} for the column that should have matched a row against
the table that was last removed from the query.

@item
If you are comparing @code{FLOAT} or @code{DOUBLE} columns with numbers that
have decimals, you can't use equality (@code{=}) 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
@code{FLOAT} to a @code{DOUBLE} will fix this.
@xref{Problems with float}.

@item
If you still can't figure out what's wrong, create a minimal test that can
be run with @code{mysql test < query.sql} that shows your problems.  You can
create a test file by dumping the tables with @command{mysqldump --quick
db_name @var{tbl_name_1} ... @var{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 @code{SELECT} statement at the end of the file.

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

@example
shell> mysqladmin create test2
shell> mysql test2 < query.sql
@end example

Post the test file using @command{mysqlbug} to the general MySQL mailing list.
@xref{Mailing-list}.
@end enumerate

@node Problems with float,  , No matching rows, Query Issues
@appendixsubsec Problems with Floating-Point Comparisons

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 @code{FLOAT}, @code{DOUBLE}, and @code{DECIMAL} are such.
@code{DECIMAL} columns store values with exact precision because they are
represented as strings, but calculations on @code{DECIMAL} values may be done
using floating-point operations.

The following example demonstrate the problem. It shows that even for the
@code{DECIMAL} column type, calculations that are done using floating-point
operations are subject to floating-point error.

@example
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 |
+------+--------+-------+
@end example

The result is correct. Although the first five records look like they
shouldn't pass the comparison test (the values of @code{a} and @code{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 computer
architecture.

The problem cannot be solved by using @code{ROUND()} or similar functions,
because the result is still a floating-point number:

@example
mysql> SELECT i, ROUND(SUM(d1), 2) AS a, ROUND(SUM(d2), 2) AS b
    -> FROM t1 GROUP BY i HAVING a <> b;
+------+--------+-------+
| i    | a      | b     |
+------+--------+-------+
|    1 |  21.40 | 21.40 |
|    2 |  76.80 | 76.80 |
|    3 |   7.40 |  7.40 |
|    4 |  15.40 | 15.40 |
|    5 |   7.20 |  7.20 |
|    6 | -51.40 |  0.00 |
+------+--------+-------+
@end example

This is what the numbers in column @code{a} look like when displayed with more
decimal places:

@example
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 |
+------+----------------------+-------+
@end example

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.

@strong{Warning:} Never use this method in your applications. It is not
an example of a trustworthy method!

@example
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 |
+------+--------+------+
@end example

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

@example
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)
@end example

Conversely, to get rows where the numbers are the same, the test should
find differences within the tolerance value:

@example
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 |
+------+-------+-------+
@end example

@node Optimizer Issues, Table Definition Issues, Query Issues, Problems
@appendixsec 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 doesn't 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:

@itemize @bullet

@item
Use the @code{EXPLAIN} statement to get information about how MySQL will
process a query. To use it, just add the keyword @code{EXPLAIN} to the
front of your @code{SELECT} statement:

@example
mysql> EXPLAIN SELECT * FROM t1, t2 WHERE t1.i = t2.i;
@end example

@code{EXPLAIN} is discussed in more detail in @ref{EXPLAIN, , @code{EXPLAIN}}.

@item
Use @code{ANALYZE TABLE @var{tbl_name}} to update the key distributions for the
scanned table.  @xref{ANALYZE TABLE,  , @code{ANALYZE TABLE}}.

@item
@findex FORCE INDEX
Use @code{FORCE INDEX} for the scanned table to tell MySQL that table
scans are very expensive compared to using the given index.
@xref{SELECT,  , @code{SELECT}}.

@example
SELECT * FROM t1, t2 FORCE INDEX (index_for_column)
WHERE t1.col_name=t2.col_name;
@end example

@code{USE INDEX} and @code{IGNORE INDEX} may also be useful.

@item
Global and table-level @code{STRAIGHT_JOIN}. @xref{SELECT,  , @code{SELECT}}.

@item
You can tune global or thread-specific system variables.  For example,
Start @command{mysqld} with the @code{--max-seeks-for-key=1000} option or use
@code{SET max_seeks_for_key=1000} to tell the optimizer to assume that no
key scan will cause more than 1,000 key seeks.
See @ref{Server system variables}.

@end itemize


@node Table Definition Issues,  , Optimizer Issues, Problems
@appendixsec Table Definition-Related Issues


@menu
* ALTER TABLE problems::        Problems with @code{ALTER TABLE}
* Change column order::         How to Change the Order of Columns in a Table
* Temporary table problems::    @code{TEMPORARY TABLE} Problems
@end menu

@node ALTER TABLE problems, Change column order, Table Definition Issues, Table Definition Issues
@appendixsubsec Problems with @code{ALTER TABLE}

@tindex ALTER TABLE
@cindex changing, table
@cindex table, changing

@code{ALTER TABLE} changes a table to the current character set.
If you get a duplicate-key error during @code{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
@code{REPAIR TABLE} on the table.

If @code{ALTER TABLE} dies with the following error, the problem may be that
MySQL crashed during an earlier @code{ALTER TABLE} operation and there is an
old table named @file{A-@var{xxx}} or @file{B-@var{xxx}} lying around:

@example
Error on rename of './database/name.frm'
to './database/B-@var{xxx}.frm' (Errcode: 17)
@end example

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

@code{ALTER TABLE} works in the following way:

@itemize @bullet
@item
Create a new table named @file{A-@var{xxx}} with the requested structural changes.
@item
Copy all rows from the original table to @file{A-@var{xxx}}.
@item
Rename the original table to @file{B-@var{xxx}}.
@item
Rename @file{A-@var{xxx}} to your original table name.
@item
Delete @file{B-@var{xxx}}.
@end itemize

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 @file{B-@var{xxx}}. A
simple rename of the table files at the system level should get your data back.

If you use @code{ALTER TABLE} on a transactional table or if you are using
Windows or OS/2, @code{ALTER TABLE} will @code{UNLOCK} the table if you had
done a @code{LOCK TABLE} on it. This is because @code{InnoDB} and these
operating systems cannot drop a table that is in use.


@node Change column order, Temporary table problems, ALTER TABLE problems, Table Definition Issues
@appendixsubsec How to Change the Order of Columns in a Table

@cindex reordering, columns
@cindex columns, changing
@cindex changing, column order
@cindex tables, changing column order

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 @var{col_name1}, @var{col_name2}, @var{col_name3}, whereas
the second returns them in the order @var{col_name1}, @var{col_name3},
@var{col_name2}:

@example
mysql> SELECT @var{col_name1}, @var{col_name2}, @var{col_name3} FROM @var{tbl_name};
mysql> SELECT @var{col_name1}, @var{col_name3}, @var{col_name2} FROM @var{tbl_name};
@end example

If you decide to change the order of table columns anyway, you can do so as
follows:

@enumerate
@item
Create a new table with the columns in the new order. 
@item
Execute this statement:

@example
mysql> INSERT INTO new_table
    -> SELECT columns-in-new-order FROM old_table;
@end example

@item
Drop or rename @code{old_table}.
@item
Rename the new table to the original name:

@example
mysql> ALTER TABLE new_table RENAME old_table;
@end example

@end enumerate

@code{SELECT *} is quite suitable for testing queries. However, in an
application, you should @emph{never} rely on using @code{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 cause
your application to fail.


@node Temporary table problems,  , Change column order, Table Definition Issues
@appendixsubsec @code{TEMPORARY TABLE} Problems

@cindex temporary tables, problems

The following list indicates limitations on the use of @code{TEMPORARY}
tables:

@itemize @bullet
@item
A @code{TEMPORARY} table can only be of type @code{HEAP}, @code{ISAM},
@code{MyISAM}, @code{MERGE}, or @code{InnoDB}.

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

@example
mysql> SELECT * FROM temp_table, temp_table AS t2;
ERROR 1137: Can't reopen table: 'temp_table'
@end example

@item
The @code{SHOW TABLES} statement does not list @code{TEMPORARY} tables.

@item
You cannot use @code{RENAME} to rename a @code{TEMPORARY} table.  However,
you can use @code{ALTER TABLE} instead:

@example
mysql> ALTER TABLE orig_name RENAME new_name;
@end example

@end itemize


@node Credits, TODO, Problems, Top
@appendix Credits

@cindex developers, list of

This appendix lists the developers, contributors, and supporters that have
helped to make MySQL what it is today.

@menu
* Developers::                  Developers at MySQL AB
* Contributors::                Contributors to MySQL
* Documenters/Translators::     Documenters and translators
* Used Libraries::              Libraries used by and included with MySQL
* Packages::                    Packages that support MySQL
* Tools used to create MySQL::  Tools that were used to create MySQL
* Supporters::                  Supporters of MySQL
@end menu


@node Developers, Contributors, Credits, Credits
@appendixsec Developers at MySQL AB

These are the developers that are or have been employed by MySQL AB
to work on the @code{MySQL} database software, roughly in the order they
started to work with us. Following each developer is a small list of the
tasks that the developer is responsible for, or the accomplishments they
have made. All developers are involved in support.

@c Updated by arjen 2002-08-06
@c Note: This is a non-exhaustive list. It just documents some notable
@c achievements, not each individual task. Nor is it a complete list
@c of past/present job roles (see above). That said, updates welcome!

@table @asis
@item Michael (Monty) Widenius
@itemize @bullet
@item
Lead developer and main author of the MySQL server (@command{mysqld}).
@item
New functions for the string library.
@item
Most of the @code{mysys} library.
@item
The @code{ISAM} and @code{MyISAM} libraries (B-tree index file
handlers with index compression and different record formats).
@item
The @code{HEAP} library. A memory table system with our superior full dynamic
hashing. In use since 1981 and published around 1984.
@item
The @command{replace} program (take a look at it, it's @strong{COOL}!).
@item
Connector/ODBC (MyODBC), the ODBC driver for Windows.
@item
Fixing bugs in MIT-pthreads to get it to work for MySQL Server. And
also Unireg, a curses-based application tool with many utilities.
@item
Porting of @code{mSQL} tools like @code{msqlperl}, @code{DBD}/@code{DBI}, and
@code{DB2mysql}.
@item
Most of @code{crash-me} and the foundation for the MySQL benchmarks.
@end itemize

@item David Axmark
@itemize @bullet
@item
Initial main writer of the @strong{Reference Manual},
including enhancements to @command{texi2html}.
@item
Automatic Web site updating from the manual.
@item
Initial Autoconf, Automake, and Libtool support.
@item
Licensing.
@item
Parts of all the text files.  (Nowadays only the @file{README} is
left. The rest ended up in the manual.)
@item
Lots of testing of new features.
@item
Our in-house Free Software legal expert.
@item
Mailing list maintainer (who never has the time to do it right...).
@item
Our original portability code (more than 10 years old now). Nowadays
only some parts of @code{mysys} are left.
@item
Someone for Monty to call in the middle of the night when he just got
that new feature to work.
@item
Chief "Open Sourcerer" (MySQL community relations).
@end itemize

@item Jani Tolonen
@itemize @bullet
@item
@command{mysqlimport}
@item
A lot of extensions to the command-line clients.
@item
@code{PROCEDURE ANALYSE()}
@end itemize

@item Sinisa Milivojevic
@itemize @bullet
@item
Compression (with @code{zlib}) in the client/server protocol.
@item
Perfect hashing for the lexical analyzer phase.
@item
Multi-row @code{INSERT}
@item
@command{mysqldump} -e option
@item
@code{LOAD DATA LOCAL INFILE}
@item
@code{SQL_CALC_FOUND_ROWS} @code{SELECT} option
@item
@code{--max-user-connections=...} option
@item
@code{net_read} and @code{net_write_timeout}
@item
@code{GRANT}/@code{REVOKE} and @code{SHOW GRANTS FOR}
@item
New client/server protocol for 4.0
@item
@code{UNION} in 4.0
@item
Multiple-table @code{DELETE}/@code{UPDATE}
@item
Derived tables in 4.1
@item
User resources management
@item
Initial developer of the @code{MySQL++} C++ API and the @code{MySQLGUI} client.
@end itemize

@item Tonu Samuel (past developer)
@itemize @bullet
@item
VIO interface (the foundation for the encrypted client/server protocol).
@item
MySQL Filesystem (a way to use MySQL databases as files
and directories).
@item
The @code{CASE} expression.
@item
The @code{MD5()} and @code{COALESCE()} functions.
@item
@code{RAID} support for @code{MyISAM} tables.
@end itemize

@item Sasha Pachev
@itemize @bullet
@item
Initial implementation of replication (up to version 4.0).
@item
@code{SHOW CREATE TABLE}.
@item
@code{mysql-bench}
@end itemize

@item Matt Wagner
@itemize @bullet
@item
MySQL test suite.
@item
Webmaster (until 2002).
@item
Coordinator of development.
@end itemize

@item Miguel Solorzano
@itemize @bullet
@item
Win32 development and release builds.
@item
Windows NT server code.
@item
WinMySQLAdmin
@end itemize

@item Timothy Smith (past developer)
@itemize @bullet
@item
Dynamic character sets support.
@item
configure, RPMs and other parts of the build system.
@item
Initial developer of @code{libmysqld}, the embedded server.
@end itemize

@item Sergei Golubchik
@itemize @bullet
@item
Full-text search.
@item
Added keys to the @code{MERGE} library.
@end itemize

@item Jeremy Cole
@itemize @bullet
@item
Proofreading and editing this fine manual.
@item
@code{ALTER TABLE ... ORDER BY ...}.
@item
@code{UPDATE ... ORDER BY ...}.
@item
@code{DELETE ... ORDER BY ...}.
@end itemize

@item Indrek Siitan
@itemize @bullet
@item
Designing/programming of our Web interface.
@item
Author of our newsletter management system.
@end itemize

@item Jorge del Conde
@itemize @bullet
@item
@command{MySQLCC} (@command{MySQL Control Center})
@item
Win32 development
@item
Initial implementation of the Web site portals.
@end itemize

@item Venu Anuganti
@itemize @bullet
@item
MyODBC 3.51
@item
New client/server protocol for 4.1 (for prepared statements).
@end itemize

@item Arjen Lentz
@itemize @bullet
@item
Maintainer of the MySQL Reference Manual.
@item
Preparing the O'Reilly printed edition of the manual.
@end itemize

@item Alexander (Bar) Barkov, Alexey (Holyfoot) Botchkov, and Ramil Kalimullin
@itemize @bullet
@item
Spatial data (GIS) and R-Trees implementation for 4.1
@item
Unicode and character sets for 4.1; documentation for same
@end itemize

@item Oleksandr (Sanja) Byelkin
@itemize @bullet
@item
Query cache in 4.0
@item
Implementation of subqueries (4.1).
@end itemize

@item Aleksey (Walrus) Kishkin and Alexey (Ranger) Stroganov
@itemize @bullet
@item
Benchmarks design and analysis.
@item
Maintenance of the MySQL test suite.
@end itemize

@item Zak Greant
@itemize @bullet
@item
Open Source advocate, MySQL community relations.
@end itemize

@item Carsten Pedersen
@itemize @bullet
@item
The MySQL Certification program.
@end itemize

@item Lenz Grimmer
@itemize @bullet
@item
Production (build and release) engineering.
@end itemize

@item Peter Zaitsev
@itemize @bullet
@item
@code{SHA1()}, @code{AES_ENCRYPT()} and @code{AES_DECRYPT()} functions.
@item
Debugging, cleaning up various features.
@end itemize

@item Alexander (Salle) Keremidarski
@itemize @bullet
@item
Support.
@item
Debugging.
@end itemize

@item Per-Erik Martin
@itemize @bullet
@item
Lead developer for stored procedures (5.0) and triggers.
@end itemize

@item Jim Winstead
@itemize @bullet
@item
Lead Web developer.
@end itemize

@item Mark Matthews
@itemize @bullet
@item
Connector/J driver (Java).
@end itemize

@item Peter Gulutzan
@itemize @bullet
@item
SQL standards compliance.
@item
Documentation of existing MySQL code/algorithms.
@item
Character set documentation.
@end itemize

@item Guilhem Bichot
@itemize @bullet
@item
Replication, from @code{MySQL} version 4.0.
@item
Fixed handling of exponents for @code{DECIMAL}.
@item
Author of @code{mysql_tableinfo}.
@end itemize

@item Antony T. Curtis
@itemize @bullet
@item
Porting of the MySQL Database software to OS/2.
@end itemize

@item Mikael Ronstrom
@itemize @bullet
@item
Much of the initial work on NDB Cluster until 2000. Roughly half the
code base at that time. Transaction protocol, node recovery, system
restart and restart code and parts of the API functionality.
@item
Lead Architect, developer, debugger of NDB Cluster 1994-2004
@item
Lots of optimisations
@end itemize

@item Jonas Oreland 
@itemize @bullet
@item
On-line Backup
@item
The automatic test environment of MySQL Cluster
@item
Portability Library for NDB Cluster
@item
Lots of other things
@end itemize

@item Pekka Nouisiainen
@itemize @bullet
@item
Ordered index implementation of MySQL Cluster
@item
BLOB support in MySQL Cluster
@item
Charset support in MySQL Cluster
@end itemize

@item Martin Skold
@itemize @bullet
@item
Unique index implementation of MySQL Cluster
@item
Integration of NDB Cluster into MySQL
@end itemize

@item Magnus Svensson
@itemize @bullet
@item
The test framework for MySQL Cluster
@item
Integration of NDB Cluster into MySQL
@end itemize

@item Tomas Ulin
@itemize @bullet
@item
Lots of work on configuration changes for simple installation and use of
MySQL Cluster
@end itemize

@end table


@node Contributors, Documenters/Translators, Developers, Credits
@appendixsec Contributors to MySQL

@cindex contributors, list of

While MySQL AB owns all copyrights in the @code{MySQL server}
and the @code{MySQL manual}, we wish to recognize those who have made
contributions of one kind or another to the @code{MySQL distribution}.
Contributors are listed here, in somewhat random order:

@table @asis
@item Gianmassimo Vigazzola @email{qwerg@@mbox.vol.it} or @email{qwerg@@tin.it}
The initial port to Win32/NT.
@item Per Eric Olsson
For more or less constructive criticism and real testing of the dynamic
record format.
@item Irena Pancirov @email{irena@@mail.yacc.it}
Win32 port with Borland compiler.  @code{mysqlshutdown.exe} and
@code{mysqlwatch.exe}
@item David J. Hughes
For the effort to make a shareware SQL database. At TcX, the predecessor
of MySQL AB, we started with @code{mSQL}, but found that it couldn't
satisfy our purposes so instead we wrote an SQL interface to our
application builder Unireg.  @command{mysqladmin} and @command{mysql} client are
programs that were largely influenced by their @code{mSQL} counterparts.
We have put a lot of effort into making the MySQL syntax a superset of
@code{mSQL}. Many of the API's ideas are borrowed from @code{mSQL} to
make it easy to port free @code{mSQL} programs to the MySQL API.
The MySQL software doesn't contain any code from @code{mSQL}.
Two files in the distribution (@file{client/insert_test.c} and
@file{client/select_test.c}) are based on the corresponding (non-copyrighted)
files in the @code{mSQL} distribution, but are modified as examples showing
the changes necessary to convert code from @code{mSQL} to MySQL Server.
(@code{mSQL} is copyrighted David J. Hughes.)
@item Patrick Lynch
For helping us acquire @uref{http://www.mysql.com/}.
@item Fred Lindberg
For setting up qmail to handle the MySQL mailing list and for the
incredible help we got in managing the MySQL mailing lists.
@item Igor Romanenko @email{igor@@frog.kiev.ua}
@command{mysqldump} (previously @code{msqldump}, but ported and enhanced by
Monty).
@item Yuri Dario
For keeping up and extending the MySQL OS/2 port.
@item Tim Bunce
Author of @command{mysqlhotcopy}.
@item Zarko Mocnik @email{zarko.mocnik@@dem.si}
Sorting for Slovenian language.
@item "TAMITO" @email{tommy@@valley.ne.jp}
The @code{_MB} character set macros and the ujis and sjis character sets.
@item Joshua Chamas @email{joshua@@chamas.com}
Base for concurrent insert, extended date syntax, debugging on NT, and
answering on the MySQL mailing list.
@item Yves Carlier @email{Yves.Carlier@@rug.ac.be}
@command{mysqlaccess}, a program to show the access rights for a user.
@item Rhys Jones @email{rhys@@wales.com} (And GWE Technologies Limited)
For one of the early JDBC drivers.
@item Dr Xiaokun Kelvin ZHU @email{X.Zhu@@brad.ac.uk}
Further development of one of the early JDBC drivers and other MySQL-related
Java tools.
@item James Cooper @email{pixel@@organic.com}
For setting up a searchable mailing list archive at his site.
@item Rick Mehalick @email{Rick_Mehalick@@i-o.com}
For @code{xmysql}, a graphical X client for MySQL Server.
@item Doug Sisk @email{sisk@@wix.com}
For providing RPM packages of MySQL for Red Hat Linux.
@item Diemand Alexander V. @email{axeld@@vial.ethz.ch}
For providing RPM packages of MySQL for Red Hat Linux-Alpha.
@item Antoni Pamies Olive @email{toni@@readysoft.es}
For providing RPM versions of a lot of MySQL clients for Intel
and SPARC.
@item Jay Bloodworth @email{jay@@pathways.sde.state.sc.us}
For providing RPM versions for MySQL 3.21.
@item David Sacerdote @email{davids@@secnet.com}
Ideas for secure checking of DNS hostnames.
@item Wei-Jou Chen @email{jou@@nematic.ieo.nctu.edu.tw}
Some support for Chinese(BIG5) characters.
@item  Wei He @email{hewei@@mail.ied.ac.cn}
A lot of functionality for the Chinese(GBK) character set.
@item Jan Pazdziora @email{adelton@@fi.muni.cz}
Czech sorting order.
@item Zeev Suraski @email{bourbon@@netvision.net.il}
@code{FROM_UNIXTIME()} time formatting, @code{ENCRYPT()} functions, and
@command{bison} advisor.
Active mailing list member.
@item Luuk de Boer @email{luuk@@wxs.nl}
Ported (and extended) the benchmark suite to @code{DBI}/@code{DBD}. Have
been of great help with @code{crash-me} and running benchmarks. Some new
date functions. The @command{mysql_setpermission} script.
@item Alexis Mikhailov @email{root@@medinf.chuvashia.su}
User-defined functions (UDFs); @code{CREATE FUNCTION} and
@code{DROP FUNCTION}.
@item Andreas F. Bobak @email{bobak@@relog.ch}
The @code{AGGREGATE} extension to UDF functions.
@item Ross Wakelin @email{R.Wakelin@@march.co.uk}
Help to set up InstallShield for MySQL-Win32.
@item Jethro Wright III @email{jetman@@li.net}
The @file{libmysql.dll} library.
@item James Pereria @email{jpereira@@iafrica.com}
Mysqlmanager, a Win32 GUI tool for administering MySQL Servers.
@item Curt Sampson @email{cjs@@portal.ca}
Porting of MIT-pthreads to NetBSD/Alpha and NetBSD 1.3/i386.
@item Martin Ramsch @email{m.ramsch@@computer.org}
Examples in the MySQL Tutorial.
@item Steve Harvey
For making @command{mysqlaccess} more secure.
@item Konark IA-64 Centre of Persistent Systems Private Limited
@uref{http://www.pspl.co.in/konark/}.  Help with the Win64 port of the
MySQL server.
@item Albert Chin-A-Young.
Configure updates for Tru64, large file support and better TCP wrappers
support.
@item John Birrell
Emulation of @code{pthread_mutex()} for OS/2.
@item Benjamin Pflugmann
Extended @code{MERGE} tables to handle @code{INSERTS}. Active member
on the MySQL mailing lists.
@item Jocelyn Fournier
Excellent spotting and reporting innumerable bugs
(especially in the MySQL 4.1 subquery code).
@item Marc Liyanage
Maintaining the Mac OS X packages and providing invaluable feedback
on how to create Mac OS X PKGs.
@item Robert Rutherford
Providing invaluable information and feedback about the QNX port.
@item Previous developers of NDB Cluster
Lots of people were involved in various ways summer students, master thesis
students, employees. In total more than 100 people so too many to mention here.
Notable name is Ataullah Dabaghi who up until 1999 contributed around a
third of the code base. A special thanks also to developers of the AXE system
which provided much of the architecturial foundations for NDB Cluster with
blocks, signals and crash tracing functionality. Also credit should be given
to those who believed in the ideas enough to allocate of their budgets for its
development from 1992 to present time.
@end table

Other contributors, bugfinders, and testers: James H. Thompson, Maurizio
Menghini, Wojciech Tryc, Luca Berra, Zarko Mocnik, Wim Bonis, Elmar
Haneke, @email{jehamby@@lightside}, @email{psmith@@BayNetworks.com},
@email{duane@@connect.com.au}, Ted Deppner @email{ted@@psyber.com},
Mike Simons, Jaakko Hyvatti.

And lots of bug report/patches from the folks on the mailing list.

A big tribute goes to those that help us answer questions on the
MySQL mailing lists:

@table @asis
@item Daniel Koch @email{dkoch@@amcity.com}
Irix setup.
@item Luuk de Boer @email{luuk@@wxs.nl}
Benchmark questions.
@item Tim Sailer @email{tps@@users.buoy.com}
@code{DBD::mysql} questions.
@item Boyd Lynn Gerber @email{gerberb@@zenez.com}
SCO-related questions.
@item Richard Mehalick @email{RM186061@@shellus.com}
@code{xmysql}-related questions and basic installation questions.
@item Zeev Suraski @email{bourbon@@netvision.net.il}
Apache module configuration questions (log & auth), PHP-related
questions, SQL syntax-related questions and other general questions.
@item Francesc Guasch @email{frankie@@citel.upc.es}
General questions.
@item Jonathan J Smith @email{jsmith@@wtp.net}
Questions pertaining to OS-specifics with Linux, SQL syntax, and other
things that might need some work.
@item David Sklar @email{sklar@@student.net}
Using MySQL from PHP and Perl.
@item Alistair MacDonald @email{A.MacDonald@@uel.ac.uk}
Not yet specified, but is flexible and can handle Linux and maybe HP-UX.
Will try to get user to use @command{mysqlbug}.
@item John Lyon @email{jlyon@@imag.net}
Questions about installing MySQL on Linux systems, using either
@file{.rpm} files or compiling from source.
@item Lorvid Ltd. @email{lorvid@@WOLFENET.com}
Simple billing/license/support/copyright issues.
@item Patrick Sherrill @email{patrick@@coconet.com}
ODBC and VisualC++ interface questions.
@item Randy Harmon @email{rjharmon@@uptimecomputers.com}
@code{DBD}, Linux, some SQL syntax questions.
@end table

@node Documenters/Translators, Used Libraries, Contributors, Credits
@appendixsec Documenters and translators

@cindex Documenters, list of
@cindex Translators, list of

The following people has helped us with writing the MySQL documentation and
translating the documentation or error messages in MySQL.

@table @asis
@item Paul DuBois
Ongoing help with making this manual correct and understandable.
That includes rewriting Monty's and David's attempts at English into
English as other people know it.
@item Kim Aldale
Helped to rewrite Monty's and David's early attempts at English into English.
@item Michael J. Miller Jr. @email{mke@@terrapin.turbolift.com}
For the first MySQL manual. And a lot of spelling/language
fixes for the FAQ (that turned into the MySQL manual a long
time ago).
@item Yan Cailin
First translator of the MySQL Reference Manual into simplified
Chinese in early 2000 on which the Big5 and HK coded
(@uref{http://mysql.hitstar.com/}) versions were
based. @uref{http://linuxdb.yeah.net, Personal home page at
linuxdb.yeah.net}.
@item Jay Flaherty @email{fty@@mediapulse.com}
Big parts of the Perl @code{DBI}/@code{DBD} section in the manual.
@item Paul Southworth @email{pauls@@etext.org}, Ray Loyzaga @email{yar@@cs.su.oz.au}
Proof-reading of the Reference Manual.
@item Therrien Gilbert @email{gilbert@@ican.net}, Jean-Marc Pouyot @email{jmp@@scalaire.fr}
French error messages.
@item Petr Snajdr, @email{snajdr@@pvt.net}
Czech error messages.
@item Jaroslaw Lewandowski @email{jotel@@itnet.com.pl}
Polish error messages.
@item Miguel Angel Fernandez Roiz
Spanish error messages.
@item Roy-Magne Mo @email{rmo@@www.hivolda.no}
Norwegian error messages and testing of MySQL 3.21.xx.
@item Timur I. Bakeyev @email{root@@timur.tatarstan.ru}
Russian error messages.
@item @email{brenno@@dewinter.com} & Filippo Grassilli @email{phil@@hyppo.com}
Italian error messages.
@item Dirk Munzinger @email{dirk@@trinity.saar.de}
German error messages.
@item Billik Stefan @email{billik@@sun.uniag.sk}
Slovak error messages.
@item Stefan Saroiu @email{tzoompy@@cs.washington.edu}
Romanian error messages.
@item Peter Feher
Hungarian error messages.
@item Roberto M. Serqueira
Portuguese error messages.
@item Carsten H. Pedersen
Danish error messages.
@item Arjen G. Lentz
Dutch error messages, completing earlier partial translation
(also work on consistency and spelling).
@end table

@node Used Libraries, Packages, Documenters/Translators, Credits
@appendixsec Libraries used by and included with MySQL

@cindex libraries, list of

The following is a list of the creators of the libraries we have
included with the MySQL server source to make it easy to compile and
install MySQL. We are very thankfully to all individuals that have
created these and it has made our life much easier.

@table @asis
@item Fred Fish
For his excellent C debugging and trace library. Monty has made a number
of smaller improvements to the library (speed and additional options).
@item Richard A. O'Keefe
For his public domain string library.
@item Henry Spencer
For his regex library, used in @code{WHERE column REGEXP regexp}.
@item Chris Provenzano
Portable user level pthreads. From the copyright: This product includes
software developed by Chris Provenzano, the University of California,
Berkeley, and contributors.  We are currently using version 1_60_beta6
patched by Monty (see @file{mit-pthreads/Changes-mysql}).
@item Jean-loup Gailly and Mark Adler
For the zlib library (used on MySQL on Windows).
@item Bjorn Benson
For his safe_malloc (memory checker) package which is used in when you
configure MySQL with @code{--debug}.
@item Free Software Foundation
The @code{readline} library (used by the @command{mysql} command-line client).
@item The NetBSD foundation
The @code{libedit} package (optionally used by the @command{mysql} command-line
client).
@end table

@node Packages, Tools used to create MySQL, Used Libraries, Credits
@appendixsec Packages that support MySQL

@cindex packages, list of
@cindex API's, list of

The following is a list of creators/maintainers of some of the most
important API/packages/applications that a lot of people use with MySQL.

We can't list every possible package here because the list would then be
way to hard to maintain. For other packages, please refer to the
software portal at @uref{http://solutions.mysql.com/software/}.

@table @asis
@item Tim Bunce, Alligator Descartes
For the @code{DBD} (Perl) interface.
@item Andreas Koenig @email{a.koenig@@mind.de}
For the Perl interface for MySQL Server.
@item Jochen Wiedmann @email{wiedmann@@neckar-alb.de}
For maintaining the Perl @code{DBD::mysql} module.
@item Eugene Chan @email{eugene@@acenet.com.sg}
For porting PHP for MySQL Server.
@item Georg Richter
MySQL 4.1 testing and bug hunting.
New PHP 5.0 @code{mysqli} extension (API) for use with MySQL 4.1 and up.
@item Giovanni Maruzzelli @email{maruzz@@matrice.it}
For porting iODBC (Unix ODBC).
@item Xavier Leroy @email{Xavier.Leroy@@inria.fr}
The author of LinuxThreads (used by the MySQL Server on Linux).
@end table

@node Tools used to create MySQL, Supporters, Packages, Credits
@appendixsec Tools that were used to create MySQL

@cindex tools, list of

The following is a list of some of the tools we have used to create MySQL.
We use this to express our thanks to those that has created them as without
these we could not have made MySQL what is is today.

@table @asis
@item Free Software Foundation
From whom we got an excellent compiler (@command{gcc}), an excellent
debugger (@command{gdb} and the @code{libc} library (from which we have
borrowed @file{strto.c} to get some code working in Linux).
@item Free Software Foundation & The XEmacs development team
For a really great editor/environment used by almost everybody at
MySQL AB.
@item Julian Seward
Author of @code{valgrind}, an excellent memory checker tool that has helped
us find a lot of otherwise hard to find bugs in MySQL.
@item Dorothea L@"utkehaus and Andreas Zeller
For @code{DDD} (The Data Display Debugger) which is an excellent
graphical frontend to @command{gdb}).
@end table

@node Supporters,  , Tools used to create MySQL, Credits
@appendixsec Supporters of MySQL

@cindex contributing companies, list of

While MySQL AB owns all copyrights in the @code{MySQL server}
and the @code{MySQL manual}, we wish to recognize the following companies,
which helped us finance the development of the @code{MySQL server},
such as by paying us for developing a new feature or giving us hardware
for development of the @code{MySQL server}.

@table @asis
@item VA Linux / Andover.net
Funded replication.
@item NuSphere
Editing of the MySQL manual.
@item Stork Design studio
The MySQL Web site in use between 1998-2000.
@item Intel
Contributed to development on Windows and Linux platforms.
@item Compaq
Contributed to Development on Linux/Alpha.
@item SWSoft
Development on the embedded @command{mysqld} version.
@item FutureQuest
@code{--skip-show-database}
@end table

@node TODO, News, Credits, Top
@appendix MySQL and the Future (the TODO)

@cindex ToDo list for MySQL

@menu
* TODO MySQL 5.0::              New Features Planned for 5.0
* TODO MySQL 5.1::              New Features Planned for 5.1
* TODO future::                 New Features Planned for the Near Future
* TODO sometime::               New Features Planned for the Mid-Term Future
* TODO unplanned::              New Features We Don't Plan to Implement
@end menu

This section summarizes the features that we plan to implement in
MySQL Server. The items are ordered by release series. Within a list,
items are shown in approximately the order they will be done.

@strong{Note}: If you are an enterprise-level user with an urgent need
for a particular feature, please contact @email{sales@@mysql.com} to
discuss sponsoring options. Targeted financing by sponsor companies
allows us to allocate additional resources for specific purposes.
One example of a feature sponsored in the past is replication.


@node TODO MySQL 5.0, TODO MySQL 5.1, TODO, TODO
@appendixsec New Features Planned for 5.0

The following features are planned for inclusion into MySQL 5.0.
Some of the features such as stored procedures are complete and are
included in MySQL 5.0 alpha, which is available now.  Others such
as cursors are only partially available. Expect these and other
features to mature and be fully supported in upcoming releases.

Note that because we have many developers that are working on different
projects, there will also be many additional features. There is also a
small chance that some of these features will be added to MySQL 4.1.
For a list what is already done in MySQL 4.1, see @ref{Nutshell 4.1 features}.

For those wishing to take a look at the bleeding edge of MySQL
development, we make our BitKeeper repository for
MySQL version 5.0 publicly available.
@xref{Installing source tree}.
As of December 2003, binary builds of version 5.0 are also available.

@table @asis

@item Views
@itemize @bullet
@item
Views, implemented in stepwise fashion up to full functionality.
@xref{ANSI diff Views}. @xref{CREATE VIEW,  , @code{CREATE VIEW}}.
@end itemize

@item Stored Procedures
@itemize @bullet
@item
Stored procedures currently are implemented, based on the SQL:2003
standard.
@xref{Stored Procedures}.

@c Commented this out -- it's unclear whether this will happen or how much.

@c We will also implement a framework to hook in external languages,
@c and (where possible) compatibility with, for example, PL/SQL and T-SQL.
@end itemize

@item New functionality
@itemize @bullet
@item
Elementary cursor support.
@xref{Cursors}.
@item
The ability to specify explicitly for @code{MyISAM} tables that an index
should be created as an @code{RTREE} index.  (In MySQL 4.1, @code{RTREE} indexes
are used internally for geometrical data that use GIS data types, but cannot be
created on request.)
@item
Dynamic length rows for @code{MEMORY} tables.
@end itemize

@item Standards compliance, portability and migration
@itemize @bullet
@item
Support for Data Dictionary / @code{INFORMATION_SCHEMA}.
@item
Add true @code{VARCHAR} support (column lengths longer than 255, and
no stripping of trailing whitespace).
There is already support for this in the @code{MyISAM} storage engine,
but it is not yet available at the user level.
@end itemize

@item Speed enhancements
@itemize @bullet
@item
@code{SHOW COLUMNS FROM @var{tbl_name}} (used by the @command{mysql} client to allow
expansions of column names) should not open the table, only the
definition file. This will require less memory and be much faster.
@item
Allow @code{DELETE} on @code{MyISAM} tables to use the record cache.
To do this, we need to update the threads record cache when we update
the @file{.MYD} file.
@item
Better support for @code{MEMORY} tables:
@itemize @bullet
@item
Dynamic length rows.
@item
Faster row handling (less copying).
@end itemize
@end itemize

@item Usability enhancements
@itemize @bullet
@item
Resolving the issue of @code{RENAME TABLE} on a table used in an active
@code{MERGE} table possibly corrupting the table.
@end itemize

@end table

The news section of this manual includes a more in-depth list of features.
@xref{News-5.0.x}.


@node TODO MySQL 5.1, TODO future, TODO MySQL 5.0, TODO
@appendixsec New Features Planned for 5.1

@table @asis
@item New functionality
@itemize @bullet
@item
@code{FOREIGN KEY} support for all table types, not just @code{InnoDB}.
@item
Column-level constraints.
@xref{Constraints}.
@c Commented out, it's not actually on the list
@c @item
@c Fail-safe replication.
@item
Online backup with very low performance penalty.  The online backup will
make it easy to add a new replication slave without taking down the
master.
@end itemize

@c @item Standards compliance, portability and migration
@c @itemize @bullet
@c @end itemize

@item Speed enhancements
@itemize @bullet
@item
New text based table definition file format (@file{.frm} files) and a
table cache for table definitions.  This will enable us to do faster
queries of table structures and do more efficient foreign key support.
@item
Optimize the @code{BIT} type to take one bit. (@code{BIT} now takes one byte;
it is treated as a synonym for @code{TINYINT}.)
@end itemize

@c @item Internationalzsation
@c @itemize @bullet
@c @end itemize

@item Usability enhancements
@itemize @bullet
@item
Add options to the client/server protocol to get progress notes
for long running commands.
@item
Implement @code{RENAME DATABASE}. To make this safe for all storage engines,
it should work as follows:
@enumerate
@item
Create the new database.
@item
For every table, do a rename of the table to another database, as
we do with the @code{RENAME} command.
@item
Drop the old database.
@end enumerate
@item
New internal file interface change.  This will make all file handling much
more general and make it easier to add extensions like RAID.
@end itemize

@end table


@node TODO future, TODO sometime, TODO MySQL 5.1, TODO
@appendixsec New Features Planned for the Near Future

@table @asis
@item New functionality
@itemize @bullet
@item
Oracle-like @code{CONNECT BY PRIOR} to search tree-like (hierarchical)
structures.
@item
Add all missing standard SQL and ODBC 3.0 types.
@item
Add @code{SUM(DISTINCT)}.
@item
@code{INSERT SQL_CONCURRENT} and @command{mysqld --concurrent-insert} to do
a concurrent insert at the end of a table if the table is read-locked.
@item
Allow variables to be updated in @code{UPDATE} statements. For example:
@code{UPDATE foo SET @@a:=a+b,a=@@a, b=@@a+c}.
@item
Change when user variables are updated so that you can use them with
@code{GROUP BY}, as in the following statement:
@code{SELECT id, @@a:=COUNT(*), SUM(@var{sum_col})/@@a FROM @var{tbl_name} GROUP BY id}.
@item
Add an @code{IMAGE} option to @code{LOAD DATA INFILE} to not update
@code{TIMESTAMP} and @code{AUTO_INCREMENT} columns.
@item
Add @code{LOAD DATA INFILE ... UPDATE} syntax that works like this:
@itemize @bullet
@item
For tables with primary keys, if an input record contains a primary key
value, existing rows matching that primary key value are updated from the
remainder of the input columns. However, columns corresponding to columns
that are @emph{missing} from the input record are not touched.
@item
For tables with primary keys, if an input record does not contain the primary
key value or is missing some part of the key, the record is treated as
@code{LOAD DATA INFILE ... REPLACE INTO}.
@end itemize
@item
Make @code{LOAD DATA INFILE} understand syntax like this:
@example
LOAD DATA INFILE '@var{file_name}.txt' INTO TABLE @var{tbl_name}
     TEXT_FIELDS (text_col1, text_col2, text_col3)
     SET table_col1=CONCAT(text_col1, text_col2),
         table_col3=23
     IGNORE text_col3
@end example
This can be used to skip over extra columns in the text file,
or update columns based on expressions of the read data.
@item
New functions for working with @code{SET} type columns:
@itemize @bullet
@item @code{ADD_TO_SET(@var{value},@var{set})}
@item @code{REMOVE_FROM_SET(@var{value},@var{set})}
@end itemize
@item
If you abort @command{mysql} in the middle of a query, you should open
another connection and kill the old running query.
Alternatively, an attempt should be made to detect this in the server.
@item
Add a storage engine interface for table information so that you can use it as a system
table. This would be a bit slow if you requested information about all tables,
but very flexible.  @code{SHOW INFO FROM @var{tbl_name}} for basic table information
should be implemented.
@item
Allow @code{SELECT a FROM @var{tbl_name1} LEFT JOIN @var{tbl_name2} USING (a)}; in this
case @code{a} is assumed to come from @var{tbl_name1}.
@item
@code{DELETE} and @code{REPLACE} options to the @code{UPDATE} statement
(this will delete rows when a duplicate-key error occurs while updating).
@item
Change the format of @code{DATETIME} to store fractions of seconds.
@item
Make it possible to use the new GNU @code{regexp} library instead of the current
one (the new library should be much faster than the current one).
@end itemize

@item Standards compliance, portability and migration
@itemize @bullet
@item
Add @code{ANY()}, @code{EVERY()}, and @code{SOME()} group functions. In
standard SQL, these work only on boolean columns, but we can extend these to
work on any columns or expressions by treating a value of zero as FALSE and
non-zero values as TRUE.
@item
Fix the type of @code{MAX(column)} to be the same as the column type:
@example
mysql> CREATE TABLE t1 (a DATE);
mysql> INSERT INTO t1 VALUES (NOW());
mysql> CREATE TABLE t2 SELECT MAX(a) FROM t1;
mysql> SHOW COLUMNS FROM t2;
@end example
@end itemize

@item Speed enhancements
@itemize @bullet
@item
Don't allow more than a defined number of threads to run @code{MyISAM}
recovery at the same time.
@item
Change @code{INSERT INTO ... SELECT} to optionally use concurrent inserts.
@item
Add an option to periodically flush key pages for tables with delayed
keys if they haven't been used in a while.
@item
Allow join on key parts (optimization issue).
@item
Add a log file analyzer that can extract information about which tables
are hit most often, how often multiple-table joins are executed, and so on. This
should help users identify areas of table design that could be optimized
to execute much more efficient queries.
@end itemize

@c Internationalization has no items, so it's commented out. Remove
@c the comment markers if anything is added here.

@c @item Internationalization
@c @itemize @bullet
@c @end itemize

@item Usability enhancements
@itemize @bullet
@item
Return the original column types when doing
@code{SELECT MIN(column) ... GROUP BY}.
@item
Make it possible to specify @code{long_query_time} with a granularity
in microseconds.
@item
Link the @command{myisampack} code into the server so that it can perform
@code{PACK} or @code{COMPRESS} operations.
@item
Add a temporary key buffer cache during @code{INSERT/DELETE/UPDATE} so that we
can gracefully recover if the index file gets full.
@item
If you perform an @code{ALTER TABLE} on a table that is symlinked to another
disk, create temporary tables on that disk.
@item
Implement a @code{DATE/DATETIME} type that handles time zone information
properly, to make dealing with dates in different time zones easier.
@item
Fix @command{configure} so that all libraries (like @code{MyISAM})
can be compiled without threads.
@item
Allow user variables as @code{LIMIT} arguments; for example,
@code{LIMIT @@a,@@b}.
@item
Automatic output from @command{mysql} to a Web browser.
@item
@code{LOCK DATABASES} (with various options).
@item
Many more variables for @code{SHOW STATUS}.  Record reads and
updates.  Selects on a single table and selects with joins.  Mean number of
tables in selects. Number of @code{ORDER BY} and @code{GROUP BY} queries.
@item
@command{mysqladmin copy database new-database}; this requires a @code{COPY}
operation to be added to @command{mysqld}.
@item
Processlist output should indicate the number of queries/threads.
@item
@code{SHOW HOSTS} for printing information about the hostname cache.
@item
Change table names from empty strings to @code{NULL} for calculated columns.
@item
Don't use @code{Item_copy_string} on numerical values to avoid
number-to-string-to-number conversion in case of
@code{SELECT COUNT(*)*(id+0) FROM @var{tbl_name} GROUP BY id}.
@item
Change so that @code{ALTER TABLE} doesn't abort clients
that execute @code{INSERT DELAYED}.
@item
Fix so that when columns are referenced in an @code{UPDATE} clause,
they contain the old values from before the update started.
@end itemize

@item New operating systems
@itemize @bullet
@item
Port the MySQL clients to LynxOS.
@end itemize

@end table


@node TODO sometime, TODO unplanned, TODO future, TODO
@appendixsec New Features Planned for the Mid-Term Future

@itemize @bullet
@item
Implement function: @code{get_changed_tables(timeout,table1,table2,...)}.
@item
Change reading through tables to use @code{mmap()} when possible. Now only
compressed tables use @code{mmap()}.
@item
Make the automatic timestamp code nicer.  Add timestamps to the update
log with @code{SET TIMESTAMP=val;}.
@item
Use read/write mutex in some places to get more speed.
@item
Automatically close some tables if a table, temporary table, or temporary file
gets error 23 (too many open files).
@item
Better constant propagation. When an occurrence of @var{col_name=n}
is found in an expression, for some constant @code{n}, replace other
occurrences of @var{col_name} within the expression with @code{n}.
Currently, this is done only for some simple cases.
@item
Change all const expressions with calculated expressions if possible.
@item
Optimize @var{key} = @var{expr} comparisons. At the moment, only
@var{key} = @var{column} or @var{key} = @var{constant} comparisons are
optimized.
@item
Join some of the copy functions for nicer code.
@item
Change @file{sql_yacc.yy} to an inline parser to reduce its size and get
better error messages.
@item
Change the parser to use only one rule per different number of arguments
in function.
@item
Use of full calculation names in the order part (for Access97).
@item
@code{MINUS}, @code{INTERSECT}, and @code{FULL OUTER JOIN}.
(Currently @code{UNION} and @code{LEFT|RIGHT OUTER JOIN} are supported.)
@item
Allow @code{SQL_OPTION MAX_SELECT_TIME=val}, for placing a time limit on a query.
@item
Allow updates to be logged to a database.
@item
Enhance @code{LIMIT} to allow retrieval of data from the end of a result set.
@item
Alarm around client connect/read/write functions.
@item
Please note the changes to @command{mysqld_safe}: According to FSSTND (which
Debian tries to follow), PID files should go into @file{/var/run/<progname>.pid}
and log files into @file{/var/log}. It would be nice if you could put the
"DATADIR" in the first declaration of "pidfile" and "log" so that the
placement of these files can be changed with a single statement.
@item
Allow a client to request logging.
@item
Allow the @code{LOAD DATA INFILE} statement
to read files that have been compressed with @command{gzip}.
@item
Fix sorting and grouping of @code{BLOB} columns (partly solved now).
@item
Change to use semaphores when counting threads.  One should first implement
a semaphore library for MIT-pthreads.
@item
Add full support for @code{JOIN} with parentheses.
@item
As an alternative to the one-thread-per-connection model, manage a pool
of threads to handle queries.
@item
Allow @code{GET_LOCK()} to obtain more than one lock.  When doing this, it is
also necessary to handle the possible deadlocks this change will introduce.
@end itemize


@node TODO unplanned,  , TODO sometime, TODO
@appendixsec New Features We Don't Plan to Implement

We aim toward full compliance with ANSI/ISO SQL. There are no features
we plan not to implement.

@node News, Porting, TODO, Top
@appendix MySQL Change History

@cindex ChangeLog
@cindex changes, log
@cindex log, changes

This appendix lists the changes from version to version in the MySQL
source code.

We are now working actively on MySQL 4.1 and 5.0, and will provide
only critical bugfixes for MySQL 4.0 and MySQL 3.23.  We update this section
as we add new features, so that everybody can follow the development.

Our TODO section contains what further plans we have for MySQL 4.1 and 5.0.
@xref{TODO}.

Note that we tend to update the manual at the same time we make changes to
MySQL.  If you find a recent version of MySQL listed here that you can't
find on our download page (@uref{http://dev.mysql.com/downloads/}),
it means that the version has not yet been released.

The date mentioned with a release version is the date of the last BitKeeper
ChangeSet on which the release was based, not the date when
the packages were made available. The binaries are usually made
available a few days after the date of the tagged ChangeSet, because building
and testing all packages takes some time.

@c Please don't add a new highest-numbered version here without also
@c updating Docs/include.texi!

@menu
* News-5.0.x::                  Changes in release 5.0.x (Development)
* News-4.1.x::                  Changes in release 4.1.x (Production)
* News-4.0.x::                  Changes in release 4.0.x (Production)
* News-3.23.x::                 Changes in release 3.23.x (Recent; still supported)
* News-3.22.x::                 Changes in release 3.22.x (Old; discontinued)
* News-3.21.x::                 Changes in release 3.21.x
* News-3.20.x::                 Changes in release 3.20.x
* News-3.19.x::                 Changes in release 3.19.x
* InnoDB change history::       @code{InnoDB} Change History
* MySQL Cluster change history::  @code{MySQL Cluster} Change History
@end menu


@node News-5.0.x, News-4.1.x, News, News
@appendixsec Changes in release 5.0.x (Development)

@cindex changes, version 5.0

The following changelog shows what has already been done in the 5.0 tree:

@itemize @bullet
@item
Basic support for read-only server side cursors.
@item
Basic support for (updatable) views.
See, for example, @ref{CREATE VIEW,  , @code{CREATE VIEW}}.
@item
Basic support for stored procedures (SQL:2003 style).
@xref{Stored Procedures}.
@item
Initial support for rudimentary triggers.
@item
Added @code{SELECT INTO @var{list_of_vars}}, which can be of mixed
(that is, global and local) types.
@xref{SELECT INTO Statement,  , @code{SELECT INTO} Statement}.
@item
Removed the update log. It is fully replaced by the binary log.
If the MySQL server is started with @code{--log-update}, it will be
translated to @code{--log-bin} (or ignored if the server is explicitly
started with @code{--log-bin}), and a warning message will be written to
the error log. Setting @code{SQL_LOG_UPDATE} will silently set
@code{SQL_LOG_BIN} instead (or do nothing if the server is explicitly
started with @code{--log-bin}).
@item
User variable names are now case insensitive: If you do @code{SET
@@a=10;} then @code{SELECT @@A;} will now return @code{10}.
Case sensitivity of a variable's value depends on the collation of the value.
@item
Strict mode, which in essence means that you will get an error instead
of a warning when inserting an incorrect value into a column.
@xref{Server SQL mode}.
@item
@code{VARCHAR} fields now remembers end space. A @code{VARCHAR()} field can
now contain up to 65535 bytes.
@item
When using a constant string or a function that generate a string result
in @code{CREATE ... SELECT}, MySQL now creates the result field based
on the max_length of the string/expression:

@multitable @columnfractions .35 .65
@item @strong{max_length} @tab @strong{Column type}
@item = 0 @tab @code{CHAR(0)}
@item < 512 @tab @code{VARCHAR(max_length)}
@item >= 512 @tab @code{TEXT}
@end multitable
@end itemize

For a full list of changes, please refer to the changelog sections for
each individual 5.0.x release.

@menu
* News-5.0.3::                  Changes in release 5.0.3 (not released yet)
* News-5.0.2::                  Changes in release 5.0.2 (01 Dec 2004)
* News-5.0.1::                  Changes in release 5.0.1 (27 Jul 2004)
* News-5.0.0::                  Changes in release 5.0.0 (22 Dec 2003: Alpha)
@end menu

@node News-5.0.3, News-5.0.2, News-5.0.x, News-5.0.x
@appendixsubsec Changes in release 5.0.3 (not released yet)

@c NOTE: References to bug numbers should be written after the sentence
@c NOTE: describing the bugfix, like this:
@c NOTE: This sentence describes the fix. (Bug #nnnn)

Functionality added or changed:
@itemize @bullet
@item
API change: the @code{reconnect} flag in the @code{MYSQL} structure is now set
to 0 by @code{mysql_real_connect()}. Only those client programs which didn't
explicitely set this flag to 0 or 1 after @code{mysql_real_connect()} will
experience a change. Having automatic reconnection enabled by default was
considered too dangerous (after reconnection, table locks, temporary tables,
user and session variables are lost).
@item
@code{FLUSH TABLES WITH READ LOCK} is now killable while it's waiting for
running @code{COMMIT}s to finish.
@item InnoDB: Setting the initial @code{AUTO_INCREMENT} value for the table
using @code{CREATE TABLE...AUTO_INCREMENT = } works now also for the @code{InnoDB}
table.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Prevent adding @code{CREATE TABLE .. SELECT} query to the binary log when the
insertion of new records partially failed. (Bug #6682)
@item
Fixed a bug which caused a crash when only the slave I/O thread was
stopped and started. (Bug #6148)
@item
Giving @command{mysqld} a @code{SIGHUP} caused it to crash.
@item
Changed semantics of @code{CREATE/ALTER/DROP DATABASE} statements so
that replication of @code{CREATE DATABASE} is possible when using
@code{--binlog-do-db} and @code{--binlog-ignore-db}. (Bug #6391)
@item
A sequence of @code{BEGIN} (or @code{SET AUTOCOMMIT=0}), @code{FLUSH TABLES
WITH READ LOCK}, transactional update, @code{COMMIT}, @code{FLUSH
TABLES WITH READ LOCK} could hang the connection forever and possibly the MySQL
server itself. This happened for example when running the @code{innobackup}
script several times. (Bug #6732)
@item
@command{mysqlbinlog} did not print @code{SET PSEUDO_THREAD_ID} statements in
front of @code{LOAD DATA INFILE} statements inserting into temporary tables,
thus causing potential problems when rolling forward these statements after
restoring a backup. (Bug #6671)
@item
InnoDB: Fixed a bug no error message for ALTER with InnoDB and AUTO_INCREMENT
(Bug #7061). @code{InnoDB} now supports @code{ALTER
TABLE...AUTO_INCREMENT = x} query to set auto increment value for a
table. 

@end itemize

@node News-5.0.2, News-5.0.1, News-5.0.3, News-5.0.x
@appendixsubsec Changes in release 5.0.2 (01 Dec 2004)

Functionality added or changed:
@itemize @bullet
@code{VARCHAR} fields now remembers end space. A @code{VARCHAR()} field can
now contain up to 65535 bytes. For more details see @ref{News-5.0.x}.
@item
@strong{Warning: Incompatible change!}
The precedence of @code{NOT} operator has changed so that expressions such as
@code{NOT a BETWEEN b AND c} are parsed correctly as
@code{NOT (a BETWEEN b AND c)} rather than as
@code{(NOT a) BETWEEN b AND c}.
The pre-5.0 higher-precedence behavior can be obtained by enabling the new
@code{HIGH_NOT_PRECEDENCE} SQL mode.
@item
Added @code{IS [NOT] @var{boolean_value}} syntax, where @var{boolean_value} is
@code{TRUE}, @code{FALSE}, or @code{UNKNOWN}.
@item
Added several @code{InnoDB} status variables.
@xref{Server status variables}.
@item
Implemented the @code{WITH CHECK OPTION} clause for @code{CREATE VIEW}.
@item
The @code{SCHEMA} and @code{SCHEMAS} keywords are now accepted as synonyms
for @code{DATABASE} and @code{DATABASES}.
@item
Added initial support for rudimentary triggers (the @code{CREATE TRIGGER} and
@code{DROP TRIGGER} statements).
@item
Added basic support for read-only server side cursors.
@item
@command{mysqldump --single-transaction --master-data} is now able to take an
online (non-blocking) dump of InnoDB and report the corresponding binary log
coordinates, which makes a backup suitable for point-in-time recovery,
roll-forward or replication slave creation. See @ref{mysqldump, ,
@command{mysqldump}}.
@item
Added @code{--start-datetime}, @code{--stop-datetime},
@code{--start-position}, @code{--stop-position} options to
@command{mysqlbinlog} (makes point-in-time recovery easier).
@item
Made the MySQL server not react to signals @code{SIGHUP} and @code{SIGQUIT} on
Mac OS X 10.3. This is needed because under this OS, the MySQL server receives
lots of these signals (reported as Bug #2030).
@item
New @code{--auto-increment-increment} and @code{--auto-increment-offset}
startup options. These allow you to set up a server to generate
auto-increment values that don't conflict with another server.
@item
MySQL now by default will check dates and only allow fully correct
dates. If you want to MySQL to behave as default, you should enable the
new @code{ALLOW_INVALID_DATES} SQL mode.
@item
Added @code{STRICT_TRANS_TABLES}, @code{STRICT_ALL_TABLES},
@code{NO_ZERO_IN_DATE}, @code{NO_ZERO_DATE},
@code{ERROR_FOR_DIVISION_BY_ZERO}, and @code{TRADITIONAL} SQL modes.
The @code{TRADITIONAL} mode is shorthand for all the preceding modes.
When using mode @code{TRADITIONAL}, MySQL generates an error if you try
to insert a wrong value in a column. It does not adjust the value to the
closest possible legal value.
@item
MySQL now remembers which columns were declared to have default values.
In @code{STRICT_TRANS_TABLES}/@code{STRICT_ALL_TABLES} mode, you now get
an error if you do an @code{INSERT} without specifying all columns that
don't have a default value. A side effect of this is that when you do
@code{SHOW CREATE} for a new table, you will no longer see a @code{DEFAULT}
value for a column for which you didn't specify a default value.
@item
The compilation flag @code{DONT_USE_DEFAULT_FIELDS} was removed because you
can get the same behavior by setting the @code{sql_mode} system variable to
@code{STRICT_TRANS_TABLES}.
@item
Added @code{NO_AUTO_CREATE_USER} SQL mode to prevent @code{GRANT}
from automatically creating new users if it would otherwise do so,
unless a password also is specified.
@item
We now detect too-large floating point numbers during statement parsing
and generate an error messages for them.
@item
Renamed the @code{sql_updatable_view_key} system variable to
@code{updatable_views_with_limit}. This variable now can have only two values:
@itemize @bullet
@item
@code{1} or @code{YES}: Don't issue an error message (warning only) if a
VIEW without presence of a key in the underlying table is used in queries
with a @code{LIMIT} clause for updating. (This is the default value.)
@item
@code{0} or @code{NO}: Prohibit update of a VIEW, which does not contain a
key in the underlying table and the query uses a @code{LIMIT} clause (usually
get from GUI tools).
@end itemize
@item
Reverted output format of @code{SHOW TABLES} to old pre-5.0.1 format that did
not include a table type column. To get the additional column that lists the
table type, use @code{SHOW FULL TABLES} now.
@item
The @command{mysql_fix_privilege_tables} script now initializes the global
@code{CREATE VIEW} and @code{SHOW VIEW} privileges in the @code{user}
table to the value of the @code{CREATE} privilege in that table.
@item
If the server finds that the @code{user} table has not been upgraded to
include the view-related privilege columns, it treats each account as having
view privileges that are the same as its @code{CREATE} privilege.
@item
InnoDB: If you specify the option @code{innodb_locks_unsafe_for_binlog}
in @file{my.cnf}, InnoDB in an @code{UPDATE} or a @code{DELETE} only
locks the rows that it updates or deletes. This greatly reduces the
probability of deadlocks.
@item
A connection doing a rollback will now display "Rolling back" in the
@code{State} column of @code{SHOW PROCESSLIST}.
@item
@command{mysqlbinlog} now prints an informative commented line (thread id,
timestamp, server id, etc) before each @code{LOAD DATA INFILE}, like it already
does for other queries; unless @code{--short-form} is used.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Fixed that @command{mysqlbinlog --read-from-remote-server} sometimes
couldn't accept two binary logfiles on the command line. (Bug #4507)
@item
Fixed that @command{mysqlbinlog --position --read-from-remote-server}
had incorrect @code{# at} lines. (Bug #4506)
@item
Fixed that @code{CREATE TABLE ... TYPE=HEAP ... AS SELECT...} caused
replication slave to stop. (Bug #4971)
@item
Fixed that @code{mysql_options(...,MYSQL_OPT_LOCAL_INFILE,...)} failed to
disable @code{LOAD DATA LOCAL INFILE}. (Bug #5038)
@item
Fixed that @code{disable-local-infile} option had no effect if client read it
from a configuration file using
@code{mysql_options(...,MYSQL_READ_DEFAULT,...)}. (Bug #5073)
@item
Fixed that @code{SET GLOBAL SYNC_BINLOG} did not work on some platforms (Mac OS
X). (Bug #5064)
@item
Fixed that @command{mysql-test-run} failed on the @code{rpl_trunc_binlog} test if
running test from the installed (the target of 'make install') directory. (Bug
#5050)
@item
Fixed that @command{mysql-test-run} failed on the @code{grant_cache} test when run
as Unix user 'root'. (Bug #4678)
@item
Fixed an unlikely deadlock which could happen when using @code{KILL}. (Bug
#4810)
@item
Fixed a crash when one connection got @code{KILL}ed while it was doing
@code{START SLAVE}. (Bug #4827)
@item
Made @code{FLUSH TABLES WITH READ LOCK} block @code{COMMIT} if server is
running with binary logging; this ensures that the binary log position can be
trusted when doing a full backup of tables and the binary log. (Bug #4953)
@item
Fixed that the counter of an @code{auto_increment} column was not reset by
@code{TRUNCATE TABLE} is the table was a temporary one. (Bug #5033)
@item
Fixed slave SQL thread so that the @code{SET COLLATION_SERVER...} statements it
replicates don't advance its position (so that if it gets interrupted before
the actual update query, it will later redo the @code{SET}). (Bug #5705)
@item
Fixed that if the slave SQL thread found a syntax error in a query (which
should be rare, as the master parsed it successfully), it stops. (Bug #5711)
@item
Fixed that if a write to a MyISAM table fails because of a full disk or an
exceeded disk quota, it prints a message to the error log every 10 minutes, and
waits until disk becomes free. (Bug #3248)
@item
Fixed problem introduced in 4.0.21 where a connection starting a transaction,
doing updates, then @code{FLUSH TABLES WITH READ LOCK}, then @code{COMMIT},
would cause replication slaves to stop (complaining about error 1223). Bug
surfaced when using the InnoDB @code{innobackup} script. (Bug #5949)
@item
@code{OPTIMIZE TABLE}, @code{REPAIR TABLE}, and @code{ANALYZE TABLE} are now replicated 
without any error code in the binary log. (Bug #5551)
@item
If a connection had an open transaction but had done no updates to
transactional tables (for example if had just done a @code{SELECT FOR UPDATE}
then executed a non-transactional update, that update automatically committed
the transaction (thus releasing InnoDB's row-level locks etc). (Bug #5714)
@item
If a connection was interrupted by a network error and did a rollback, the
network error code got stored into the @code{BEGIN} and @code{ROLLBACK} binary
log events; that caused superfluous slave stops. (Bug #6522)
@end itemize

@node News-5.0.1, News-5.0.0, News-5.0.2, News-5.0.x
@appendixsubsec Changes in release 5.0.1 (27 Jul 2004)

@strong{Note}: This build passes our test suite and fixes a lot of reported
bugs found in the previous 5.0.0 release. However, please be aware that this is
not a ``standard MYSQL build'' in the sense that there are still some
open critical bugs in our bugs database at @uref{http://bugs.mysql.com/}
that affect this release as well. We are actively fixing these and will
make a new release where these are fixed as soon as possible. However,
this binary should be a good candidate for testing new MySQL 5.0 features
for future products.

Functionality added or changed:
@itemize @bullet
@item
Added support for read-only and updatable views based on a single table or
other updatable views. View use requires that you upgrade your grant tables
to add the view-related privileges.
@xref{Upgrading-grant-tables}.
@item
Implemented a new ``greedy search'' optimizer that can significantly reduce
the time spent on query optimization for some many-table joins. (You are
affected if not only some particular @code{SELECT} is slow, but even using
@code{EXPLAIN} for it takes a noticeable amount of time.) Two new system
variables, @code{optimizer_search_depth} and @code{optimizer_prune_level}, can
be used to fine-tune optimizer behavior.
@item
@strong{Warning: Incompatible change!}
C API change: @code{mysql_shutdown()} now requires a second argument.
This is a source-level incompatibility that affects how you compile client
programs; it does not affect the ability of compiled clients to communicate
with older servers.
@xref{mysql_shutdown,  , @code{mysql_shutdown()}}.
@item
A stored procedure is no longer ``global.'' That is, it now belongs to a
specific database:
@itemize @bullet
@item
When a database is dropped, all routines belonging to that database are also
dropped.
@item
Procedure names may be qualified, for example, @code{db.p()}
@item
When executed from another database, an implicit @code{USE @var{db_name}} is
in effect.
@item
Explicit @code{USE @var{db_name}} statements no longer are allowed in a
stored procedure.
@end itemize
@xref{Stored Procedures}.
@item
Fixed @code{SHOW TABLES} output field name and values according to standard.
Field name changed from @code{Type} to @code{table_type}, values are
@code{BASE TABLE}, @code{VIEW} and @code{ERROR}. (Bug #4603)
@item
Added the @code{sql_updatable_view_key} system variable.
@item
Added the @code{--replicate-same-server-id} server option.
@item
Added @code{Last_query_cost} status variable that reports optimizer cost
for last compiled query.
@item
Added the @code{--to-last-log} option to @command{mysqlbinlog}, for use
in conjunction with @code{--read-from-remote-server}.
@item
Added the @code{--innodb-safe-binlog} server option, which adds consistency
guarantees between the content of @code{InnoDB} tables and the binary log.
@xref{Binary log}.
@item
@code{OPTIMIZE TABLE} for @code{InnoDB} tables is now mapped to @code{ALTER
TABLE} instead of @code{ANALYZE TABLE}.
@item
@code{sync_frm} is now a settable global variable (not only a startup option).
@item
For replication of @code{MEMORY} (@code{HEAP}) tables: Made the master
automatically write a @code{DELETE FROM} statement to its binary log when a
@code{MEMORY} table is opened for the first time since master's startup.
This is for the case where the slave has replicated a non-empty
@code{MEMORY} table, then the master is shut down and restarted: the table
is now empty on master; the @code{DELETE FROM} empties it on slave too. Note
that even with this fix, between the master's restart and the first use of
the table on master, the slave still has out-of-date data in the table. But
if you use the @code{--init-file} option to populate the @code{MEMORY} table
on the master at startup, it ensures that the failing time interval is zero.
(Bug #2477)
@item
When a session having open temporary tables terminates, the statement
automatically written to the binary log is now @code{DROP TEMPORARY TABLE IF
EXISTS} instead of @code{DROP TEMPORARY TABLE}, for more robustness.
@item
The MySQL server now returns an error if @code{SET SQL_LOG_BIN} is issued by a
user without the @code{SUPER} privilege (in previous versions it just silently
ignored the statement in this case).
@item
Changed that when the MySQL server has binary logging disabled (that is,
no @code{--log-bin} option was used), then no transaction binary log cache
is allocated for connections. This should save @code{binlog_cache_size}
bytes of memory (32KB by default) for every connection.
@item
Added the @code{sync_binlog=N} global variable and startup option, which makes
the MySQL server synchronize its binary log to disk (@code{fdatasync()}) after
every Nth write to the binary log.
@item
Changed the slave SQL thread to print less useless error messages (no more
message duplication; no more messages when an error is skipped because of
@code{slave-skip-errors}).
@item
@code{DROP DATABASE IF EXISTS}, @code{DROP TABLE IF EXISTS}, single-table
@code{DELETE}, and single-table @code{UPDATE} now are written to the binary log
even if they changed nothing on the master (for example, even if a
@code{DELETE} matched no rows). The old behavior sometimes caused bad surprises
in replication setups.
@item
Replication and @command{mysqlbinlog} now have better support for the case that
the session character set and collation variables are changed within a given
session.
@xref{Replication Features}.
@item
Killing a @code{CHECK TABLE} statement does not result in the table being
marked as ``corrupted'' any more; the table remains as if @code{CHECK TABLE}
had not even started.
@xref{KILL,  , @code{KILL}}.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Strange results with index (x, y) ... WHERE x=val_1 AND y>=val_2 ORDER BY pk; (Bug #3155)
@item
Subquery and order by (Bug #3118)
@item
@code{ALTER DATABASE} caused the client to hang if the database did not
exist. (Bug #2333)
@item
@code{SLAVE START} (which is a deprecated syntax, @code{START SLAVE} should be
used instead) could crash the slave. (Bug #2516)
@item
Multiple-table @code{DELETE} statements were never replicated by the slave if
there were any @code{--replicate-*-table} options. (Bug #2527)
@item
The MySQL server did not report any error if a statement (submitted through
@code{mysql_real_query()} or @code{mysql_stmt_prepare()}) was terminated
by garbage characters. This can happen if you pass a wrong @code{length}
parameter to these functions. The result was that the
garbage characters were written into the binary log. (Bug #2703)
@item
Replication:
If a client connects to a slave server and issues an administrative
statement for a table (for example, @code{OPTIMIZE TABLE} or @code{REPAIR
TABLE}), this could sometimes stop the slave SQL thread. This does not lead
to any corruption, but you must use @code{START SLAVE} to get replication
going again. (Bug #1858)
@item
Made clearer the error message that one gets when an update is refused because
of the @code{--read-only} option. (Bug #2757)
@item
Fixed that @code{--replicate-wild-*-table} rules apply to @code{ALTER DATABASE}
when the table pattern is @code{%}, as is already the case for @code{CREATE
DATABASE} and @code{DROP DATABASE}. (Bug #3000)
@item
Fixed that when a @code{Rotate} event is found by the slave SQL thread in the
middle of a transaction, the value of @code{Relay_Log_Pos} in @code{SHOW SLAVE
STATUS} remains correct. (Bug #3017)
@item
Corrected the master's binary log position that @code{InnoDB} reports when it is doing a
crash recovery on a slave server. (Bug #3015)
@item
Changed the column @code{Seconds_Behind_Master} in @code{SHOW SLAVE STATUS} to
never show a value of @minus{}1. (Bug #2826)
@item
Changed that when a @code{DROP TEMPORARY TABLE} statement is automatically
written to the binary log when a session ends, the statement is recorded with an
error code of value zero (this ensures that killing a @code{SELECT} on the
master does not result in a superfluous error on the slave). (Bug #3063)
@item
Changed that when a thread handling @code{INSERT DELAYED} (also known as a
@code{delayed_insert} thread) is killed, its statements are recorded with an
error code of value zero (killing such a thread does not endanger
replication, so we thus avoid a superfluous error on the slave). (Bug #3081)
@item
Fixed deadlock when two @code{START SLAVE} commands were run at the same
time. (Bug #2921)
@item
Fixed that a statement never triggers a superfluous error on the slave, if it
must be excluded given the @code{--replicate-*} options. The bug was that if the
statement had been killed on the master, the slave would stop. (Bug #2983)
@item
The @code{--local-load} option of @command{mysqlbinlog} now requires an argument.
@item
Fixed a segmentation fault when running @code{LOAD DATA FROM MASTER} after
@code{RESET SLAVE}. (Bug #2922)
@item
@command{mysqlbinlog --read-from-remote-server} read all binary logs following the
one that was requested.  It now stops at the end of the requested file, the
same as it does when reading a local binary log. There is an option
@code{--to-last-log} to get the old behavior. (Bug #3204)
@item
Fixed @command{mysqlbinlog --read-from-remote-server} to print the exact
positions of events in the "at #" lines. (Bug #3214)
@item
Fixed a rare error condition that caused the slave SQL thread spuriously
to print the message @code{Binlog has bad magic number} and stop when it
was not necessary to do so.  (Bug #3401)
@item
Fixed @command{mysqlbinlog} not to forget to print a @code{USE} statement
under rare circumstances where the binary log contained a @code{LOAD DATA
INFILE} statement. (Bug #3415)
@item
Fixed a memory corruption when replicating a @code{LOAD DATA INFILE} when the
master had version 3.23. (Bug #3422)
@item
Multiple-table @code{DELETE} statements were always replicated by the slave if
there were some @code{--replicate-*-ignore-table} options and no
@code{--replicate-*-do-table} options. (Bug #3461)
@item
Fixed a crash of the MySQL slave server when it was built with
@code{--with-debug} and replicating itself. (Bug #3568)
@item
Fixed that in some replication error messages, a very long query caused the rest
of the message to be invisible (truncated), by putting the query last in the
message. (Bug #3357)
@item
If @code{server-id} was not set using startup options but with @code{SET
GLOBAL}, the replication slave still complained that it was not set.
(Bug #3829)
@item
@command{mysql_fix_privilege_tables} didn't correctly handle the argument of its
@code{--password=#} option. (Bug #4240)
@item
Fixed potential memory overrun in @code{mysql_real_connect()} (which
required a compromised DNS server and certain operating systems). (Bug #4017)
@item
During the installation process of the server RPM on Linux, @command{mysqld}
was run as the @code{root} system user, and if you had
@code{--log-bin=<somewhere_out_of_var_lib_mysql>} it created binary log
files owned by @code{root} in this directory, which remained owned by
@code{root} after the installation. This is now fixed by starting
@command{mysqld} as the @code{mysql} system user instead. (Bug #4038)
@item
Made @code{DROP DATABASE} honor the value of
@code{lower_case_table_names}. (Bug #4066)
@item
The slave SQL thread refused to replicate @code{INSERT ... SELECT} if it
examined more than 4 billion rows. (Bug #3871)
@item
@command{mysqlbinlog} didn't escape the string content of user variables, and did
not deal well when these variables were in non-ASCII character sets; this is
now fixed by always printing the string content of user variables in
hexadecimal. The character set and collation of the string is now also
printed. (Bug #3875)
@item
Fixed incorrect destruction of expression that led to a server crash on
complex @code{AND}/@code{OR} expressions if query was ignored (either by a
replication server because of @code{--replicate-*-table} rules, or by any MySQL
server because of a syntax error). (Bug #3969, Bug #4494)
@item
If @code{CREATE TEMPORARY TABLE t SELECT} failed while loading the data, the
temporary table was not dropped. (Bug #4551)
@item
Fixed that when a multiple-table @code{DROP TABLE} failed to drop a table on
the master server, the error code was not written to the binary log.
(Bug #4553)
@item
When the slave SQL thread was replicating a @code{LOAD DATA INFILE}
statement, it didn't show the statement in the output of @code{SHOW
PROCESSLIST}. (Bug #4326)
@end itemize


@node News-5.0.0,  , News-5.0.1, News-5.0.x
@appendixsubsec Changes in release 5.0.0 (22 Dec 2003: Alpha)

Functionality added or changed:
@itemize @bullet
@item
The @code{KILL} statement now takes @code{CONNECTION} and @code{QUERY}
modifiers. The first is the same as @code{KILL} with no modifier (it
kills a given connection thread).  The second kills only the statement
currently being executed by the connection.
@item
Added @code{TIMESTAMPADD()} and @code{TIMESTAMPDIFF()} functions.
@item
Added @code{WEEK} and @code{QUARTER} values as @code{INTERVAL} arguments
for the @code{DATE_ADD()} and @code{DATE_SUB()} functions.
@item
New binary log format that enables replication of these session variables:
@code{sql_mode}, @code{SQL_AUTO_IS_NULL}, @code{FOREIGN_KEY_CHECKS}
(which was already replicated since 4.0.14, but here it's done more
efficiently and takes less space in the binary logs), @code{UNIQUE_CHECKS}.
Other variables (like character sets, @code{SQL_SELECT_LIMIT}, ...) will be
replicated in upcoming 5.0.x releases.
@item
Implemented Index Merge optimization for @code{OR} clauses.
@xref{Index Merge optimization}.
@item
Basic support for stored procedures (SQL:2003 style).
@xref{Stored Procedures}.
@item
Added @code{SELECT INTO @var{list_of_vars}}, which can be of mixed
(that is, global and local) types.
@xref{SELECT INTO Statement,  , @code{SELECT INTO} Statement}.
@item
Easier replication upgrade (5.0.0 masters can read older binary logs and
5.0.0 slaves can read older relay logs). See @ref{Replication Compatibility}
for more details). The format of the binary log and relay log is changed
compared to that of MySQL 4.1 and older.
@item
@strong{Important note:} If you upgrade to MySQL 4.1.1 or higher, it is
difficult to downgrade back to 4.0 or 4.1.0! That is because, for earlier
versions, @code{InnoDB} is not aware of multiple tablespaces.
@end itemize

Bugs fixed:
@itemize @bullet
@end itemize


@node News-4.1.x, News-4.0.x, News-5.0.x, News
@appendixsec Changes in release 4.1.x (Production)

@cindex changes, version 4.1

Version 4.1 of the MySQL server includes many enhancements and new features.
Binaries for this version are available for download at
@uref{http://dev.mysql.com/downloads/mysql-4.1.html}.

@itemize @bullet
@item
Subqueries and derived tables (unnamed views).
@xref{Subqueries}.
@item
@code{INSERT ... ON DUPLICATE KEY UPDATE ...} syntax.  This allows you to
@code{UPDATE} an existing row if the insert would cause a duplicate value
in a @code{PRIMARY} or @code{UNIQUE} key. (@code{REPLACE} allows you to
overwrite an existing row, which is something entirely different.)
@xref{INSERT}.
@item
A newly designed @code{GROUP_CONCAT()} aggregate function.
@xref{Group by functions and modifiers}.
@item
Extensive Unicode (UTF8) support.
@item
Table names and column names now are stored in @code{UTF8}. This makes MySQL
more flexible, but might cause some problems upgrading if you have table
or column names that use characters outside of the standard 7-bit US-ASCII
range.
@xref{Upgrading-from-4.0}.
@item
Character sets can be defined per column, table, and database.
@item
New key cache for @code{MyISAM} tables with many tunable parameters.  You can
have multiple key caches, preload index into caches for batches...
@item
@code{BTREE} index on @code{HEAP} tables.
@item
Support for OpenGIS spatial types (geographical data).
@xref{Spatial extensions in MySQL}.
@item
@code{SHOW WARNINGS} shows warnings for the last command.
@xref{SHOW WARNINGS,  , @code{SHOW WARNINGS}}.
@item
Faster binary protocol with prepared statements and parameter binding.
@xref{C API Prepared statements}.
@item
You can now issue multiple statements with a single C API call and
then read the results in one go.
@xref{C API multiple queries}.
@item
Create Table: @code{CREATE [TEMPORARY] TABLE [IF NOT EXISTS] table2 LIKE
table1}.
@item
Server based @code{HELP} command that can be used in the @command{mysql}
command-line client (and other clients) to get help for SQL statements.
@end itemize

For a full list of changes, please refer to the changelog sections for
each individual 4.1.x release.

@menu
* News-4.1.9::                  Changes in release 4.1.9 (not released yet)
* News-4.1.8::                  Changes in release 4.1.8 (14 Dec 2004)
* News-4.1.7::                  Changes in release 4.1.7 (23 Oct 2004: Production)
* News-4.1.6::                  Changes in release 4.1.6 (10 Oct 2004)
* News-4.1.5::                  Changes in release 4.1.5 (16 Sep 2004)
* News-4.1.4::                  Changes in release 4.1.4 (26 Aug 2004: Gamma)
* News-4.1.3::                  Changes in release 4.1.3 (28 Jun 2004: Beta)
* News-4.1.2::                  Changes in release 4.1.2 (28 May 2004)
* News-4.1.1::                  Changes in release 4.1.1 (01 Dec 2003)
* News-4.1.0::                  Changes in release 4.1.0 (03 Apr 2003: Alpha)
@end menu

@node News-4.1.9, News-4.1.8, News-4.1.x, News-4.1.x
@appendixsubsec Changes in release 4.1.9 (not released yet)

@c NOTE: References to bug numbers should be written after the sentence
@c NOTE: describing the bugfix, like this:
@c NOTE: This sentence describes the fix. (Bug #nnnn)

Functionality added or changed:
@itemize @bullet
@end itemize

Bugs fixed:
@itemize @bullet
@end itemize

@node News-4.1.8, News-4.1.7, News-4.1.9, News-4.1.x
@appendixsubsec Changes in release 4.1.8 (14 Dec 2004)

Functionality added or changed:
@itemize @bullet
@item
For @code{ALTER DATABASE}, the database name now can be omitted to apply the
change to the default database.
@item
Added @code{WITH CONSISTENT SNAPSHOT} clause to @code{START TRANSACTION} to
begin a transaction with a consistent read.
@item
Added @code{--order-by-primary} to @command{mysqldump},
to sort each table's data in a dump file.
This may be useful when dumping a MyISAM table which
will be loaded into an InnoDB table.
Dumping a MyISAM table with this option is considerably
slower than without.
@item
InnoDB: Do not periodically write @code{SHOW INNODB STATUS} information
to a temporary file unless the configuration option
@code{innodb_status_file=1} is set.
@item
InnoDB: Commit after every 10,000 copied rows when executing
@code{ALTER TABLE}.  This makes it much faster to recover from an
aborted @code{ALTER TABLE} or @code{OPTIMIZE TABLE}.
@item
@code{FULLTEXT} index block size is changed to be 1024 instead of 2048.
@item
Added @code{--disable-log-bin} option to @command{mysqlbinlog}. Using
this option you can disable binary logging for the statements produced
by @command{mysqlbinlog}. That is, @code{mysqlbinlog --disable-log-bin
<file_name> | mysql} won't write any statements to the MySQL server
binary log.
@item
The @code{--master-data} option for @command{mysqldump} now takes an optional
argument of 1 or 2 to produce a non-commented or commented @code{CHANGE MASTER
TO} statement. The default is 1 for backward compatibility.
@item
@code{mysqldump --single-transaction --master-data} now is able to take an
online (non-blocking) dump of InnoDB and report the corresponding binary log
coordinates. This makes a backup suitable for point-in-time recovery,
roll-forward or replication slave creation. See @ref{mysqldump, ,
@command{mysqldump}}.
@item
Added @code{--lock-all-tables} to @command{mysqldump} to lock all tables by
acquiring a global read lock.
@item
Added @code{--hex-blob} option to @command{mysqldump} for dumping binary
string columns using hexadecimal notation.
@item
Added @code{mysql_hex_string()} C API function that hex-encodes a string.
@item
In the normal log MySQL now prints the logposition for @code{Binlog Dump}
requests.
@item
Added @code{[mysql_cluster]} section to @file{my.cnf} file for configuration
settings specific to MySQL Cluster. @code{ndb-connectstring} variable moved here.
@item
A connection doing a rollback will now display "Rolling back" in the
@code{State} column of @code{SHOW PROCESSLIST}.
@item
@code{mysqlbinlog} now prints an informative commented line (thread id,
timestamp, server id, etc) before each @code{LOAD DATA INFILE}, like it already
does for other queries; unless @code{--short-form} is used.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Fixed incorrect referencing to column by name from subquery to outer query in
case of using temporary table by outer query and placing subquery in the
@code{WHERE} clause. (Bug #7079)
@item
Fixed a bug in authentication code that allowed a malicious user
to crash the server with specially crafted packets
(using a modified client library). (Bug #7187)
@item
Fixed a crashing bug in a string function @code{LEFT}, when this function
is part of the expression which is used as @code{GROUP BY} field.
(Bug #7101)
@item
Fixed bug which caused MySQL to require privileges on system time zone
description tables for implicit access to them (i.e. if one set 
@code{time_zone} variable or used @code{CONVERT_TZ()} function) in case
when some table-level or column-level privileges existed. (Bug #6765)
@item 
@code{mysql_stmt_data_seek(stmt,0)} will now rewind a counter and enable
that buffered rows can be re-fetched on the client side.
(Bug #6996)
@item
Fixed an insufficient privilege check in @code{SHOW CREATE TABLE}
command. (Bug #7043)
@item
Fixed a rare memory corruption (that resulted in a crash) in
@code{MATCH ... AGAINST} on columns that use multi-byte character sets.
(Bug #6269)
@item
Fixed NULL processing in ALL/SOME subqueries. (Bug #6247)
@item
Fixed execution complex queries with subqueries. (Bug #6406, Bug #6841)
@item
Fixed initialization of some internal structures for first execution.
(Bug #6517)
@item
Backported a fix for the fulltext interface from MySQL 5.0.
(Bug #6523)
@item
Fixed NULL value handling in case of empty results in subqueries. (Bug #6806)
@item
Prevent adding @code{CREATE TABLE .. SELECT} query to the binary log when the
insertion of new records partially failed. (Bug #6682)
@item
@code{INSERT ... SELECT} no longer reports spurious "column truncated" warnings
(Bug #6284)
@item
Fixed a bug that could cause "Record has changed since last read in table"
error message in some queires on @code{HEAP} tables that contain only one row.
(Bug #6748)
@item
@command{mysqld_safe} was in many cases ignoring any
@code{--no-defaults}, @code{--defaults-file}, or
@code{--defaults-extra-file} arguments.  Those arguments
are now honored, and this may change what options are
passed to @command{mysqld} in some installations.
@item
The server was interpreting @code{CHAR BINARY} and @code{VARCHAR BINARY}
columns from 4.0 tables as having the @code{BINARY} and @code{VARBINARY}
data types.  Now they are interpreted as @code{CHAR} and @code{VARCHAR}
columns that have the binary collation of the column's character set. (This
is the same way that @code{CHAR BINARY} and @code{VARCHAR BINARY} are
handled for new tables created in 4.1.)
@item
Fixed spurious "duplicate key" error from @code{REPLACE} or
@code{INSERT ... ON DUPLICATE KEY UPDATE} statements performing multiple-row
insert in the table that had unique and fulltext indexes.
(Bug #6784)
@item
Fixed a bug in execution of subqueries in @code{SET} and @code{DO} statements
which caused wrong results to be returned from subsequent queries.
(Bug #6462)
@item
Fixed a bug which allowed server to accept datetime values with wrong year
part. Also now server will perform same checks for datetime values passed 
through @code{MYSQL_TIME} structure as for datetime values passed as strings.
(Bug #6266)
@item
Fixed a bug with @code{INSERT} for a table with @code{FULLTEXT} indexes.
Under rare circumstances, this could result in a corrupted table if words of
different lengths may be considered equal. This is possible in some
collations, for example, in @code{utf8_general_ci} or @code{latin1_german2_ci}.
(Bug #6265)
@item
InnoDB: Do not intentionally crash @file{mysqld} if the buffer
pool is exhausted by the lock table; return error 1206 instead.
Do not intentionally crash @file{mysqld} if we cannot allocate the
memory for the InnoDB buffer pool. (Bug #6817) (Bug #6827)
@item
InnoDB: Let InnoDB's @code{FOREIGN KEY} parser to remove the @code{latin1}
character @code{0xA0} from the end of an unquoted identifier. The EMS MySQL
Manager in @code{ALTER TABLE} adds that character after a table name, which
caused error 121 when we tried to add a new constraint.
@item
InnoDB: Refuse to open new-style tables created with MySQL 5.0.3 or later.
(Bug #7089)
@item
InnoDB: Do not call @code{rewind()} when displaying
@code{SHOW INNODB STATUS} information on @code{stderr}.
@item
InnoDB: Made the foreign key parser better aware of quotes.  (Bug #6340)
@item
InnoDB: If one used @code{INSERT IGNORE} to insert several rows at a time,
and the first inserts were ignored because of a duplicate key collision,
then InnoDB in a replication slave assigned @code{AUTO_INCREMENT} values 1
bigger than in the master. This broke the MySQL replication. (Bug #6287)
@item
InnoDB: Fixed a bug: InnoDB ignored in @code{innodb_data_file_path} the
@code{max} specification in @code{:autoextend:max:2000M}.
This bug was introduced in 4.1.1.
@item
InnoDB: Fixed a bug: @code{innodb_locks_unsafe_for_binlog} still uses
next-key locking (Bug #6747). InnoDB used next-key locking when
record matched completely to search tuple. This unnecessary
next-key locking is now removed when @code{innodb_locks_unsafe_for_binlog}
option is used.
@item
InnoDB: Fix two hangs: @code{FOREIGN KEY} constraints treated table and
database names as case-insensitive. @code{RENAME TABLE t TO T} would hang
in an endless loop if @code{t} had a foreign key constraint defined on it.
Fix also a hang over the dictionary mutex that would occur if one tried
in @code{ALTER TABLE} or @code{RENAME TABLE} to create a foreign key
constraint name that collided with another existing name. (Bug #3478)
@item
If @code{STMT_ATTR_UPDATE_MAX_LENGTH} is set for a prepared statement,
@code{mysql_stmt_store_result()} will update @code{field->max_length}
for numeric columns as well. (Bug#6096)
@item
Prepared statements now handle zerofill when converting @code{integer} to
@code{string}.
@item
Fixed crash when a call to @code{mysql_stmt_store_result()} occurred without
a preceding call to @code{mysql_stmt_bind_result()}.
@item
Fixed crash in prepared statements when using
@code{SELECT * FROM t1 NATURAL JOIN t2...}.
@item
Fixed crash in prepared statements when using @code{SELECT ... PROCEDURE}.
@item
Fixed crash in prepared statements when using subqueries.
@item
@code{GROUP_CONCAT(...ORDER BY)} when used with prepared statements gave
wrong sorting order.
@code{CREATE TABLE @var{created_table}} didn't signal when table was created.
This could cause a @code{DROP TABLE @var{created_table}} in another thread
to wait "forever".
@item
Server warnings now are reset when you execute a prepared statement.
@item
Improved performance of identifier comparisons
(if many tables or columns are specified).
@item
@code{OPTIMIZE TABLE}, @code{REPAIR TABLE}, and @code{ANALYZE TABLE} are now replicated
without any error code in the binary log. (Bug #5551)
@item
@code{LOAD DATA INFILE} now works with option replicate-rewrite-db.
(Bug #6353)
@item
Fixed a bug which caused a crash when only the slave I/O thread was
stopped and started. (Bug #6148)
@item
Changed semantics of @code{CREATE/ALTER/DROP DATABASE} statements so
that replication of @code{CREATE DATABASE} is possible when using
@code{--binlog-do-db} and @code{--binlog-ignore-db}. (Bug #6391)
@item
If a connection had an open transaction but had done no updates to
transactional tables (for example if had just done a @code{SELECT FOR UPDATE}
then executed a non-transactional update, that update automatically committed
the transaction (thus releasing InnoDB's row-level locks etc). (Bug #5714)
@item
If a connection was interrupted by a network error and did a rollback, the
network error code got stored into the @code{BEGIN} and @code{ROLLBACK} binary
log events; that caused superfluous slave stops. (Bug #6522)
@item
A sequence of @code{BEGIN} (or @code{SET AUTOCOMMIT=0}), @code{FLUSH TABLES
WITH READ LOCK}, transactional update, @code{COMMIT}, @code{FLUSH
TABLES WITH READ LOCK} could hang the connection forever and possibly the MySQL
server itself. This happened for example when running the @code{innobackup}
script several times. (Bug #6732)
@item
@command{mysqlbinlog} did not print @code{SET PSEUDO_THREAD_ID} statements in
front of @code{LOAD DATA INFILE} statements inserting into temporary tables,
thus causing potential problems when rolling forward these statements after
restoring a backup. (Bug #6671)
@end itemize

@node News-4.1.7, News-4.1.6, News-4.1.8, News-4.1.x
@appendixsubsec Changes in release 4.1.7 (23 Oct 2004: Production)

Functionality added or changed:
@itemize @bullet
@item
@code{MOD()} no longer rounds arguments with a fractional part to integers.
Now it returns exact remainder after division. (Bug #6138)
@item
InnoDB: Added a
startup option and settable system variable @code{innodb_table_locks}
for making @code{LOCK TABLE} acquire also @code{InnoDB} locks.
The default value is 1, which means that
@code{LOCK TABLES} causes also InnoDB internally to take a table lock.
In applications using @code{AUTOCOMMIT=1} and @code{LOCK TABLES}, InnoDB's
internal table locks that were added in 4.0.20 and 4.1.2
can cause deadlocks. You can set
@code{innodb_table_locks=0} in @file{my.cnf} to remove that problem.
(Bug #3299, Bug #5998)
@item
@xref{InnoDB restrictions}.  (Bug #3299, Bug #5998)
InnoDB: @code{SHOW TABLE STATUS} now shows the creation time of the table
for InnoDB. Note that this timestamp might not be the correct time because,
e.g., @code{ALTER TABLE} changes this timestamp.
@item
InnoDB: If @code{innodb_thread_concurrency} would be exceeded, let a thread
sleep 10 ms before entering the FIFO queue; previously, the value was 50 ms.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Fixed a bug with @code{FOUND_ROWS()} used together with @code{LIMIT} clause
in prepared statements. (Bug#6088)
@item
Fixed a bug with @code{NATURAL JOIN} in prepared statements. (Bug#6046).
@item
Fixed a bug in join of tables from different databases having columns with 
identical names (prepared statements). (Bug#6050)
@item
Now implicit access to system time zone description tables (which happens
when you set @code{time_zone} variable or use @code{CONVERT_TZ()} function)
does not require any privileges. (Bug #6116)
@item
Fixed a bug which caused the server to crash when the deprecated @code{libmysqlclient} 
function @code{mysql_create_db()} was called. (Bug #6081)
@item
Fixed @code{REVOKE ALL PRIVILEGES, GRANT OPTION FROM @var{user}} so that all
privileges are revoked correctly. (Bug #5831).  This corrects a case that
the fix in 4.1.6 could miss.
@item
Fixed crash when selecting from a @code{HEAP} table with @code{key_column IS
NOT NULL}. This could also cause a crash if not all index parts where used.
(Bug #6082)
@item
Fixed a bug that could cause MyISAM index corruption when key values
start with character codes below @code{BLANK}. This was caused by the
new key sort order in 4.1. (Bug #6151)
@item
InnoDB: Fixed a bug in @code{LOAD DATA INFILE@dots{}REPLACE}
printing duplicate key error when executing the same
load query several times. (Bug #5835)
@item
Fixed a bug in the prepared statements protocol when wrong metadata 
was sent for @code{SELECT} statements not returning a result set (such
as @code{SELECT ... INTO OUTFILE}). (Bug #6059)
@item
Fixed bug which allowed one to circumvent missing UPDATE privilege if one had
INSERT and SELECT privileges for table with primary key. (Bug #6173)
@item 
Fixed a bug in @code{libmysqlclient} with wrong conversion of negative time
values to strings. (Bug #6049).
@item
Fixed a bug in @code{libmysqlclient} with wrong conversion of zero date
values (@code{0000-00-00}) to strings. (Bug #6058)
@item 
Fixed a bug that caused the server to crash on attempt to prepare 
a statement with @code{RAND(?)}. (Bug #5985)
@item 
Fixed a bug with handling of @code{DATE}, @code{TIME}, and @code{DATETIME}
columns in the binary protocol. The problem is compiler-specific and could
have been observed on HP-UX, AIX, Solaris9, when compiling with native
compiler. (Bug #6025)
@item 
Fixed a bug with handling of @code{TINYINT} columns in the binary protocol.
The problem is specific to platforms where the C compiler has the @code{char}
data type unsigned by default. (Bug #6024)
@item
InnoDB: Fixed problem introduced in MySQL 4.0.21 where a connection starting a
transaction, doing updates, then @code{FLUSH TABLES WITH READ LOCK},
then @code{COMMIT}, would cause replication slaves to stop (complaining
about error 1223). Bug surfaced when using the InnoDB @code{innobackup}
script. (Bug #5949)
@item
InnoDB: Release the dictionary latch during a long cascaded @code{FOREIGN KEY}
operation, so that we do not starve other users doing @code{CREATE TABLE}
or other DDL operation. This caused a notorious 'Long semaphore wait' message
to be printed to the @file{.err} log. (Bug #5961)
@end itemize

@node News-4.1.6, News-4.1.5, News-4.1.7, News-4.1.x
@appendixsubsec Changes in release 4.1.6 (10 Oct 2004)

Functionality added or changed:
@itemize @bullet
@item
Added option @code{--sigint-ignore} to the @code{mysql} command line client
to make it ignore @code{SIGINT} signals (typically the result of the user
pressing Control-C).
@item
InnoDB: Added the startup option and settable global variable
@code{innodb_max_purge_lag} for delaying @code{INSERT}, @code{UPDATE}
and @code{DELETE} operations when the purge operations are lagging.
The default value of this parameter is zero, meaning that there will
not be any delays. @xref{Implementation}.
@item
InnoDB: The @code{innodb_autoextend_increment} startup option that was
introduced in release 4.1.5 was made a settable global variable. (Bug #5736)
@item
InnoDB: If @code{DROP TABLE} is invoked on an InnoDB table for which the
@code{.ibd} file is missing, print to error log that the table was removed
from the @code{InnoDB} data dictionary, and allow MySQL to delete the
@code{.frm} file.  Maybe @code{DROP TABLE} should issue a warning in this
case.
@item
@code{TIMESTAMP} columns now can store @code{NULL} values. To create such 
a column, you must explicitly specify the @code{NULL} attribute in the column
specification. (Unlike all other column types, @code{TIMESTAMP} columns
are @code{NOT NULL} by default.)
@item
Now if @code{ALTER TABLE} converts one @code{AUTO_INCREMENT} column to
another @code{AUTO_INCREMENT} column it will preserve zero values (this
includes the case that we don't change such column at all).
@item
Now if @code{ALTER TABLE} converts some column to @code{TIMESTAMP NOT NULL}
column it will convert @code{NULL} values to current timestamp value (One can
still get old behavior by setting system @code{TIMESTAMP} variable to zero).
@item
On Windows, the MySQL configuration files included in the package now
use @file{.ini} instead of @file{.cnf} as the file name suffix.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Fixed a bug that caused the server to crash on attempt to execute 
a prepared statement with a subselect inside a boolean expression.
(Bug #5987)
@item
Fixed a bug that caused the server to sometimes choose non-optimal
execution plan for a prepared statement executed with changed placeholder
values. (Bug #6042)
@item
InnoDB: Make the check for excessive semaphore waits tolerate glitches
in the system clock (do not crash the server if the system time is
adjusted while InnoDB is under load.).  (Bug #5898)
@item
InnoDB: Fixed a bug in the InnoDB @code{FOREIGN KEY} parser that prevented
@code{ALTER TABLE} of tables containing @samp{#} in their names.  (Bug #5856)
@item
InnoDB: Fixed a bug that prevented
@code{ALTER TABLE @var{t} DISCARD TABLESPACE} from working.  (Bug #5851)
@item
InnoDB: @code{SHOW CREATE TABLE} now obeys the @code{SET SQL_MODE=ANSI}
and @code{SET SQL_QUOTE_SHOW_CREATE=0} settings.  (Bug #5292)
@item
InnoDB: Fixed a bug that caused
@code{CREATE TEMPORARY TABLE ... ENGINE=InnoDB} to terminate
@code{mysqld} when running in @code{innodb_file_per_table} mode.
Per-table tablespaces for temporary tables will from now on be
created in the temporary directory of @code{mysqld}.  (Bug #5137)
@item
InnoDB: Fixed some (not all) UTF-8 bugs in column prefix indexes.  (Bug #5975)
@item
InnoDB: If one updated a column so that its size changed, or updated
it to an externally stored (@code{TEXT} or @code{BLOB}) value, then
ANOTHER externally stored column would show up as 512 bytes of good
data + 20 bytes of garbage in a consistent read that fetched the old
version of the row. (Bug #5960)
@item
InnoDB: Change error code to @code{HA_ERR_ROW_IS_REFERENCED} if we cannot
@code{DROP} a parent table referenced by a @code{FOREIGN KEY} constraint;
this error number is less misleading than the previous number
@code{HA_ERR_CANNOT_ADD_FOREIGN}, but misleading still.
@item
Fixed @code{REVOKE ALL PRIVILEGES, GRANT OPTION FROM @var{user}}
so that all privileges are revoked correctly.  (Bug #5831)
@item
Fixed a bug that caused the server to crash when character set
conversion was implicitly used in prepared mode; for example, as in
@code{'abc' LIKE CONVERT('abc' as utf8)}. (Bug #5688)
@item
The @code{mysql_change_user()} C API function now frees all prepared statements
associated with the connection. (Bug #5315)
@item
Fixed a bug when inserting @code{NULL} into an @code{AUTO_INCREMENT} column
failed, when using prepared statements. (Bug #5510)
@item
Fixed slave SQL thread so that the @code{SET COLLATION_SERVER...} statements it
replicates don't advance its position (so that if it gets interrupted before
the actual update query, it will later redo the @code{SET}). (Bug #5705)
@item
Fixed that if the slave SQL thread found a syntax error in a query (which
should be rare, as the master parsed it successfully), it stops. (Bug #5711)
@item
Fixed that if a write to a @code{MyISAM} table fails because of a full disk or
an exceeded disk quota, it prints a message to the error log every 10 minutes,
and waits until disk space becomes available. (Bug #3248)
@item
Now MySQL will not prefer columns, which are mentioned in select list but
are renamed, over columns from other tables participating in @code{FROM} 
clause when it resolves @code{GROUP BY} clause (e.g. @code{SELECT t1.a AS
c FROM t1, t2 ORDER BY a} will produce an error if both @code{t1} and
@code{t2} tables contain @code{a} column). (Bug #4302)
@item
Behavior of @code{ALTER TABLE} converting column containing @code{NULL}
values to @code{AUTO_INCREMENT} column is no longer affected by
@code{NO_AUTO_VALUE_ON_ZERO} mode. (Bug #5915).
@end itemize

@node News-4.1.5, News-4.1.4, News-4.1.6, News-4.1.x
@appendixsubsec Changes in release 4.1.5 (16 Sep 2004)

Functionality added or changed:
@itemize @bullet
@item
@code{InnoDB}: Added configuration option @code{innodb_autoextend_increment}
for setting the size in megabytes by which @code{InnoDB} tablespaces are
extended when they become full.  The default value is 8, corresponding to
the fixed increment of 8MB in previous versions of MySQL.
@item
@code{InnoDB}: The new Windows installation wizard of MySQL makes InnoDB as
the MySQL default table type on Windows, unless explicitly specified
otherwise. Note that it places the @file{my.ini} file in the
installation directory of the MySQL server.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Fixed a bug which caused the server to crash on attempt to execute 
a prepared statement with @code{BETWEEN ? AND ?} and a datetime column.
(Bug #5748)
@item
Fixed name resolving of external fields of subqueries if subquery placed in
select list of query with grouping. (Bug #5326)
@item
Fixed detection of using same table for updating and selecting in
multi-update queries. (Bug #5455)
@item
The values of the @code{max_sort_length}, @code{sql_mode}, and
@code{group_concat_max_len} system variables now are stored in the query cache
with other query information to avoid returning an incorrect result from the
query cache. (Bug #5394)
(Bug #5515)
@item
Fixed syntax analyzer with @code{sql_mode=IGNORE_SPACE}. It happened
to take phrases like @code{default .07} as
@code{identifier.identifier}. (Bug #5318)
@item
Fixed illegal internal field length of user variables of integer type. 
This showed up when creating a table as @code{SELECT @@@var{var_name}}.
(Bug #4788)
@item
Fixed a buffer overflow in prepared statements API (libmysqlclient) when
a statement containing thousands of placeholders was executed. (Bug #5194)
@item
Fixed a bug in the server when after reaching a certain limit of
prepared statements per connection (97), statement ids began to overlap, 
so occasionally wrong statements were chosen for execution. (Bug #5399)
@item
Fixed a bug in prepared statements when @code{LIKE} used with arguments
in different character sets crashed server on first execute. (Bug #4368)
@item 
Fixed a bug in prepared statements when providing '0000-00-00' date to
a parameter lead to server crash. (Bug #4231, Bug #4562)
@item 
Fixed a bug in @code{OPTIMIZE TABLE} that could cause table corruption
on @code{FULLTEXT} indexes. (Bug #5327)
@item
InnoDB: Fixed a bug that InnoDB only allowed a maximum of 1000 connections
inside InnoDB at the same time. A higher number could cause an assertion
failure in sync0arr.c, line 384. Now we allow 1000, 10000, or 50000,
depending on the buffer pool size. (Bug #5414)
@end itemize

@node News-4.1.4, News-4.1.3, News-4.1.5, News-4.1.x
@appendixsubsec Changes in release 4.1.4 (26 Aug 2004: Gamma)

@strong{Note}: To fix a compile problem on systems that do not have
@code{automake} 1.7 installed, an updated 4.1.4a source tarball has been
published.  In addition to resolving this @code{automake} dependency (Bug
#5319), it also fixes some reported @code{libedit} compile errors when using
a non-@code{gcc} compiler (Bug #5353).

Functionality added or changed:
@itemize @bullet
@item
Added the @code{CSV} storage engine.
@item
Made internal representation of @code{TIMESTAMP} values in @code{InnoDB} in
4.1 to be the same as in 4.0. This difference resulted in incorrect datetime
values in @code{TIMESTAMP} columns in @code{InnoDB} tables after an upgrade
from 4.0 to 4.1. (Bug #4492)
@strong{Warning: extra steps during upgrade required!}
Unfortunately this means that if you are upgrading from 4.1.x,
where x <= 3, to 4.1.4
you should use @command{mysqldump} for saving and then restoring your
@code{InnoDB} tables with @code{TIMESTAMP} columns.
@item
The @command{mysqld-opt} Windows server was renamed to @command{mysqld}.
This completes the Windows server renaming begun in MySQL 4.1.2.
@xref{Windows select server}.
@item
Added Latin language collations for the @code{ucs2} and @code{utf8} Unicode
character sets.  These are called @code{ucs2_roman_ci} and
@code{utf8_roman_ci}.
@item
Corrected the name of the Mac OS X StartupItem script (it must match the name
of the subdirectory, which was renamed to @code{MySQLCOM} in MySQL 4.1.2).
Thanks to Bryan McCormack for reporting this.
@item
Added @code{--start-datetime}, @code{--stop-datetime}, @code{--start-position},
and @code{--stop-position} options to @code{mysqlbinlog}. These make
point-in-time recovery easier.
@item
Killing a @code{CHECK TABLE} statement does not result in the table being
marked as ``corrupted'' any more; the table remains as if @code{CHECK TABLE}
had not even started.
@xref{KILL,  , @code{KILL}}.
@item
Made the MySQL server ignore @code{SIGHUP} and @code{SIGQUIT} on Mac OS X 10.3.
This is needed because under this OS, the MySQL server receives lots of these
signals (reported as Bug #2030).
@item
Support of usage of column aliases qualified by table name or alias in 
@code{ORDER BY} and @code{GROUP BY} was dropped. For example the following
query @code{SELECT a AS b FROM t1 ORDER BY t1.b} is not allowed. One should
use @code{SELECT a AS b FROM t1 ORDER BY t1.a} or @code{SELECT a AS b FROM
t1 ORDER BY b} instead. This was non-standard (since aliases are defined on
query level not on table level) and caused problems with some queries.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Fixed a bug that caused libmysql to crash when attempting to fetch a value of
@code{MEDIUMINT} column. (Bug #5126)
@item
Fixed a bug that caused the MySQL server to crash when attempting to execute
a prepared statement with @code{SELECT ... INTO @@var} for a second time.
(Bug #5034)
@item
Fixed execution of optimized @code{IN} subqueries that use compound
indexes. (Bug #4435)
@item
Prohibited resolving of table fields in inner queries if fields do not take
part in grouping for queries with grouping (inside aggregate function
arguments, all table fields are still allowed). (Bug #4814)
@item
Fixed a crash after @code{SLAVE STOP} if the IO thread was in a special
state. (Bug #4629)
@item
Fixed an old bug in concurrent accesses to @code{MERGE} tables
(even one @code{MERGE} table and @code{MyISAM} tables), that could have
resulted in a crash or hang of the server. (Bug #2408)
@item
Fixed a bug that caused server crash on attempt to execute for a second
time a prepared statement with @code{NOT} in @code{WHERE} or @code{ON}
clauses. (Bug #4912)
@item
@code{MATCH ... AGAINST} now works in a subquery. (Bug #4769)
@item
Fixed a bug that omitted the @file{.err} extension of the error log
file (@code{--log-error}) when the hostname contained a domain name.
The domain name is now replaced by the extension. (Bug #4997)
@item
Fixed a crash in @command{myisamchk}. (Bug #4901)
@item
Fixed a bug which caused server crash if one used the @code{CONVERT_TZ()}
function with time zone described in database as parameter and this time
zone was not used before. (Bug #4508)
@item
Support for @code{%T, %r, %V, %v} and @code{%X, %x} format specifiers was
added to @code{STR_TO_DATE()} function. (Bug #4756)
@item
Fixed a bug (hang) in @code{NATURAL JOIN} where joined table had
no common column. (Bug #4807)
@item
Fixed a crash caused by @code{UNHEX(NULL)}. (Bug #4441)
@item
@command{mysql_fix_privilege_tables} didn't correctly handle the argument of its
@code{--password=#} option. (Bug #4240, Bug #4543)
@item
Fixed that @command{mysqlbinlog --read-from-remote-server} sometimes
couldn't accept 2 binary logs on command line. (Bug #4507)
@item
Fixed that @command{mysqlbinlog --position --read-from-remote-server}
had wrong @code{# at} lines. (Bug #4506)
@item
If @code{CREATE TEMPORARY TABLE t SELECT} failed while loading the data, the
temporary table was not dropped. (Bug #4551)
@item
Fixed that when a multiple-table @code{DROP TABLE} failed to drop a table on
the master server, the error code was not written to the binary log.
(Bug #4553)
@item
When the slave SQL thread was replicating a @code{LOAD DATA INFILE}
statement, it didn't show the statement in the output of @code{SHOW
PROCESSLIST}. (Bug #4326)
@item
Fixed an assertion failure when reading the grant tables (Bug #4407)
@item
Fixed that @code{CREATE TABLE ... TYPE=HEAP ... AS SELECT...} caused
replication slave to stop. (Bug #4971)
@item
Fixed that @code{mysql_options(...,MYSQL_OPT_LOCAL_INFILE,...)} failed to
disable @code{LOAD DATA LOCAL INFILE}. (Bug #5038)
@item
Fixed that @code{disable-local-infile} option had no effect if client read it
from a configuration file using
@code{mysql_options(...,MYSQL_READ_DEFAULT,...)}. (Bug #5073)
@item
Fixed that @code{SET GLOBAL SYNC_BINLOG} did not work on some platforms (Mac OS
X). (Bug #5064)
@item
Fixed that @command{mysql-test-run} failed on the @code{rpl_trunc_binlog} test
if running test from the installed (the target of 'make install') directory.
(Bug #5050)
@item
Fixed that @command{mysql-test-run} failed on the @code{grant_cache} test when
run as Unix user 'root'. (Bug #4678)
@item
Fixed an unlikely deadlock which could happen when using @code{KILL}.
(Bug #4810)
@item
Fixed a crash when one connection got @code{KILL}ed while it was doing
@code{START SLAVE}. (Bug #4827)
@item
Made @code{FLUSH TABLES WITH READ LOCK} block @code{COMMIT} if server is
running with binary logging; this ensures that the binary log position is
trustable when doing a full backup of tables and the binary log. (Bug #4953)
@item
Fixed that the counter of an @code{auto_increment} column was not reset by
@code{TRUNCATE TABLE} if the table was a temporary table. (Bug #5033)
@item
Fixed bug which caused error to be reported when column from @code{ORDER BY}
clause was present in two tables participating in @code{SELECT} even if the
second instance of column in select list was renamed. (Bug #4302)
@end itemize

@node News-4.1.3, News-4.1.2, News-4.1.4, News-4.1.x
@appendixsubsec Changes in release 4.1.3 (28 Jun 2004: Beta)

@strong{Note}: The initial release of MySQL 4.1.3 for Windows accidentally was
not compiled with support for the Spatial Extensions (OpenGIS). This was fixed
by rebuilding from the same 4.1 code snapshot with the missing option and
releasing those packages as version 4.1.3a.

To enable compiling the newly released PHP 5 against MySQL 4.1.3 on Windows, the
Windows packages had to be rebuilt once more to add a few missing symbols to
the MySQL client library. These packages were released as MySQL 4.1.3b.

Functionality added or changed:
@itemize @bullet
@item
Added the @code{ARCHIVE} storage engine.
@item
Added SQL syntax for prepared statements.
@xref{SQLPS}.
@item
Language-specific collations were added for the @code{ucs2} and @code{utf8}
Unicode character sets: Icelandic, Latvian, Romanian, Slovenian, Polish,
Estonian, Swedish, Turkish, Czech, Danish, Lithuanian, Slovak, Spanish,
Traditional Spanish.
@item
Support for per-connection time zones was added. Now you can set the current
time zone for a connection by setting the @code{@@@@time_zone} system
variable to a value such as @code{'+10:00'} or @code{'Europe/Moscow'} (where
@code{'Europe/Moscow'} is the name of one of the time zones described in the
system tables). Functions like @code{CURRENT_TIMESTAMP},
@code{UNIX_TIMESTAMP}, and so forth honor this time zone. Values of
@code{TIMESTAMP} type are also interpreted as values in this time zone. So
now our @code{TIMESTAMP} type behaves similar to Oracle's @code{TIMESTAMP
WITH LOCAL TIME ZONE}. That is, values stored in such a column are
normalized towards UTC and converted back to the current connection time
zone when they are retrieved from such a column.
To set up the tables that store time zone information, see
@ref{Post-installation}.
@item
@strong{Warning: Incompatible change!}
The @code{timezone} system variable has been removed and replaced by
@code{system_time_zone}.
@xref{Server system variables}.
@item
Basic time zone conversion function @code{CONVERT_TZ()} was
added. It assumes that its first argument is a datetime value in the time zone
specified by its second argument and returns the equivalent datetime value in
the time zone specified by its third argument.
@item
@code{CHECK TABLE} now can be killed. It will then mark the table as corrupted.
@xref{KILL,  , @code{KILL}}.
@item
@strong{Warning: Incompatible change!}
C API change: @code{mysql_shutdown()} now requires a second argument.
This is a source-level incompatibility that affects how you compile client
programs; it does not affect the ability of compiled clients to communicate
with older servers.
@xref{mysql_shutdown,  , @code{mysql_shutdown()}}.
@item
@code{OPTIMIZE TABLE} for @code{InnoDB} tables is now mapped to @code{ALTER
TABLE} instead of @code{ANALYZE TABLE}.
@item
@code{sync_frm} is now a settable global variable (not only a startup option).
@item
Added the @code{sync_binlog=N} global variable and startup option, which makes
the MySQL server synchronize its binary log to disk (@code{fdatasync()}) after
every @var{N}th write to the binary log.
@item
Changed the slave SQL thread to print fewer useless error messages (no more
message duplication; no more messages when an error is skipped (because of
@code{slave-skip-errors}).
@item
@code{DROP DATABASE IF EXISTS}, @code{DROP TABLE IF EXISTS}, single-table
@code{DELETE} and single-table @code{UPDATE} are now written to the binary log
even if they changed nothing on the master (for example, even if the
@code{DELETE} matched no row). The old behavior sometimes caused bad surprises
in replication setups.
@item
Replication and @command{mysqlbinlog} now have better support for the case that
the session character set and collation variables are changed within a given
session.
@xref{Replication Features}.
@item
Added @code{--innodb-safe-binlog} server option, which adds consistency
guarantees between the content of @code{InnoDB} tables and the binary log.
@xref{Binary log}.
@item
@code{LIKE} now supports the use of a prepared statement parameter or
delimited constant expression as the argument to @code{ESCAPE} (Bug #4200).
@end itemize

Bugs fixed:
@itemize @bullet
@item
Fixed @code{CREATE DATABASE IF NOT EXISTS} for Win32 which caused an 
error if database existed. (Bug #4378)
@item
Added missing @code{root} account to Windows version of @command{mysqld}.
(Bug #4242)
@item
Fixed bug in prepared @code{EXPLAIN} statement which led to server crash.
(Bug #4271)
@item
Fixed a bug of using parameters in some prepared statements via SQL syntax.
(Bug #4280)
@item
Fixed a bug in @code{MERGE} tables created with @code{INSERT_METHOD=LAST}, that
were not able to report a key number that caused ``Duplicate entry''
error for @code{UNIQUE} key in @code{INSERT}. As a result, error message was
not precise enough (error 1022 instead of error 1062) and
@code{INSERT ... ON DUPLICATE KEY UPDATE} did not work.
(Bug #4008)
@item
Fixed a bug in @code{DELETE} from a table with @code{FULLTEXT} indexes
which under rare circumstances could result in a corrupted table, if words of
different lengths may be considered equal (which is possible in some
collations, for example, in @code{utf8_general_ci} or @code{latin1_german2_ci}.)
(Bug #3808)
@item
Fixed too-early unlocking of tables if we have subquery in @code{HAVING}
clause. (Bug #3984)
@item
Fixed a bug in @command{mysqldump} when it didn't return an error if 
the output device was filled (Bug #1851)
@item
Fixed a bug in client-side conversion of string column to @code{MYSQL_TIME}
application buffer (prepared statements API). (Bug #4030)
@item
Fixed a bug with server crash on attempt to execute a non-prepared 
statement. (Bug #4236)
@item
Fixed a bug with server crash on attempt to prepare a statement with 
character set introducer. (Bug #4105)
@item
Fixed bug which caused different number of warnings to be generated
when bad datetime as string or as number was inserted into @code{DATETIME}
or @code{TIMESTAMP} column. (Bug #2336)
@item
Fixed some byte order bugs with prepared statements on machines with
high-byte-first. (Bug #4173)
@item
Fixed unlikely bug in the range optimizer when using many @code{IN()} queries on
different key parts. (Bug #4157)
@item
Fixed problem with @code{NULL} and derived tables. (Bug #4097)
@item
Fixed wrong @code{UNION} results if display length of fields for numeric
types was set less then real length of values in them. (Bug #4067)
@item
Fixed a bug in @code{mysql_stmt_close()}, which hung up when attempting
to close statement after failed @code{mysql_stmt_fetch()}. (Bug #4079)
@item
Fixed bug of re-execution optimized @code{COUNT(*)}, @code{MAX()} and 
@code{MIN()} functions in prepared statements. (Bug #2687)
@item
Fixed a bug with @code{COUNT(DISTINCT)} performance degradation in cases
like @code{COUNT(DISTINCT a TEXT, b CHAR(1))} (no index used). (Bug #3904) 
@item
Fixed a bug in @code{MATCH ... AGAINST(... IN BOOLEAN MODE)} that
under rare circumstances could cause wrong results
if in the data's collation one byte could match many
(like in @code{utf8_general_ci} or @code{latin1_german2_ci}.)
(Bug #3964)
@item
Fixed a bug in prepared statements protocol, when microseconds part of
@code{MYSQL_TYPE_TIME}/@code{MYSQL_TYPE_DATETIME} columns was not sent to
the client. (Bug #4026) 
@item
Fixed a bug that using @code{--with-charset} with @command{configure} didn't
affect the MySQL client library. (Bug #3990)
@item
Fixed a bug in authentication code that allowed a malicious user
to bypass password verification with specially crafted packets
(using a modified client library).
@item
Fixed bug with wrong result of @code{CONCAT(?, @var{col_name})} in prepared
statements. (Bug #3796)
@item
Fixed potential memory overrun in @code{mysql_real_connect()} (which
required a compromised DNS server and certain operating systems). (Bug #4017)
@item
During the installation process of the server RPM on Linux, @command{mysqld}
was run as the @code{root} system user, and if you had
@code{--log-bin=@var{file_name}}, where the file was located somewhere
outside of the data directory, it created binary log files owned by
@code{root} in this directory that remained owned by @code{root} after the
installation. This is now fixed by starting @command{mysqld} as the
@code{mysql} system user instead. (Bug #4038)
@item
Made @code{DROP DATABASE} honor the value of
@code{lower_case_table_names}. (Bug #4066)
@item
The slave SQL thread refused to replicate @code{INSERT ... SELECT} if it
examined more than 4 billion rows. (Bug #3871)
@item
@command{mysqlbinlog} didn't escape the string content of user variables, and did
not deal well when these variables were in non-ASCII character sets; this is
now fixed by always printing the string content of user variables in
hexadecimal. The character set and collation of the string is now also
printed. (Bug #3875)
@item
Fixed incorrect destruction of expression which led to crash of server on
complex @code{AND}/@code{OR} expressions if query was ignored (either by a
replication server because of @code{--replicate-*-table} rules, or by any MySQL
server because of a syntax error). (Bug #3969, Bug #4494)
@end itemize

@node News-4.1.2, News-4.1.1, News-4.1.3, News-4.1.x
@appendixsubsec Changes in release 4.1.2 (28 May 2004)

Functionality added or changed:
@itemize @bullet
@item
Added the @code{EXAMPLE} storage engine.
@item
The @command{mysqld} Windows server was renamed to @command{mysqld-debug}.
@xref{Windows select server}.
@item
Added @code{Handler_discover} status variable.
@item
Added support for character set conversion and @code{MYSQL_TYPE_BLOB} type
code in prepared statement protocol.
@item
Added explanation of hidden @code{SELECT} of @code{UNION} in output of
@code{EXPLAIN SELECT} statement.
@item
@command{mysql} command-line client now supports multiple @code{-e} options.
(Bug #591)
@item
New @code{myisam_data_pointer_size} system variable.
@xref{Server system variables, @code{myisam_data_pointer_size}}.
@item
The @code{--log-warnings} server option now is enabled by default.
Disable with @code{--skip-log-warnings}.
@item
The @code{--defaults-file=@var{file_name}} option now requires that the filename
must exist (safety fix). (Bug #3413)
@item
@command{mysqld_multi} now creates the log in the directory named by
@code{datadir} (from the @code{[mysqld]} section in @file{my.cnf} or
compiled in), not in @file{/tmp} (vulnerability ID CAN-2004-0388). Thanks to
Christian Hammers from Debian Security Team for reporting this.
@item
@strong{Warning: Incompatible change!}
String comparison now works according to the SQL standard.  Because we have
that @code{'a' = 'a '} then from it must follow that @code{'a' > 'a\t'}.
(The latter was not the case before MySQL 4.1.2.) To implement it, we had to
change how storage engines compare strings internally.  As a side effect, if
you have a table where a @code{CHAR} or @code{VARCHAR} column in some row
has a value with the last character less than @code{ASCII(32)}, you will have
to repair this table. @code{CHECK TABLES} will tell you if this problem
exists. (Bug #3152)
@item
Added support for @code{DEFAULT CURRENT_TIMESTAMP} and for @code{ON UPDATE
CURRENT_TIMESTAMP} specifications for @code{TIMESTAMP} columns. Now you can
explicitly say that a @code{TIMESTAMP} column should be set automatically
to the current timestamp for @code{INSERT} and/or @code{UPDATE} statements, or
even prevent the column from updating automatically. Only one column with such
an auto-set 
feature per table is supported. @code{TIMESTAMP} columns created with earlier 
versions of MySQL behave as before. Behavior of @code{TIMESTAMP} columns that 
were created without explicit specification of default/on as earlier
depends on its position in table: If it is the first @code{TIMESTAMP} column, it will
be treated as having been specified as @code{TIMESTAMP DEFAULT
CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP}.
In other cases, it would be treated as a @code{TIMESTAMP DEFAULT 0} column.
@code{NOW} is supported as an alias for @code{CURRENT_TIMESTAMP}.
@strong{Warning: Incompatible change!} Unlike in previous versions, explicit
specification of default values for @code{TIMESTAMP} column is never ignored
and turns off the auto-set feature (unless you have @code{CURRENT_TIMESTAMP} as
the default).
@item
@strong{Warning: Incompatible change!}
Renamed prepared statements C API functions:
@multitable @columnfractions .30 .70
@item @strong{Old Name}           @tab @strong{New Name}
@item @code{mysql_bind_param()}     @tab @code{mysql_stmt_bind_param()}
@item @code{mysql_bind_result()}    @tab @code{mysql_stmt_bind_result()}
@item @code{mysql_prepare()}        @tab @code{mysql_stmt_prepare()}
@item @code{mysql_execute()}        @tab @code{mysql_stmt_execute()}
@item @code{mysql_fetch()}          @tab @code{mysql_stmt_fetch()}
@item @code{mysql_fetch_column()}   @tab @code{mysql_stmt_fetch_column()}
@item @code{mysql_param_count()}    @tab @code{mysql_stmt_param_count()}
@item @code{mysql_param_result()} @tab @code{mysql_stmt_param_metadata()}
@item @code{mysql_get_metadata()} @tab @code{mysql_stmt_result_metadata()}
@item @code{mysql_send_long_data()} @tab @code{mysql_stmt_send_long_data()}
@end multitable

Now all functions that operate with a @code{MYSQL_STMT} structure begin with
the prefix @code{mysql_stmt_}.
@item
@strong{Warning: Incompatible change!}
The signature of the @code{mysql_stmt_prepare()} function was changed to
@code{int mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query,
unsigned long length)}.
To create a @code{MYSQL_STMT} handle, you 
should use the @code{mysql_stmt_init()} function, not
@code{mysql_stmt_prepare()}.
@item
@code{SHOW GRANTS} with no @code{FOR} clause or with @code{FOR
CURRENT_USER()} shows the privileges for the current session.
@item
The improved character set support introduced in MySQL 4.1.0 for the
@code{MyISAM} and @code{HEAP} storage engines is now available for
@code{InnoDB} as well.
@item
A name of ``Primary'' no longer can be specified as an index name.
(That name is reserved for the @code{PRIMARY KEY} if the table has one.)
(Bug #856)
@item
MySQL now issues a warning when a @code{SET} or @code{ENUM} column with
duplicate values in the list is created. (Bug #1427)
@item
Now @code{SQL_SELECT_LIMIT} variable has no influence on subqueries.
(Bug #2600)
@item
@code{UNHEX()} function implemented.
@xref{String functions, , @code{UNHEX(str)}}.
@item
The @command{mysql} command-line client no longer stores in the history file
multiple copies of identical queries that are run consecutively.
@item
Multi-line statements in the @code{mysql} command-line client now are stored
in the history file as a single line. 
@item
@code{UUID()} function implemented. Note that it does not work with replication
yet.
@xref{Miscellaneous functions, , @code{UUID()}}.
@item
Prepared statements with all types of subqueries fixed.
@item
MySQL now supports up to 64 indexes per table.
@item
@code{MyISAM} tables now support keys up to 1000 bytes long.
@item
@code{MyISAM} and @code{InnoDB} tables now support index prefix lengths up
to 1000 bytes long.
@item
If you try to create a key with a key part that is too long, and it is safe
to auto-truncate it to a smaller length, MySQL now does so.  A warning is
generated, rather than an error.
@item
The @code{ft_boolean_syntax} variable now can be changed while the server is
running.
@xref{Server system variables}.
@item
@code{REVOKE ALL PRIVILEGES, GRANT FROM user_list}
is changed to a more consistent
@code{REVOKE ALL PRIVILEGES, GRANT OPTION FROM user_list}. (Bug #2642)
@item
Internal string-to-number conversion now supports only SQL:2003 compatible
syntax for numbers. In particular, @code{'0x10'+0} will not work anymore.
(Actually, it worked only on some systems before, such as Linux. It
did not work on others, such as FreeBSD or Solaris. Making these queries
OS-independent was the goal of this change.) Use @code{CONV()} to convert
hexadecimal numbers to decimal. E.g. @code{CONV(MID('0x10',3),16,10)+0}.
@item
@command{mysqlhotcopy} now works on NetWare.
@item
@code{ALTER TABLE DROP PRIMARY KEY} no longer drops the first @code{UNIQUE}
index if there is no primary index. (Bug #2361)
@item
Added @code{latin1_spanish_ci} (Modern Spanish) collation for the @code{latin1}
character set.
@item
Added the @code{ENGINE} table option as a synonym for the @code{TYPE} option
for @code{CREATE TABLE} and @code{ALTER TABLE}.
@item
Added the @code{--default-storage-engine} server option as a synonym for
@code{--default-table-type}.
@item
Added the @code{storage_engine} system variable as a synonym for
@code{table_type}.
@item
@strong{Warning: Incompatible change!}
The @code{Type} output column for @code{SHOW TABLE STATUS} now is labeled
@code{Engine}.
@item
Added @code{init_connect} and @code{init_slave} system variables.
The values should be SQL statements to be executed when each client
connects or each time a slave's SQL thread starts, respectively.
@item
C API enhancement:
@code{SERVER_QUERY_NO_INDEX_USED} and
@code{SERVER_QUERY_NO_GOOD_INDEX_USED} flags are now set
in the @code{server_status} field of the @code{MYSQL} structure.
It is these flags that make the query to be logged as slow 
if @command{mysqld} was started with @code{--log-slow-queries
--log-queries-not-using-indexes}.
@item
For replication of @code{MEMORY} (@code{HEAP}) tables: Made the master
automatically write a @code{DELETE FROM} statement to its binary log when a
@code{MEMORY} table is opened for the first time since master's startup.
This is for the case where the slave has replicated a non-empty
@code{MEMORY} table, then the master is shut down and restarted: the table
is now empty on master; the @code{DELETE FROM} empties it on slave too. Note
that even with this fix, between the master's restart and the first use of
the table on master, the slave still has out-of-date data in the table. But
if you use the @code{init-file} option to populate the @code{MEMORY} table
on the master at startup, it ensures that the failing time interval is zero.
(Bug #2477)
@item
When a session having open temporary tables terminates, the statement
automatically written to the binary log is now @code{DROP TEMPORARY TABLE IF
EXISTS} instead of @code{DROP TEMPORARY TABLE}, for more robustness.
@item
The MySQL server now returns an error if @code{SET SQL_LOG_BIN} or @code{SET
SQL_LOG_UPDATE} is issued by a user without the @code{SUPER} privilege (in
previous versions it just silently ignored the statement in this case).
@item
Changed that when the MySQL server has binary logging disabled (that is,
no @code{--log-bin} option was used), then no transaction binary log cache
is allocated for connections. This should save @code{binlog_cache_size}
bytes of memory (32KB by default) for every connection.
@item
Added @code{Binlog_cache_use} and @code{Binlog_cache_disk_use} status
variables that count the number of transactions that used transaction binary
log and that had to flush this temporary binary log to disk instead of using
only the in-memory buffer. They can be used for tuning the
@code{binlog_cache_size} system variable.
@item
Added option @code{--replicate-same-server-id}.
@item
The Mac OS X Startup Item has been moved from the directory
@file{/Library/StartupItems/MySQL} to @file{/Library/StartupItems/MySQLCOM}
to avoid a file name collision with the MySQL Startup Item installed with
Mac OS X Server. @xref{Mac OS X}.
@item
Added option @code{--to-last-log} to @command{mysqlbinlog}, for use in conjunction
with @code{--read-from-remote-server}.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Fixed check of @code{EXPLAIN} of @code{UNION}. (Bug #3639)
@item
Fixed a bug in a query that used @code{DISTINCT} and @code{ORDER BY}
by column's real name, while the column had an alias, specified in
@code{SELECT} clause. (Bug #3681)
@item
@command{mysqld} could crash when a table was altered and used at the same time.
This was a 4.1.2-specific bug. (Bug #3643).
@item
Fixed bug when using impossible @code{WHERE} with @code{PROCEDURE ANALYSE()}.
(Bug #2238).
@item
Fixed security problem in new authentication where password was not checked
for changed @code{GRANT} accounts until @code{FLUSH PRIVILEGES} was executed.
(Bug #3404)
@item
Fixed crash of @code{GROUP_CONCAT()} on expression with @code{ORDER BY}
and external @code{ORDER BY} in a query. (Bug #3752)
@item
Fixed a bug in @code{ALL}/@code{SOME} subqueries in case of optimization (key
field present in subquery). (Bug #3646)
@item
Fixed a bug in @code{SHOW GRANTS} and @code{EXPLAIN SELECT} character
set conversion.  (Bug #3403)
@item
Prepare statements parameter do not cause error message as fields used in
select list but not included in @code{ORDER BY} list.
@item
@code{UNION} statements did not consult @code{SQL_SELECT_LIMIT} value when
set. This is now fixed properly, which means that this limit is applied
to the top level query, unless @code{LIMIT} for entire @code{UNION} is
used. 
@item
Fixed a bug in multiple-table @code{UPDATE} statements that resulted in an
error when one of the tables was not updated but was used in the nested query,
contained therein.
@item
Fixed @code{mysql_stmt_send_long_data()} behavior on second execution of 
prepared statement and in case when long data had zero length. (Bug #1664)
@item
Fixed crash on second execution of prepared statement with @code{UNION}.
(Bug #3577)
@item
Fixed incorrect results of aggregate functions in subquery with empty result
set. (Bug #3505)
@item
You can now call @code{mysql_stmt_attr_set(..., STMT_ATTR_UPDATE_MAX_LENGTH)}
to tell the client library to update @code{MYSQL_FIELD->max_length} when
doing @code{mysql_stmt_store_result()}. (Bug #1647).
@item
Added support for unsigned integer types to prepared statement API
(Bug #3035).
@item
Fixed crash in prepared statements when subquery in the @code{FROM}
clause with parameter used. (Bug #3020)
@item
Fixed unknown error when negative value bind to unsigned. (Bug #3223)
@item
Fixed aggregate function in prepared statements. (Bug #3360)
@item
Incorrect error message when wrong table used in multiple-table @code{DELETE}
statement in prepared statements. (Bug #3411)
@item
Requiring @code{UPDATE} privilege for tables which will not be updated in
multiple-table @code{UPDATE} statement in prepared statements.
@item
Fixed prepared statement support for @code{INSERT}, @code{REPLACE},
@code{CREATE}, @code{DELETE}, @code{SELECT}, @code{DO}, @code{SET} and
@code{SHOW}. All other commands are prohibited via prepared statement
interface. (Bug #3398, Bug #3406, Bug #2811)
@item
Fixed a lot of bugs in @code{GROUP_CONCAT()}. (Bug #2695, Bug #3381, Bug #3319)
@item
Added optimization that allows for prepared statements using a large number of 
tables or tables with a large number of columns to be re-executed significantly 
faster. (Bug #2050)
@item
Fixed bug that caused execution of prepared statements to fail then table
that this statement were using left table cache. This bug showed up as if
this prepared statement used random garbage as column names or as server
crashes. (Bug #3307)
@item
Fixed a problem resulting from setting the @code{character_set_results}
variable to @code{NULL}.
(Bug #3296)
@item
Fixed query cache statistics.
@item
Fixed bug in @code{ANALYZE TABLE} on a @code{BDB} table inside a transaction
that hangs server thread. (Bug #2342)
@item
Fixed a symlink vulnerability in @file{mysqlbug} script. (Bug #3284)
@item
Fixed a bug in parallel repair
(@command{myisamchk -p}, @code{myisam_repair_threads});
sometimes the repair process failed to repair a table. (Bug #1334)
@item
A query that uses both @code{UNION [DISTINCT]} and @code{UNION ALL}
now works correctly. (Bug #1428)
@item
Table default character set affects @code{LONGBLOB} columns. (Bug #2821)
@item
@code{CONCAT_WS()} makes the server die in case of illegal mix of collations. (Bug #3087)
@item
UTF8 charset breaks joins with mixed column/string constant. (Bug #2959)
@item 
Fixed @code{DROP DATABASE} to report number of tables deleted.
@item 
Fixed memory leak in the client library when statement handle was freed 
on closed connection (call to @code{mysql_stmt_close} after
@code{mysql_close}). (Bug #3073)
@item
Fixed server segfaults when processing malformed prepared statements
commands. (Bug #2795, Bug #2274)
@item
Fixed using subqueries with @code{OR} and @code{AND} functions. (Bug #2838)
@item
Fixed comparison of tables/database names with 
@code{--lower_case_table_names} option. (Bug #2880)
@item
Removed try to check @code{NULL} if index built on column where @code{NULL}
is impossible in @code{IN} subquery optimization. (Bug #2393)
@item
Fixed incorrect parsing of subqueries in the @code{FROM} clause. (Bug #2421)
@item
Fixed processing of @code{RAND()} in subqueries with static tables. (bug #2645)
@item
Fixed bug with quoting of table names in @command{mysqldump} for 
various values of @code{sql_mode} of server. (Bug #2591)
@item
Fixed bug with storing values that are out of range for @code{DOUBLE} and
@code{FLOAT} columns.
(Bug #2082)
@item
Fixed bug with compiling @code{--with-pstack} with binutils 2.13.90. (Bug #1661)
@item
Fixed a bug in the @code{GRANT} system. When a password was assigned to an
account at the global level and then privileges were granted at the database
level (without specifying any password), the existing password was replaced
temporarily in memory until the next @code{FLUSH PRIVILEGES} operation or
the server was restarted. (Bug #2953)
@item
Fixed a bug in full-text search on multi-byte character set (such as UTF8)
that appeared when a search word was shorter than a matching word from
the index (for example, searching for ``Uppsala'' when table data contain
``Upps@ringaccent{a}la''). (Bug #3011)
@item
Fixed a bug that made @code{Max_used_connections} to be less than
the actual maximum number of connections in use simultaneously.
@item
Fixed calculation of @code{Index_length} in @code{HEAP} table status for
@code{BTREE} indexes. (Bug #2719)
@item
Fixed @code{mysql_stmt_affected_rows()} call to always return number of rows 
affected by given statement. (Bug #2247)
@item
Fixed crash in @code{MATCH ... AGAINST()} on a phrase search operator with
a missing closing double quote. (Bug #2708)
@item
Fixed output of @command{mysqldump --tab}. (Bug #2705)
@item
Fix for a bug in @code{UNION} operations that prevented proper handling of
@code{NULL} columns. This happened only if a column in the first
@code{SELECT} node was @code{NOT NULL}. (Bug #2508)
@item
Fix for a bug in @code{UNION} operations with @code{InnoDB} storage engine,
when some columns from one table were used in one @code{SELECT} statement and
some were used in another @code{SELECT} statement. (Bug #2552)
@item 
Fixed a few years old bug in the range optimizer that
caused a segmentation fault on some very rare queries. (Bug #2698)
@item
Fixed bug with @code{SHOW CREATE TABLE ...} which didn't properly double 
quotes. (Bug #2593)
@item
Queries with subqueries in @code{FROM} clause locks all tables at once for now.
This also fixed bugs in @code{EXPLAIN} of subqueries
in @code{FROM} output. (Bug #2120)
@item
Fixed bug with @command{mysqldump} not quoting ``tricky'' names correctly.
(Bug #2592)
@item 
Fix for a bug that prevented table / column privileges from
being loaded on startup. (Bug #2546)
@item
Fixed bug in replication with @code{CREATE TABLE ... LIKE ...} that resulted
in a statement not being written to the binary log. (Bug #2557)
@item
Fixed memory leak in @code{INSERT ... ON DUPLICATE KEY UPDATE ...}. 
(Bug #2438)
@item
Fixed bug in the parser, making the syntax @code{CONVERT(@var{expr},@var{type})}
legal again.
@item
Fixed parsing of short-form IP addresses in @code{INET_ATON()}. (Bug #2310)
@item
Fixed a bug in @code{CREATE ... SELECT} that sometimes caused a
string column with a multi-byte character set (such as @code{utf8}) to have
insufficient length to hold the data.
@item
Fixed a rare table corruption on adding data (@code{INSERT}, @code{REPLACE},
@code{UPDATE}, etc. but not @code{DELETE}) to a @code{FULLTEXT} index.
(Bug #2417)
@item
Compile the @code{MySQL-client} RPM package against @code{libreadline} instead
of @code{libedit}. (Bug #2289)
@item
Fix for a crashing bug that was caused by not setting
@code{vio_timeout()} virtual function for all protocols. This bug occurred on
Windows. (Bug #2025)
@item
Fix for a bug that caused @command{mysql} client program to erroneously
cache the value of the current database. (Bug #2025)
@item
Fix for a bug that caused client/server communication to be
broken when @code{mysql_set_server_option()} or
@code{mysql_get_server_option()} were invoked.
(Bug #2207)
@item
Fix for a bug that caused wong results when @code{CAST()} was
applied on @code{NULL} to signed or unsigned integer column.
(Bug #2219)
@item
Fix for a crashing bug that occurred in the @command{mysql} client program when
database name was longer then expected.
(Bug #2221)
@item
Fixed a bug in @code{CHECK TABLE} that sometimes
resulted in a spurious error @code{Found key at page ... that points to record
outside datafile} for a table with a @code{FULLTEXT} index. (Bug #2190)
@item
Fixed bug in @code{GRANT} with table-level privilege handling. (Bug #2178)
@item
Fixed bug in @code{ORDER BY} on a small column. (Bug #2147)
@item
Fixed a bug with the @code{INTERVAL()} function when 8 or more 
comparison arguments are provided. (Bug #1561)
@item
Packaging:
Fixed a bug in the Mac OS PKG @code{postinstall} script
(@command{mysql_install_db} was called with an obsolete argument).
@item
Packaging:
Added missing file @file{mysql_create_system_tables} to the server RPM
package. This bug was fixed for the 4.1.1 RPMs by updating the MySQL-server
RPM from @code{MySQL-server-4.1.1-0} to @code{MySQL-server-4.1.1-1}. The
other RPMs were not affected by this change.
@item
Fixed a bug in @command{myisamchk} and @code{CHECK TABLE} that sometimes
resulted in a spurious error @code{Found key at page ... that points to record
outside datafile} for a table with a @code{FULLTEXT} index. (Bug #1977)
@item
Fixed a hang in full-text indexing of strings in multi-byte (all besides
@code{utf8}) charsets. (Bug #2065)
@item
Fixed a crash in full-text indexing of UTF8 data. (Bug #2033)
@item
Replication:
a rare race condition in the slave SQL thread that could lead to an
incorrect complaint that the relay log is corrupted. (Bug #2011)
@item
Replication:
If a client connects to a slave server and issues an administrative
statement for a table (for example, @code{OPTIMIZE TABLE} or @code{REPAIR
TABLE}), this could sometimes stop the slave SQL thread. This does not lead
to any corruption, but you must use @code{START SLAVE} to get replication
going again. (Bug #1858)
@item
Replication:
in the slave SQL thread, a multiple-table @code{UPDATE} could produce an
incorrect complaint that some record was not found in one table, if the
@code{UPDATE} was preceded by a @code{INSERT ... SELECT}. (Bug #1701)
@item
Replication: sometimes the master gets a non-fatal error during the execution
of a statement but finally the statements succeeds (for example, a write to a
@code{MyISAM} table first receives "no space left on device" but is able to finally
complete, @pxref{Full disk}); the bug was that the master forgot to reset the
error code to 0 after success, so the error code got into its binary log, thus
making the slave giving false alarms like "did not get the same error as on
master". (Bug #2083)
@item
Removed a misleading "check permissions on master.info" from a replication
error message, because the cause of the problem could be different from
permissions. (Bug #2121)
@item
Fixed a crash when the replication slave was unable to create the first relay
log. (Bug #2145)
@item
@code{ALTER DATABASE} caused the client to hang if the database did not
exist. (Bug #2333)
@item
Multiple-table @code{DELETE} statements were never replicated by the slave if
there were any @code{--replicate-*-table} options. (Bug #2527)
@item
Fixed bug in @code{ALTER TABLE RENAME}, when rename to the table with
the same name in another database silently dropped destination table if
it existed. (Bug #2628)
@item
The MySQL server did not report any error if a statement (submitted through
@code{mysql_real_query()} or @code{mysql_stmt_prepare()}) was terminated
by garbage characters. This can happen if you pass a wrong @code{length}
parameter to these functions. The result was that the
garbage characters were written into the binary log. (Bug #2703)
@item
Fixed bug in client library that caused @code{mysql_stmt_fetch} and 
@code{mysql_stmt_store_result()} to hang if they were called without
prior call of @code{mysql_stmt_execute()}. Now they give an error instead. 
(Bug #2248)
@item
Made clearer the error message that one gets when an update is refused because
of the @code{--read-only} option. (Bug #2757)
@item
Fixed that @code{--replicate-wild-*-table} rules apply to @code{ALTER DATABASE}
when the table pattern is @code{%}, as is already the case for @code{CREATE
DATABASE} and @code{DROP DATABASE}. (Bug #3000)
@item
Fixed that when a @code{Rotate} event is found by the slave SQL thread in the
middle of a transaction, the value of @code{Relay_Log_Pos} in @code{SHOW SLAVE
STATUS} remains correct. (Bug #3017)
@item
Corrected the master's binary log position that @code{InnoDB} reports when it is doing a
crash recovery on a slave server. (Bug #3015)
@item
Changed the column @code{Seconds_Behind_Master} in @code{SHOW SLAVE STATUS} to
never show a value of @minus{}1. (Bug #2826)
@item
Changed that when a @code{DROP TEMPORARY TABLE} statement is automatically
written to the binary log when a session ends, the statement is recorded with an
error code of value zero (this ensures that killing a @code{SELECT} on the
master does not result in a superfluous error on the slave). (Bug #3063)
@item
Changed that when a thread handling @code{INSERT DELAYED} (also known as a
@code{delayed_insert} thread) is killed, its statements are recorded with an
error code of value zero (killing such a thread does not endanger
replication, so we thus avoid a superfluous error on the slave). (Bug #3081)
@item
Fixed deadlock when two @code{START SLAVE} commands were run at the same
time. (Bug #2921)
@item
Fixed that a statement never triggers a superfluous error on the slave, if it
must be excluded given the @code{--replicate-*} options. The bug was that if the
statement had been killed on the master, the slave would stop. (Bug #2983)
@item
The @code{--local-load} option of @command{mysqlbinlog} now requires an argument.
@item
Fixed a segmentation fault when running @code{LOAD DATA FROM MASTER} after
@code{RESET SLAVE}. (Bug #2922)
@item
@command{mysqlbinlog --read-from-remote-server} read all binary logs following the
one that was requested.  It now stops at the end of the requested file, the
same as it does when reading a local binary log. There is an option
@code{--to-last-log} to get the old behavior. (Bug #3204)
@item
Fixed @command{mysqlbinlog --read-from-remote-server} to print the exact
positions of events in the "at #" lines. (Bug #3214)
@item
Fixed a rare error condition that caused the slave SQL thread spuriously
to print the message @code{Binlog has bad magic number} and stop when it
was not necessary to do so.  (Bug #3401)
@item
Fixed the @code{Exec_master_log_pos} column and its disk image in the
@file{relay-log.info} file to be correct if the master had version 3.23. (The
value was too big by six bytes.) This bug does not exist in MySQL 5.0.
(Bug #3400)
@item
Fixed @command{mysqlbinlog} not to forget to print a @code{USE} statement
under rare circumstances where the binary log contained a @code{LOAD DATA
INFILE} statement. (Bug #3415)
@item
Fixed a memory corruption when replicating a @code{LOAD DATA INFILE} when the
master had version 3.23. Some smaller problems remain in this setup,
@xref{Replication Features}. (Bug #3422)
@item
Multiple-table @code{DELETE} statements were always replicated by the slave if
there were some @code{--replicate-*-ignore-table} options and no
@code{--replicate-*-do-table} options. (Bug #3461)
@item
Fixed a crash of the MySQL slave server when it was built with
@code{--with-debug} and replicating itself. (Bug #3568)
@item
Fixed that in some replication error messages, a very long query caused the rest
of the message to be invisible (truncated), by putting the query last in the
message. (Bug #3357)
@item
Fixed a bug in @code{REPAIR TABLE} that resulted sometimes in a corrupted
table, if the table contained @code{FULLTEXT} indexes and many words
of different lengths that are considered equal (which is possible in
certain collations, such as @code{latin1_german2_ci}
or @code{utf8_general_ci}).
(Bug #3835)
@item
Fixed a crash of @command{mysqld} that was started with binary
logging disabled, but with a non-zero value for the @code{expire_logs_days}
system variable.
(Bug #3807)
@item
If @code{server-id} was not set using startup options but with @code{SET
GLOBAL}, the replication slave still complained that it was not set. (Bug
#3829)
@end itemize

@node News-4.1.1, News-4.1.0, News-4.1.2, News-4.1.x
@appendixsubsec Changes in release 4.1.1 (01 Dec 2003)

This release includes all fixes in MySQL 4.0.16 and most of the fixes
in MySQL 4.0.17.

Functionality added or changed:
@itemize @bullet
@item
Table aliases are not case sensitive if @code{lower_case_table_names} is
non-zero.
@item
The @code{--old-protocol} option for @command{mysqld} is no longer supported
and has been removed.
@item
Renamed @code{bdb_version} system variable to @code{version_bdb}.
@item
New @code{CHECKSUM TABLE} statement for reporting table checksum values.
@item
Added @code{character_set_client}, @code{character_set_connection},
@code{character_set_database}, @code{character_set_results},
@code{character_set_server}, @code{character_set_system},
@code{collation_connection}, @code{collation_database}, and
@code{collation_server} system variables to provide information about
character sets and collations.
@item
It is now possible to create multiple key caches, assign table indexes to
particular caches, and to preload indexes into caches.
@xref{CACHE INDEX,  , @code{CACHE INDEX}}.
@xref{LOAD INDEX,  , @code{LOAD INDEX}}.
Structured system
variables are introduced as a means of grouping related key cache parameters.
@xref{Structured System Variables}.
@item
Added @code{preload_buffer_size} system variable.
@item
New @code{COERCIBILITY()} function to return the collation coercibility of a
string.
@item
The @code{--quote-names} option for @command{mysqldump} now is enabled
by default.
@item
@command{mysqldump} now includes a statement in the dump output to set
@code{FOREIGN_KEY_CHECKS} to 0 to avoid problems with tables having to be
reloaded in a particular order when the dump is reloaded. The existing
@code{FOREIGN_KEY_CHECKS} value is saved and restored.
@item
@strong{Important note:} If you upgrade to @code{InnoDB}-4.1.1 or higher,
you cannot downgrade to a version lower than 4.1.1
any more! That is because earlier versions of @code{InnoDB} are not aware of
multiple tablespaces.
@item
One can revoke all privileges from a user with
@code{REVOKE ALL PRIVILEGES, GRANT FROM user_list}.
@item
Added @code{IGNORE} option for @code{DELETE} statement.
@item
The MySQL source distribution now also includes the MySQL Internals
Manual @file{internals.texi}.
@item
Added @code{mysql_set_server_option()} C API client function to allow multiple
statement handling in the server to be enabled or disabled.
@item
The @code{mysql_next_result()} C API function now returns @code{-1} if there
are no more result sets.
@item
Renamed @code{CLIENT_MULTI_QUERIES} connect option flag to
@code{CLIENT_MULTI_STATEMENTS}. To allow for a transition period, the old
option will continue to be recognized for a while.
@item
Require @code{DEFAULT} before table and database default character set.
This enables us to use @code{ALTER TABLE @var{tbl_name} ... CHARACTER SET=...}
to change the character set for all @code{CHAR}, @code{VARCHAR}, and
@code{TEXT} columns in a table.
@item
Added @code{MATCH ... AGAINST( ... WITH QUERY EXPANSION)} and the
@code{ft_query_expansion_limit} system variable.
@item
Removed unused @code{ft_max_word_len_for_sort} system variable.
@item
Removed unused @code{ft_max_word_len_for_sort} variable from @command{myisamchk}.
@item
Full-text search now supports multi-byte character sets and the Unicode
@code{utf8} character set. (The Unicode @code{ucs2} character set is not
yet supported.)
@item
Phrase search in @code{MATCH ... AGAINST ( ... IN BOOLEAN MODE)} no longer
matches partial words.
@item
Added aggregate function @code{BIT_XOR()} for bitwise XOR operations.
@item
Replication over SSL now works.
@item
The @code{START SLAVE} statement now supports an @code{UNTIL} clause for
specifying that the slave SQL thread should be started but run only until it
reaches a given position in the master's binary logs or in the slave's relay logs.
@item
Produce warnings even for single-row @code{INSERT} statements, not just for
multiple-row @code{INSERT} statements. Previously, it was necessary to set
@code{SQL_WARNINGS=1} to generate warnings for single-row statements.
@item
Added @code{delimiter} (@code{\d}) command to the @command{mysql} command-line
client for changing the statement delimiter (terminator).
The default delimiter is semicolon.
@item
@code{CHAR}, @code{VARCHAR}, and @code{TEXT} columns now have lengths measured
in characters rather than in bytes.
The character size depends on the column's character set.
This means, for example, that a @code{CHAR(@var{n})} column
for a multi-byte character set will take more storage than before.
Similarly, index values on such columns are measured in characters, not bytes.
@item
@code{LIMIT} no longer accepts negative arguments
(they used to be treated as very big positive numbers before).
@item
The @code{DATABASE()} function now returns @code{NULL} rather than the empty
string if there is no database selected.
@item
Added @code{--sql-mode=NO_AUTO_VALUE_ON_ZERO} option to suppress the usual
behavior of generating the next sequence number when zero is stored in
an @code{AUTO_INCREMENT} column. With this mode enabled, zero is stored as
zero; only storing @code{NULL} generates a sequence number.
@item
@strong{Warning: Incompatible change!}
Client authentication now is based on 41-byte passwords in the
@code{user} table, not 45-byte passwords as in 4.1.0.
Any 45-byte passwords created for 4.1.0 must be reset after running the
@command{mysql_fix_privilege_tables} script.
@item
Added @code{secure_auth} global server system variable and @code{--secure-auth}
server option that disallow authentication for accounts that have old
(pre-4.1.1) passwords.
@item
Added @code{--secure-auth} option to @command{mysql} command-line client. If this
option is set, the client refuses to send passwords in old (pre-4.1.1) format.
@item
@strong{Warning: Incompatible change!}
Renamed the C API @code{mysql_prepare_result()} function to
@code{mysql_get_metadata()} as the old name was confusing.
@item
Added @code{DROP USER '@var{user_name}'@@'@var{host_name}'} statement to drop an account
that has no privileges.
@item
The interface to aggregated UDF functions has changed a bit. You must now
declare a @code{xxx_clear()} function for each aggregate function @code{XXX()}.
@item
Added new @code{ADDTIME()}, @code{DATE()}, @code{DATEDIFF()}, @code{LAST_DAY()},
@code{MAKEDATE()}, @code{MAKETIME()}, @code{MICROSECOND()}, @code{SUBTIME()},
@code{TIME()}, @code{TIMEDIFF()}, @code{TIMESTAMP()}, @code{UTC_DATE()},
@code{UTC_TIME()}, @code{UTC_TIMESTAMP()}, and @code{WEEKOFYEAR()}
functions.
@item
Added new syntax for @code{ADDDATE()} and @code{SUBDATE()}.
The second argument now may be a number representing the number of days to
be added to or subtracted from the first date argument.
@item
Added new @code{type} values @code{DAY_MICROSECOND},
@code{HOUR_MICROSECOND}, @code{MINUTE_MICROSECOND},
@code{SECOND_MICROSECOND}, and @code{MICROSECOND}
for @code{DATE_ADD()}, @code{DATE_SUB()}, and @code{EXTRACT()}.
@item
Added new @code{%f} microseconds format specifier for @code{DATE_FORMAT()} and
@code{TIME_FORMAT()}.
@item
All queries in which at least one @code{SELECT} does not use indexes properly
now are written to the slow query log when long log format is used.  
@item
It is now possible to create a @code{MERGE} table from @code{MyISAM} tables in
different databases. Formerly, all the @code{MyISAM} tables had to be in the
same database, and the @code{MERGE} table had to be created in that database
as well.
@item
Added new @code{COMPRESS()}, @code{UNCOMPRESS()}, and
@code{UNCOMPRESSED_LENGTH()} functions.
@item
When using @code{SET sql_mode='mode'} for a complex mode (like @code{ANSI}), we
now update the @code{sql_mode} variable to include all the individual options
implied by the complex mode.
@item
Added the OLAP (On-Line Analytical Processing) function @code{ROLLUP}, which
provides summary rows for each @code{GROUP BY} level.
@item
Added @code{SQLSTATE} codes for all server errors.
@item
Added @code{mysql_sqlstate()} and @code{mysql_stmt_sqlstate()} C API client
functions that return the @code{SQLSTATE} error code for the last error.
@item
@code{TIME} columns with hour values greater than 24 were returned incorrectly
to the client.
@item
@code{ANALYZE TABLE}, @code{OPTIMIZE TABLE}, @code{REPAIR TABLE}, and @code{FLUSH} statements
are now stored in the binary log and thus replicated to slaves.
This logging does not occur if the optional @code{NO_WRITE_TO_BINLOG} keyword 
(or its alias @code{LOCAL}) is given.  Exceptions are that
@code{FLUSH LOGS}, @code{FLUSH MASTER}, @code{FLUSH SLAVE}, and
@code{FLUSH TABLES WITH READ LOCK} are not logged in any case.
For a syntax example, see @ref{FLUSH, , @code{FLUSH}}.
@item
New global system variable @code{relay_log_purge} to enable or disable automatic
relay log purging.
@item
@code{LOAD DATA} now produces warnings that can be fetched with
@code{SHOW WARNINGS}.
@item
Added support for syntax @code{CREATE TABLE table2 (LIKE table1)}
that creates an empty table @code{table2} with a definition that is
exactly the same as @code{table1}, including any indexes.
@item
@code{CREATE TABLE @var{tbl_name} (...) TYPE=@var{storage_engine}} now generates a
warning if the named storage engine is not available. The table is still
created as a @code{MyISAM} table, as before.
@item
Most subqueries are now much faster than before.
@item
Added @code{PURGE BINARY LOGS} as an alias for @code{PURGE MASTER LOGS}.
@item
Disabled the @code{PURGE LOGS} statement that was added in version 4.1.0.
The statement now should be issued as @code{PURGE MASTER LOGS} or
@code{PURGE BINARY LOGS}.
@item
Added @code{SHOW BDB LOGS} as an alias for @code{SHOW LOGS}.
@item
Added @code{SHOW MASTER LOGS} as an alias for @code{SHOW BINARY LOGS}.
(In 4.1.0, @code{SHOW MASTER LOGS} was renamed to @code{SHOW BINARY LOGS}.
Now you can use either one.)
@item
Added @code{Slave_IO_State} and @code{Seconds_Behind_Master} columns
to the output of @code{SHOW SLAVE STATUS}.
@code{Slave_IO_State} indicates the state of the slave I/O thread, and
@code{Seconds_Behind_Master} indicates the number of seconds by
which the slave is late compared to the master.
@item
The @code{--lower-case-table-names=1} server option now also makes aliases case
insensitive. (Bug #534)
@item
Changed that the relay log is flushed to disk by the slave I/O thread every
time it reads a relay log event. This reduces the risk of losing some part of
the relay log in case of brutal crash.
@item
The @code{DELAYED} keyword in @code{INSERT DELAYED} no longer causes an
error for @code{InnoDB} tables. Now it is silently ignored.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Fixed @command{mysql} parser not to erroneously interpret @samp{;} character
within @code{/* ... */} comment as statement terminator.
@item
Fixed merging types and length of result set columns for @code{UNION}
operations. The types and lengths now are determined taking into
account values for all @code{SELECT} statements in the @code{UNION},
not just the first @code{SELECT}.
@item
Fixed a bug in privilege handling that caused connections from
certain IP addresses to be assigned incorrect database-level privileges.
A connection could be assigned the database privileges of the
previous successful authentication from one of those IP addresses,
even if the IP address username and database name were different. (Bug #1636)
@item
Error-handling functions were not called properly when an error resulted
from @code{[CREATE | REPLACE| INSERT] ... SELECT} statements.
@item
@code{HASH}, @code{BTREE}, @code{RTREE}, @code{ERRORS}, and
@code{WARNINGS} no longer are reserved words. (Bug #724)
@item
Fix for bug in @code{ROLLUP} when all tables were @code{const} tables.
(Bug #714)
@item
Fixed a bug in @code{UNION} that prohibited @code{NULL} values from being
inserted into result set columns where the first @code{SELECT} of the
@code{UNION} retrieved @code{NOT NULL} columns. The type and max_length
of the result column is now defined based on all @code{UNION} parts.
@item
Fixed name resolution of columns of reduced subqueries in unions. (Bug #745)
@item
Fixed memory overrun in subqueries in select list with @code{WHERE} clause
bigger than outer query @code{WHERE} clause. (Bug #726)
@item
Fixed a bug that caused @code{MyISAM} tables with @code{FULLTEXT} indexes
created in 4.0.x to be unreadable in 4.1.x.
@item
Fixed a data loss bug in @code{REPAIR TABLE ... USE_FRM} when used
with tables
that contained @code{TIMESTAMP} columns and were created in 4.0.x.
@item
Fixed reduced subquery processing in @code{ORDER BY}/@code{GROUP BY}
clauses. (Bug #442)
@item
Fixed name resolution of outer columns of subquery in
@code{INSERT}/@code{REPLACE} statements. (Bug #446)
@item
Fixed bug in marking columns of reduced subqueries. (Bug #679)
@item
Fixed a bug that made @code{CREATE FULLTEXT INDEX} syntax illegal.
@item
Fixed a crash when a @code{SELECT} that required a temporary table
(marked by @code{Using temporary} in @code{EXPLAIN} output)
was used as a derived table in @code{EXPLAIN} command. (Bug #251)
@item
Fixed a rare table corruption bug in @code{DELETE}
from a big table with
a @strong{new} (created by MySQL-4.1) full-text index.
@item
@code{LAST_INSERT_ID()} now returns 0 if the last @code{INSERT} statement
didn't insert any rows.
@item
Fixed missing last character in function output. (Bug #447)
@item
Fixed a rare replication bug when a transaction spanned two or more
relay logs, and the slave was stopped while executing the part
of the transaction that was in the second or later relay log. Then
replication would resume at the beginning of the second or later
relay log, which was incorrect. (It should resume at @code{BEGIN}, in the
first relay log.) (Bug #53)
@item
@code{CONNECTION_ID()} now is properly replicated. (Bug #177)
@item
The new @code{PASSWORD()} function in 4.1 is now properly replicated.
(Bug #344)
@item
Fixed a bug with double freed memory.
@item
Fixed a crashing bug in @code{UNION} operations that involved temporary tables.
@item
Fixed a crashing bug in @code{DERIVED TABLES} when @code{EXPLAIN} is
used on a @code{DERIVED TABLES} with a join.
@item
Fixed a crashing bug in @code{DELETE} with @code{ORDER BY} and
@code{LIMIT} caused by an uninitialized array of reference pointers.
@item
Fixed a bug in the @code{USER()} function caused by an error in the size of
the allocated string.
@item
Fixed a crashing bug when attempting to create a table containing a spatial
(GIS) column with a storage engine that does not support spatial types. 
@item
Fixed a crashing bug in @code{UNION} caused by the empty select list and
a non-existent column being used in some of the individual @code{SELECT}
statements.
@item
Fixed a replication bug with a 3.23 master and a 4.0 slave: The
slave lost the replicated temporary tables if @code{FLUSH LOGS} was
issued on the master. (Bug #254)
@item
Fixed a security bug: A server compiled without SSL support still allowed
connections by users who had the @code{REQUIRE SSL} option specified for
their accounts.
@item
When an undefined user variable was used in a updating query on the
master (such as @code{INSERT INTO t VALUES(@@a)}, where @code{@@a} had never
been set by this connection before), the slave could replicate the
query incorrectly if a previous transaction on the master used a user
variable of the same name. (Bug #1331)
@item
Fixed bug with prepared statements: Using the @code{?} prepared statement
parameter as the argument to certain functions or statement clauses caused
a server crash when @code{mysql_prepare()} was invoked. (Bug #1500)
@item
Fixed bug with prepared statements: after call to mysql_prepare
placeholders became allowed in all consequent statements, even if they are 
not prepared (Bug #1946)
@item
@code{SLAVE START} (which is a deprecated syntax, @code{START SLAVE} should be
used instead) could crash the slave. (Bug #2516)
@item
Fixed bug in @code{ALTER TABLE RENAME}, when rename to the table with
the same name in another database silently dropped destination table if
it existed. (Bug #2628)
@item
When not specify hostname in @code{SET PASSWORD FOR user} it's now
defaulted to @code{%} instead of the current host.
@end itemize

@node News-4.1.0,  , News-4.1.1, News-4.1.x
@appendixsubsec Changes in release 4.1.0 (03 Apr 2003: Alpha)

Functionality added or changed:
@itemize @bullet
@item
Renamed @code{SHOW MASTER LOGS} statement to @code{SHOW BINARY LOGS}.
@item
Allow @code{DEFAULT(@var{col_name})} in expressions; it produces the
column's default value.
@item
Added @code{--compatible} option to @command{mysqldump} for producing output that
is compatible with other database systems or with older MySQL servers.
@item
The @code{--opt} option for @command{mysqldump} now is enabled by default,
as are all the options implied by @code{--opt}.
@item
New @code{CHARSET()} and @code{COLLATION()} functions to return the character
set and collation of a string.
@item
Allow index type to be specified explicitly for some storage engines via
@code{USING type_name} syntax in index definition.
@item
New function @code{IS_USED_LOCK()} for determining the connection identifier
of the client that holds a given advisory lock.
@item
New more secure client authentication based on 45-byte passwords in the
@code{user} table.
@item
New @code{CRC32()} function to compute cyclic redundancy check value.
@item
On Windows, we are now using shared memory to communicate between server
and client when they are running on the same machine and you are
connecting to @code{localhost}.
@item
@code{REPAIR TABLE} of @code{MyISAM} tables now uses less temporary disk space when
sorting char columns.
@item
@code{DATE}/@code{DATETIME} checking is now a bit stricter to support the 
ability to automatically distinguish between date, datetime, and time
with microseconds. For example, dates of type @code{YYYYMMDD HHMMDD} are no 
longer supported; you must either have separators between each
@code{DATE}/@code{TIME} part or not at all.
@item
Server side help for all MySQL functions. One can now type @code{help
week} in the @command{mysql} client and get help for the @code{week()}
function.
@item
Added new @code{mysql_get_server_version()} C API client function.
@item
Fixed bug in @code{libmysqlclient} that fetched column defaults.
@item
Fixed bug in @file{mysql} command-line client in interpreting quotes
within comments.  (Bug #539)
@item
Added @code{record_in_range()} method to @code{MERGE} tables to be
able to choose the right index when there are many to choose from.
@item
Replication now works with @code{RAND()} and user variables @code{@@var}.
@item
Allow one to change mode for @code{ANSI_QUOTES} on the fly.
@item
@code{EXPLAIN SELECT} now can be killed. @xref{KILL,  , @code{KILL}}.
@item
@code{REPAIR TABLE} and @code{OPTIMIZE TABLE}
now can be killed. @xref{KILL,  , @code{KILL}}.
@item
Allow empty index lists to be specified for @code{USE INDEX},
@code{IGNORE INDEX}, and @code{FORCE INDEX}.
@item
@code{DROP TEMPORARY TABLE} now drops only temporary tables and doesn't
end transactions.
@item
Added support for @code{UNION} in derived tables.
@item
@strong{Warning: Incompatible change!}
@code{TIMESTAMP} is now returned as a string of type
@code{'YYYY-MM-DD HH:MM:SS'} and different timestamp lengths are not supported.

This change was necessary for SQL standards compliance. In a future
version, a further change will be made (backward compatible with this
change), allowing the timestamp length to indicate the desired number
of digits of fractions of a second.
@item
New faster client/server protocol that supports prepared statements,
bound parameters, and bound result columns, binary transfer of data,
warnings.
@item
Added database and real table name (in case of alias) to the
@code{MYSQL_FIELD} structure.
@item
Multi-line queries: You can now issue several queries at once and
then read the results in one go.
@item
In @code{CREATE TABLE foo (a INT not null primary key)} the
@code{PRIMARY} word is now optional.
@item
In @code{CREATE TABLE} the attribute @code{SERIAL} is now an alias for
@code{BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE}.
@item
@c description_for_help_topic DUAL
@code{SELECT ... FROM DUAL} is an alias for @code{SELECT ...}.
(To be compatible with some other databases).
@c end_description_for_help_topic
@item
If one creates a too long @code{CHAR}/@code{VARCHAR} it's now
automatically changed to @code{TEXT} or @code{BLOB}; One will get a
warning in this case.
@item
One can specify the different @code{BLOB}/@code{TEXT} types with the
syntax @code{BLOB(length)} and @code{TEXT(length)}.  MySQL will
automatically change it to one of the internal @code{BLOB}/@code{TEXT}
types.
@item
@c description_for_help_topic CHAR BYTE  CHAR BYTE
@code{CHAR BYTE} is an alias for @code{CHAR BINARY}.
@c end_description_for_help_topic
@item
@code{VARCHARACTER} is an alias for @code{VARCHAR}.
@item
New operators @code{integer MOD integer} and @code{integer DIV integer}.
@code{DIV} is now a reserved word.
@item
@code{SERIAL DEFAULT VALUE} added as an alias for @code{AUTO_INCREMENT}.
@item
@c help_category Functions
@c description_for_help_topic TRUE FALSE  FALSE TRUE
@code{TRUE} and @code{FALSE} added as alias for 1 and 0, respectively.
@c end_description_for_help_topic
@item
Aliases are now forced in derived tables, as per standard SQL.
@item 
Fixed @code{SELECT .. LIMIT 0} to return proper row count for
@code{SQL_CALC_FOUND_ROWS}.
@item
One can specify many temporary directories to be used in a round-robin
fashion with:  @code{--tmpdir=dirname1:dirname2:dirname3}.
@item
Subqueries: @code{SELECT * from t1 where t1.a=(SELECT t2.b FROM t2)}.
@item
Derived tables:
@example
SELECT a.col1, b.col2
       FROM (SELECT MAX(col1) AS col1 FROM root_table) a,
       other_table b
       WHERE a.col1=b.col1;
@end example
@item
Character sets to be defined per column, table and database.
@item
Unicode (UTF8) support.
@item
New @code{CONVERT(... USING ...)} syntax for converting string values between
character sets.
@item
@code{BTREE} index on @code{MEMORY} (@code{HEAP}) tables.
@item
Faster embedded server (new internal communication protocol).
@item
One can add a comment per column in @code{CREATE TABLE}.
@item
@code{SHOW FULL COLUMNS FROM @var{tbl_name}} shows column comments.
@item
@code{ALTER DATABASE}.
@item
Support for GIS (Geometrical data).
@xref{Spatial extensions in MySQL}.
@item
@code{SHOW [COUNT(*)] WARNINGS} shows warnings from the last command.
@item
One can specify a column type for a column in @code{CREATE TABLE
... SELECT} by defining the column in the @code{CREATE} part.

@example
CREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar;
@end example
@item 
@code{@var{expr} SOUNDS LIKE @var{expr}} same as @code{SOUNDEX(@var{expr})=SOUNDEX(@var{expr})}.
@item
Added new @code{VARIANCE(@var{expr})} function returns the variance of @var{expr}
@item
One can create a table from the existing table using @code{CREATE 
[TEMPORARY] TABLE [IF NOT EXISTS] @var{table} (LIKE @var{table})}. The table can 
be either normal or temporary.
@item
New options @code{--reconnect} and @code{--skip-reconnect} for the
@command{mysql} client, to reconnect automatically or not if the
connection is lost.
@item
@code{START SLAVE} (@code{STOP SLAVE}) no longer returns an error
if the slave is already started (stopped); it returns a
warning instead.
@item
@code{SLAVE START} and @code{SLAVE STOP} are no longer accepted by the query
parser; use @code{START SLAVE} and @code{STOP SLAVE} instead.
@end itemize


@node News-4.0.x, News-3.23.x, News-4.1.x, News
@appendixsec Changes in release 4.0.x (Production)

@cindex changes, version 4.0

Version 4.0 of the MySQL server includes many enhancements and new features:

@itemize @bullet
@item
The @code{InnoDB} storage engine is now included in the standard binaries,
adding transactions, row-level locking, and foreign keys.
@xref{InnoDB,  , @code{InnoDB}}.
@item
A query cache, offering vastly increased performance for many applications.
By caching complete result sets, later identical queries can return
instantly.
@xref{Query Cache}.
@item
Improved full-text indexing with boolean mode, truncation, and phrase searching.
@xref{Fulltext Search}.
@item
Enhanced @code{MERGE} tables, now supporting @code{INSERT} statements and
@code{AUTO_INCREMENT}.
@xref{MERGE storage engine,  , @code{MERGE} storage engine}.
@item
@code{UNION} syntax in @code{SELECT}.
@xref{UNION,  , @code{UNION}}.
@item
Multiple-table @code{DELETE} statements.
@xref{DELETE,  , @code{DELETE}}.
@item
@code{libmysqld}, the embedded server library.
@xref{libmysqld,  , @code{libmysqld}}.
@item
Additional @code{GRANT} privilege options for even tighter control and
security.
@xref{GRANT,  , @code{GRANT}}.
@item
Management of user resources in the @code{GRANT} system, particularly
useful for ISPs and other hosting providers.
@xref{User resources}.
@item
Dynamic server variables, allowing configuration changes to be made
without having to stop and restart the server.
@xref{SET OPTION,  , @code{SET OPTION}}.
@item
Improved replication code and features.
@xref{Replication}.
@item
Numerous new functions and options.
@item
Changes to existing code for enhanced performance and reliability.
@end itemize

For a full list of changes, please refer to the changelog sections for
each individual 4.0.x release.


@menu
* News-4.0.23::                 Changes in release 4.0.23 (not released yet)
* News-4.0.22::                 Changes in release 4.0.22 (27 Oct 2004)
* News-4.0.21::                 Changes in release 4.0.21 (06 Sep 2004)
* News-4.0.20::                 Changes in release 4.0.20 (17 May 2004)
* News-4.0.19::                 Changes in release 4.0.19 (04 May 2004)
* News-4.0.18::                 Changes in release 4.0.18 (12 Feb 2004)
* News-4.0.17::                 Changes in release 4.0.17 (14 Dec 2003)
* News-4.0.16::                 Changes in release 4.0.16 (17 Oct 2003)
* News-4.0.15::                 Changes in release 4.0.15 (03 Sep 2003)
* News-4.0.14::                 Changes in release 4.0.14 (18 Jul 2003)
* News-4.0.13::                 Changes in release 4.0.13 (16 May 2003)
* News-4.0.12::                 Changes in release 4.0.12 (15 Mar 2003: Production)
* News-4.0.11::                 Changes in release 4.0.11 (20 Feb 2003)
* News-4.0.10::                 Changes in release 4.0.10 (29 Jan 2003)
* News-4.0.9::                  Changes in release 4.0.9 (09 Jan 2003)
* News-4.0.8::                  Changes in release 4.0.8 (07 Jan 2003)
* News-4.0.7::                  Changes in release 4.0.7 (20 Dec 2002)
* News-4.0.6::                  Changes in release 4.0.6 (14 Dec 2002: Gamma)
* News-4.0.5::                  Changes in release 4.0.5 (13 Nov 2002)
* News-4.0.4::                  Changes in release 4.0.4 (29 Sep 2002)
* News-4.0.3::                  Changes in release 4.0.3 (26 Aug 2002: Beta)
* News-4.0.2::                  Changes in release 4.0.2 (01 Jul 2002)
* News-4.0.1::                  Changes in release 4.0.1 (23 Dec 2001)
* News-4.0.0::                  Changes in release 4.0.0 (Oct 2001: Alpha)
@end menu

@node News-4.0.23, News-4.0.22, News-4.0.x, News-4.0.x
@appendixsubsec Changes in release 4.0.23 (not released yet)

@c NOTE: References to bug numbers should be written after the sentence
@c NOTE: describing the bugfix, like this:
@c NOTE: This sentence describes the fix. (Bug #nnnn)

Functionality added or changed:
@itemize @bullet
@item
Added @code{--hex-blob} option to @command{mysqldump} for dumping binary
string columns using hexadecimal notation.
@item
Added @code{mysql_hex_string()} C API function that hex-encodes a string.
@item
InnoDB: Do not periodically write @code{SHOW INNODB STATUS} information
to a temporary file unless the configuration option
@code{innodb_status_file=1} is set.
@item
InnoDB: Made the foreign key parser better aware of quotes. (Bug #6340)
@item
InnoDB: Fixed a bug in @code{LOAD DATA INFILE@dots{}REPLACE}
printing duplicate key error when executing the same
load query several times. (Bug #5835)
@item
@code{mysqlbinlog} now prints an informative commented line (thread id,
timestamp, server id, etc) before each @code{LOAD DATA INFILE}, like it already
does for other queries; unless @code{--short-form} is used.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Prevent adding @code{CREATE TABLE .. SELECT} query to the binary log when the
insertion of new records partially failed. (Bug #6682)
@item
Fixed bug which caused @code{FROM_UNIXTIME()} function to return wrong result
if the argument was too big. (Bug #6439)
@item
Fixed bug which caused MySQL server to store wrong values in @code{TIMESTAMP} 
columns and give wrong results for @code{UNIX_TIMESTAMP()} function if it
was run in time zone with leap seconds. (Bug #6387)
@item
InnoDB: Refuse to open new-style tables created with MySQL 5.0.3 or later.
(Bug #7089)
@item
InnoDB: Do not call @code{rewind()} when displaying
@code{SHOW INNODB STATUS} information on @code{stderr}.
@item
InnoDB: If one used @code{INSERT IGNORE} to insert several rows at a time,
and the first inserts were ignored because of a duplicate key collision,
then InnoDB in a replication slave assigned @code{AUTO_INCREMENT} values 1
bigger than in the master. This broke the MySQL replication. (Bug #6287)
@item
InnoDB: Fix two hangs: @code{FOREIGN KEY} constraints treated table and
database names as case-insensitive. @code{RENAME TABLE t TO T} would hang
in an endless loop if @code{t} had a foreign key constraint defined on it.
Fix also a hang over the dictionary mutex that would occur if one tried
in @code{ALTER TABLE} or @code{RENAME TABLE} to create a foreign key
constraint name that collided with another existing name. (Bug #3478)
@item
Fixed a bug which caused a crash when only the slave I/O thread was
stopped and restarted. (Bug #6148)
@item
If a connection had an open transaction but had done no updates to
transactional tables (for example if had just done a @code{SELECT FOR UPDATE}
then executed a non-transactional update, that update automatically committed
the transaction (thus releasing InnoDB's row-level locks etc). (Bug #5714)
@item
If a connection was interrupted by a network error and did a rollback, the
network error code got stored into the @code{BEGIN} and @code{ROLLBACK} binary
log events; that caused superfluous slave stops. (Bug #6522)
@item
A sequence of @code{BEGIN} (or @code{SET AUTOCOMMIT=0}), @code{FLUSH TABLES
WITH READ LOCK}, transactional update, @code{COMMIT}, @code{FLUSH
TABLES WITH READ LOCK} could hang the connection forever and possibly the MySQL
server itself. This happened for example when running the @code{innobackup}
script several times. (Bug #6732)
@end itemize

@node News-4.0.22, News-4.0.21, News-4.0.23, News-4.0.x
@appendixsubsec Changes in release 4.0.22 (27 Oct 2004)

Functionality added or changed:
@itemize @bullet
@item 
The @code{--with-openssl} option for @command{configure} now accepts a path
prefix as an argument. @code{--with-openssl-includes} and 
@code{--with-openssl-libs} are still supported, but are needed only to 
override the default values. (Bug #5494)
@item
Added new @code{--without-man} option to @command{configure} to suppress
building/installing the manual pages. (Bug #5379)
@item
InnoDB: New @code{mysqld} option @code{--innodb-table-locks} and session
variable @code{innodb_table_locks} (on by default). 
In applications using @code{AUTOCOMMIT=1} and MySQL's @code{LOCK TABLES}
command, InnoDB's internal table locks that were added in 4.0.20
can cause deadlocks. You can set
@code{innodb_table_locks=0} in @file{my.cnf} to remove that problem.
@xref{InnoDB restrictions}.
(Bug #3299, Bug #5998)
@item
InnoDB: Added the startup option and settable global variable
@code{innodb_max_purge_lag} for delaying @code{INSERT}, @code{UPDATE}
and @code{DELETE} operations when the purge operations are lagging.
The default value of this parameter is zero, meaning that there will
not be any delays.  @xref{Implementation}.
@item
InnoDB: Change error code to @code{HA_ERR_ROW_IS_REFERENCED} if we cannot
@code{DROP} a parent table because it is referenced by a
@code{FOREIGN KEY} constraint.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Fixed bug in server which caused connection stall when one of deprecated
@code{libmysqlclient} functions @code{mysql_create_db(), mysql_rm_db()}
were called and were going to return error. (Bug #6081)
@item
Fixed returning wrong query result from query cache if a temporary table was
hiding a real table after putting results to query cache. (Bug #6084)
@item
Fixed @code{ENABLE KEYS}, which failed if @code{tmpdir} ran out of
space. Now, a full repair is done in this case. (Bug #5625)
@item
Fixed an improper error message when trying to drop a table which is
referenced by a @code{FOREIGN KEY} constraint. (Bug #5784)
@item 
Fixed a bug that allowed @code{FLUSH TABLE(S)} to close @code{HANDLER}
tables. @code{HANDLER} tables are now reopened after a @code{FLUSH
TABLE(S)} the next time they are used. However, they lose their file position
if this happens.  (Bug #4286)
@item 
Fixed a bug that allowed @code{HANDLER} tables with the same alias to be
opened multiple times. @code{HANDLER} aliases must now be unique, even though
it is syntactically correct in versions below 4.1, to qualify them with their
base table's database name (e.g. test_db.handler_tbl, but this will now
conflict with e.g. another_db.handler_tbl). (Bug #4335)
@item
Fixed crash when using MySQL 4.0 with privilege tables from MySQL 5.0.
@item
@command{mysqlimport} now reads input files locally from the client host only
if the @code{--local} option is given.  Previously, it assumed incorrectly
in some cases that files were local even without @code{--local}.
(Bug #5829)
@item
InnoDB: Make the check for excessive semaphore waits to tolerate glitches
in the system clock (do not crash the server if the system time is
adjusted while InnoDB is under load.). (Bug #5898)
@item
InnoDB: Fixed a bug in the InnoDB @code{FOREIGN KEY} parser that prevented
@code{ALTER TABLE} of tables containing @samp{#} in their names. (Bug #5856)
@item
InnoDB: Fixed problem introduced in 4.0.21 where a connection starting
a transaction,
doing updates, then @code{FLUSH TABLES WITH READ LOCK}, then @code{COMMIT},
would cause replication slaves to stop (complaining about error 1223).
Bug surfaced
when using the InnoDB @code{innobackup} script. (Bug #5949)
@item
InnoDB: If one updated a column so that its size changed, or updated
it to an externally stored (@code{TEXT} or @code{BLOB}) value, then
ANOTHER externally stored column would show up as 512 bytes of good
data + 20 bytes of garbage in a consistent read that fetched the old
version of the row. (Bug #5960)
@item
InnoDB: Release the dictionary latch during a long cascaded @code{FOREIGN KEY}
operation, so that we do not starve other users doing @code{CREATE TABLE}
or other DDL operations. This caused a notorious 'Long semaphore wait' message
to be printed to the @file{.err} log. (Bug #5961)
@item
InnoDB: Let InnoDB remember row locking type (X or S) inside
@code{LOCK TABLES},
also over plain consistent read @code{SELECT}s.
@item
InnoDB: Fixed a bug introduced in 4.0.21. An assertion failed if
one used @command{mysqldump} with the option @code{-l} or @code{--opt},
or if one used @code{LOCK TABLES ... LOCAL}. (Workaround in 4.0.21: use
@code{--quick} and @code{--single-transaction}. (Bug #5538)
@item
InnoDB: Having a column prefix index in the primary key, and the same
column fully in a secondary key could cause an assertion failure in
row_build_row_ref(). (Bug #5180)
@item
Fixed a bug which resulted in an erroneously calculated number of examined
rows in @code{UNION}s. This value is printed in the slow query log.
(Bug #5879)
@item
Fixed bug with crash of server on some values of @code{read_rnd_buffer_size}
(Bug #5492)
@item
Fixed bug which caused truncation of values read from or into
@code{TIMESTAMP} fields if @code{--new} mode was enabled. (Bug #4131)
@item
@command{mysqladmin} now returns a status of 0 even when the server denies
access; such an error means the server is running. (Bug #3120)
@item
Fixed that if the slave SQL thread found a syntax error in a query (which
should be rare, as the master parsed it successfully), it stops. (Bug #5711)
@item
Fixed that if a write to a MyISAM table fails because of a full disk or an
exceeded disk quota, it prints a message to the error log every 10 minutes, and
waits until disk becomes free. (Bug #3248)
@item
Fixed problem with symlinked databases on Windows being shown with @code{SHOW 
DATABASES} even if the database name doesn't match the given wildcard (Bug #5539)
@end itemize

@node News-4.0.21, News-4.0.20, News-4.0.22, News-4.0.x
@appendixsubsec Changes in release 4.0.21 (06 Sep 2004)

@c NOTE: References to bug numbers should be written after the sentence
@c NOTE: describing the bugfix, like this:
@c NOTE: This sentence describes the fix. (Bug #nnnn)

Functionality added or changed:
@itemize @bullet
@item Print @var{version_comment} (from @code{./configure --comment} during
compilation) when starting the server.  E.g.:
@code{Version: '4.0.21-debug'  socket: '/tmp/mysql.sock'  port: 0  Official MySQL Binary}
@item
Made the MySQL server not react to signals @code{SIGHUP} and @code{SIGQUIT} on
Mac OS X 10.3. This is needed because under this OS, the MySQL server receives
lots of these signals (reported as Bug #2030).
@item
On Windows, the @command{mysqld-nt} and @command{mysqld-max-nt} servers now
write error messages to the Windows event log in addition to the MySQL error
log.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Fixed an old bug in concurrent accesses to @code{MERGE} tables
(even one @code{MERGE} table and @code{MyISAM} tables), that could've
resulted in a crash or hang of the server. (Bug #2408)
@item
Fixed a bug that caused incorrect results from @code{GROUP BY} queries
with expression in @code{HAVING} clause that refers to a @code{BLOB}
(@code{TEXT}, @code{TINYBLOB}, etc) fields. (Bug #4358)
@item
Fixed a bug when memory was not released when @code{HEAP} table is
dropped. 
It could only happen on Windows when a symlink file (.sym) is used and
if that symlink file contained double backslashes (\\). (Bug #4973)
@item
Fixed a bug which prevented @code{TIMESTAMP(19)} fields from being created.
(Bug #4491)
@item
Fixed a bug that caused wrong results in queries that were using index to
search for @code{NULL} values in @code{BLOB} (@code{TINYBLOB}, @code{TEXT},
@code{TINYTEXT}, etc) columns of @code{MyISAM} tables. (Bug #4816)
@item
Fixed a bug in the function @code{ROUND()} reporting incorrect metadata
(number of digits after the decimal point). It can be seen, for example,
in @code{CREATE TABLE t1 SELECT ROUND(1, 34)}. (Bug #4393)
@item
Fixed precision loss bug in some mathematical functions such as
@code{SQRT()} and @code{LOG()}. (Bug #4356)
@item
Fixed a long-standing problem with @code{LOAD DATA} with the @code{LOCAL}
option. The problem occurs when an error happens during the @code{LOAD DATA}
operation. Previously, the connection was broken. Now the error message
is returned and connection stays open.  
@item
Optimizer now treats @code{col IN (val)} the same way it does 
for @code{col = val}.
@item
Fixed a problem with @code{net_buffer_length} when building the
@code{DBD::mysql} Perl module.  (Bug #4206)
@item
@code{lower_case_table_names=2} (keep case for table names) was not honored
with @code{ALTER TABLE} and @code{CREATE/DROP INDEX}. (Bug #3109)
@item
Fixed a crash on declaration of @code{DECIMAL(0,...)} column. (Bug #4046)
@item
Fixed a bug in @code{IF()} function incorrectly determining the result type
if aggregate functions were involved. (Bug #3987)
@item
Fixed bug in privilege checking where, under some conditions, one was able to
grant privileges on the database, he has no privileges on. (Bug #3933)
@item
Fixed crash in @code{MATCH ... AGAINST()} on a phrase search operator with
a missing closing double quote. (Bug #3870)
@item
Fixed a bug with truncation of big values (> 4294967295) of 64-bit system
variables. (Bug #3754)
@item
If @code{server-id} was not set using startup options but with @code{SET
GLOBAL}, the replication slave still complained that it was not set.
(Bug #3829)
@item
Fixed potential memory overrun in @code{mysql_real_connect()} (which
required a compromised DNS server and certain operating systems). (Bug #4017)
@item
During the installation process of the server RPM on Linux, @command{mysqld}
was run as the @code{root} system user, and if you had
@code{--log-bin=<somewhere_out_of_var_lib_mysql>} it created binary log
files owned by @code{root} in this directory, which remained owned by
@code{root} after the installation. This is now fixed by starting
@command{mysqld} as the @code{mysql} system user instead. (Bug #4038)
@item
Made @code{DROP DATABASE} honor the value of
@code{lower_case_table_names}. (Bug #4066)
@item
The slave SQL thread refused to replicate @code{INSERT ... SELECT} if it
examined more than 4 billion rows. (Bug #3871)
@item
Fixed incorrect destruction of expression which led to crash of server on
complex @code{AND}/@code{OR} expressions if query was ignored (either by a
replication server because of @code{--replicate-*-table} rules, or by any MySQL
server because of a syntax error). (Bug #3969, Bug #4494)
@item
Fixed that @command{mysqlbinlog --position --read-from-remote-server}
had wrong @code{# at} lines. (Bug #4506)
@item
If @code{CREATE TEMPORARY TABLE t SELECT} failed while loading the data, the
temporary table was not dropped. (Bug #4551)
@item
Fixed that when a multiple-table @code{DROP TABLE} failed to drop a table on
the master server, the error code was not written to the binary log.
(Bug #4553)
@item
When the slave SQL thread was replicating a @code{LOAD DATA INFILE}
statement, it didn't show the statement in the output of @code{SHOW
PROCESSLIST}. (Bug #4326)
@item
Fixed that @code{CREATE TABLE ... TYPE=HEAP ... AS SELECT...} caused
replication slave to stop. (Bug #4971)
@item
Fixed that @code{disable-local-infile} option had no effect if client read it
from a configuration file using
@code{mysql_options(...,MYSQL_READ_DEFAULT,...)}. (Bug #5073)
@item
Fixed that @command{mysql-test-run} failed on the @code{rpl_trunc_binlog} test if
running test from the installed (the target of 'make install') directory. (Bug
#5050)
@item
Fixed an unlikely deadlock which could happen when using @code{KILL}. (Bug
#4810)
@item
Fixed a crash when one connection got @code{KILL}ed while it was doing
@code{START SLAVE}. (Bug #4827)
@item
Made @code{FLUSH TABLES WITH READ LOCK} block @code{COMMIT} if server is
running with binary logging; this ensures that the binary log position is
trustable when doing a full backup of tables and the binary log. (Bug #4953)
@item
Fixed that the counter of an @code{auto_increment} column was not reset by
@code{TRUNCATE TABLE} is the table was a temporary one. (Bug #5033)
@item
Made database names to compare case-insensitively in fully
qualified column names (@code{database.table.column}) when
@code{lower_case_table_names=1}. (Bug #4792)
@item
Fixed that @code{SET CHARACTER SET} was not replicated correctly. MySQL 4.1
does not have that bug. (Bug #4500)
@end itemize

@node News-4.0.20, News-4.0.19, News-4.0.21, News-4.0.x
@appendixsubsec Changes in release 4.0.20 (17 May 2004)

@strong{Note}: The windows packages had to be repackaged and re-released
several times to resolve packaging issues (such as missing files). This did not
affect the binaries included (they have not been recompiled), therefore the
installation packages are of version 4.0.20d, while the binaries included still
identify themselves as version 4.0.20b.

Functionality added or changed:
@itemize @bullet
@item
Phrase search in @code{MATCH ... AGAINST ( ... IN BOOLEAN MODE)} no longer
matches partial words.
@end itemize

Bugs fixed:
@itemize @bullet
@item
A crashing bug (race condition) was fixed in InnoDB diagnostic logging.
It was introduced in 4.0.19. (Bug #3596)
@item
Fixed a bug in division @code{/} reporting incorrect metadata
(number of digits after the decimal point). It can be seen, for example,
in @code{CREATE TABLE t1 SELECT "0.01"/"3"}. (Bug #3612)
@item
Fixed a problem with non-working @code{DROP DATABASE} on some configurations
(in particular, Linux 2.6.5 with ext3 are known to expose this bug).
(Bug #3594)
@item
Fixed that in some replication error messages, a very long query caused the rest
of the message to be invisible (truncated), by putting the query last in the
message. (Bug #3357)
@end itemize

@node News-4.0.19, News-4.0.18, News-4.0.20, News-4.0.x
@appendixsubsec Changes in release 4.0.19 (04 May 2004)

@strong{Note}: The MySQL 4.0.19 binaries were uploaded to the download
mirrors on May, 10th. However, a potential crashing bug was found just
before the 4.0.19 release was publicly announced and published from the
4.0 download pages at @uref{http://dev.mysql.com/}.

A fix for the bug was pushed into the MySQL source tree shortly after it
could be reproduced and is included in MySQL 4.0.20. Users upgrading from
MySQL 4.0.18 should upgrade directly to MySQL 4.0.20 or later.

See (Bug #3596) for details (it was reported against MySQL-4.1, but was
confirmed to affect 4.0.19 as well).

Functionality added or changed:
@itemize @bullet
@item
If length of a timestamp field is defined as 19, the timestamp will be
displayed as @code{"YYYY-MM-DD HH:MM:SS}. This is done to make it easier
to use tables created in MySQL 4.1 to be used in MySQL 4.0.
@item
If you use @code{RAID_CHUNKS} with a value > 255 it will be set to 255.
This was made to ensure that all raid directories are always 2 hex bytes.
(Bug #3182)
@item
Changed that the optimizer will now consider the index specified in 
@code{FORCE INDEX} clause as a candidate to resolve @code{ORDER BY}
as well.
@item
The @code{--log-warnings} server option now is enabled by default.
Disable with @code{--skip-log-warnings}.
@item
Until now, in @code{SELECT ... UNION SELECT ... ORDER BY ...}, it was possible
to qualify a column name in the @code{ORDER BY} clause with a table name. This
is no longer possible. Column names in @code{ORDER BY} should refer to names
established in the first @code{SELECT} of the @code{UNION}. (Bug #3064)
@item
Added @code{max_insert_delayed_threads} system variable as a synonym for
@code{max_delayed_threads}.
@item
Added @code{query_cache_wlock_invalidate} system variable. It allows
emulation of @code{MyISAM} table write-locking behavior, even for queries
in the query cache. (Bug #2693)
@item
The keyword @code{MASTER_SERVER_ID} is not reserved anymore.
@item
The following is relevant mainly for Mac OS X users who use a
case-insensitive filesystem.  This is not relevant for Windows users as
@code{InnoDB} in this case always stores filenames in lower case:

You can now force @code{lower_case_table_names} to 0 from the command
line or a configuration file. This is useful with case-insensitive filesystems
when you have previously not used
@code{lower_case_table_names=1} or @code{lower_case_table_names=2} and
you have already created @code{InnoDB} tables.  With
@code{lower_case_table_names=0}, @code{InnoDB} tables were stored in mixed case
while setting lower_case_table_names to a non-zero value now will force it to
lower case (to make the table names case insensitive).

Because it's possible to crash @code{MyISAM} tables by referring to them with
different case on a case-insensitive filesystem, we recommend that you
use @code{lower_case_table_names} or @code{lower_case_table_names=2} on
such filesystems.

The easiest way to convert to use @code{lower_case_table_names=2} is to
dump all your @code{InnoDB} tables with @command{mysqldump}, drop them and then
restore them.
@item
Changed that the relay log is flushed to disk by the slave I/O thread every
time it reads a relay log event. This reduces the risk of losing some part of
the relay log in case of brutal crash.
@item
When a session having open temporary tables terminates, the statement
automatically written to the binary log is now @code{DROP TEMPORARY TABLE IF
EXISTS} instead of @code{DROP TEMPORARY TABLE}, for more robustness.
@item
Added option @code{--replicate-same-server-id}.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Added missing full-text variable @code{ft_stopword_file} to @command{myisamchk}.
@item
Don't allow stray @code{','} at the end of field specifications. (Bug #3481)
@item
@code{INTERVAL} now can handle big values for seconds, minutes and hours.
(Bug #3498)
@item
Blank hostname did not work as documented for table and column privileges.
Now it's works the same way as @code{'%'}. (Bug #3473)
@item
Fixed a harmless buffer overflow in @file{replace} utility. (Bug# 3541)
@item
Fixed @code{SOUNDEX()} to ignore non-alphabetic characters also
in the beginning of the string. (Bug #3556)
@item
Fixed a bug in @code{MATCH ... AGAINST()} searches when another thread was
doing concurrent inserts into the @code{MyISAM} table in question.  The first
--- full-text search --- query could return incorrect results in this case
(for example, ``phantom'' rows or not all matching rows, even an empty result set).
The easiest way to check whether you are affected is to start @command{mysqld}
with @code{--skip-concurrent-insert} switch and see if it helps.
@item
Fixed bug when doing @code{DROP DATABASE} on a directory containing non-
MySQL files. Now a proper error message is returned. 
@item
Fixed bug in @code{ANALYZE TABLE} on a @code{BDB} table inside a transaction
that hangs server thread. (Bug #2342)
@item
Fixed a symlink vulnerability in @file{mysqlbug} script. (Bug #3284)
@item
Fixed core dump bug in @code{SELECT DISTINCT} where all selected parts
where constants and there were hidden columns in the created temporary table.
(Bug #3203)
@item
Fixed core dump bug in @code{COUNT(DISTINCT)} when there was a lot of
values and one had a big value for @code{max_heap_table_size}.
@item
Fixed problem with multiple-table-update and BDB tables. (Bug: #3098)
@item
Fixed memory leak when dropping database with @code{RAID} tables. (Bug #2882)
@item
Fixed core dump crash in replication during relay-log switch when the
relay log went over @code{max_relay_log_size} and the slave thread did a
@code{flush_io_cache()} at the same time.
@item
Fixed hangup bug when issuing multiple @code{SLAVE START} from different
threads at the same time. (Bug #2921)
@item
Fixed bug when using @code{DROP DATABASE} with @code{lower_case_table_names=2}.
@item
Fixed wrong result in @code{UNION} when using @code{lower_case_table_names=2}.
(Bug #2858)
@item
One can now kill threads that is 'stuck' in the join optimizer (can
happen when there is MANY tables in the join in which case the optimizer
can take really long time). (Bug #2825)
@item
Rollback @code{DELETE} and @code{UPDATE} statements if thread is killed.
(Bug #2422)
@item
Ensure that all rows in an @code{INSERT DELAYED} statement is written at
once if binary logging is enabled. (Bug #2491).
@item
Fixed bug in query cache statistic, more accurate formula linked statistic
variables mentioned in the manual.
@item
Fixed a bug in parallel repair
(@command{myisamchk -p}, @code{myisam_repair_threads}) -
sometimes repair process failed to repair a table. (Bug #1334)
@item
Fixed bugs with names of tables, databases and columns that end to space 
(Bug #2985)
@item
Fixed a bug in multiple-table @code{UPDATE} statements involving at least one constant 
table. Bug was exhibited in allowing non matching row to be updated.
(Bug #2996).
@item
Fixed all bugs in scripts for creating/upgrading system database (Bug #2874)
Added tests which guarantee against such bugs in the future.
@item
Fixed bug in @file{mysql} command-line client in interpreting quotes
within comments. (Bug #539)
@item
@code{--set-character-set} and @code{--character-sets-dir} options in
@command{myisamchk} now work.
@item
Fixed a bug in @command{mysqlbinlog} that caused one pointer to be free'd twice
in some cases.
@item
Fixed a bug in boolean full-text search, that sometimes could lead to false
matches in queries with several levels of subexpressions using @code{+}
operator (for example,
@code{MATCH ... AGAINST('+(+(word1 word2)) +word3*' IN BOOLEAN MODE)}.
@item
Fixed Windows-specific portability bugs in @file{myisam_ftdump}.
@item
Fixed a bug in multiple-table @code{DELETE} that was caused by foreign key
constraints. If the order of the tables established by MySQL optimizer
did not match parent-child order, no rows were deleted and no error
message was provided. (Bug #2799)
@item 
Fixed a few years old bug in the range optimizer that
caused a segmentation fault on some very rare queries. (Bug #2698)
@item
Replication:
If a client connects to a slave server and issues an administrative
statement for a table (for example, @code{OPTIMIZE TABLE} or @code{REPAIR
TABLE}), this could sometimes stop the slave SQL thread. This does not lead
to any corruption, but you must use @code{START SLAVE} to get replication
going again. (Bug #1858)
The bug was accidentally not fixed in 4.0.17 as it was unfortunately
earlier said.
@item
Fixed that when a @code{Rotate} event is found by the slave SQL thread in the
middle of a transaction, the value of @code{Relay_Log_Pos} in @code{SHOW SLAVE
STATUS} remains correct. (Bug #3017)
@item
Corrected the master's binary log position that @code{InnoDB} reports when it is doing a
crash recovery on a slave server. (Bug #3015)
@item
Changed that when a @code{DROP TEMPORARY TABLE} statement is automatically
written to the binary log when a session ends, the statement is recorded with an
error code of value zero (this ensures that killing a @code{SELECT} on the
master does not result in a superfluous error on the slave). (Bug #3063)
@item
Changed that when a thread handling @code{INSERT DELAYED} (also known as a
@code{delayed_insert} thread) is killed, its statements are recorded with an
error code of value zero (killing such a thread does not endanger
replication, so we thus avoid a superfluous error on the slave). (Bug #3081)
@item
Fixed deadlock when two @code{START SLAVE} commands were run at the same
time. (Bug #2921)
@item
Fixed that a statement never triggers a superfluous error on the slave, if it
must be excluded given the @code{--replicate-*} options. The bug was that if the
statement had been killed on the master, the slave would stop. (Bug #2983)
@item
The @code{--local-load} option of @command{mysqlbinlog} now requires an argument.
@item
Fixed a segmentation fault when running @code{LOAD DATA FROM MASTER} after
@code{RESET SLAVE}. (Bug #2922)
@item
Fixed a rare error condition that caused the slave SQL thread spuriously
to print the message @code{Binlog has bad magic number} and stop when it
was not necessary to do so.  (Bug #3401)
@item
Fixed the column @code{Exec_master_log_pos} (and its disk image in the
@code{relay-log.info} file) to be correct if the master had version 3.23 (it
was too big by 6 bytes). This bug does not exist in the 5.0 version.
(Bug #3400)
@item
Fixed that @command{mysqlbinlog} does not forget to print a @code{USE} command
under rare circumstances where the binary log contained a @code{LOAD DATA
INFILE} command. (Bug #3415)
@item
Fixed a memory corruption when replicating a @code{LOAD DATA INFILE} when the
master had version 3.23. Some smaller problems remain in this setup,
@xref{Replication Features}. (Bug #3422)
@item
Multiple-table @code{DELETE} statements were always replicated by the slave if
there were some @code{--replicate-*-ignore-table} options and no
@code{--replicate-*-do-table} options. (Bug #3461)
@item
Fixed a crash of the MySQL slave server when it was built with
@code{--with-debug} and replicating itself. (Bug #3568)
@end itemize

@node News-4.0.18, News-4.0.17, News-4.0.19, News-4.0.x
@appendixsubsec Changes in release 4.0.18 (12 Feb 2004)

Functionality added or changed:
@itemize @bullet
@item
Fixed processing of @code{LOAD DATA} by @command{mysqlbinlog} in remote mode.
(Bug #1378)
@item
New utility program @file{myisam_ftdump} was added to binary
distributions.
@item
@code{ENGINE} is now a synonym for the @code{TYPE} option for
@code{CREATE TABLE} and @code{ALTER TABLE}.
@item
@code{lower_case_table_names} system variable now can take a value of
@code{2}, to store table names in mixed case on case-insensitive filesystems.
It's forced to 2 if the database directory is located on a case-insensitive
filesystem.
@item
For replication of @code{MEMORY} (@code{HEAP}) tables: Made the master
automatically write a @code{DELETE FROM} statement to its binary log when a
@code{MEMORY} table is opened for the first time since master's startup.
This is for the case where the slave has replicated a non-empty
@code{MEMORY} table, then the master is shut down and restarted: the table
is now empty on master; the @code{DELETE FROM} empties it on slave too. Note
that even with this fix, between the master's restart and the first use of
the table on master, the slave still has out-of-date data in the table. But
if you use the @code{init-file} option to populate the @code{MEMORY} table
on the master at startup, it ensures that the failing time interval is zero.
(Bug #2477)
@item
Optimizer is now better tuned for the case where the first used key part
(of many) is a constant.  (Bug #1679)
@item
Removed old non-working @code{--old-rpl-compat} server option, which was a
holdover from the very first 4.0.x versions. (Bug #2428)
@item
Added option @code{--sync-frm}. It's on by default, to
instruct MySQL to sync to disk each time @file{.frm} file is created.
Use @code{--disable-sync-frm} to disable.
@end itemize

Bugs fixed:
@itemize @bullet
@item
@command{mysqlhotcopy} now works on NetWare.
@item
@code{DROP DATABASE} could not drop databases with RAID tables that had
more than nine @code{RAID_CHUNKS}. (Bug #2627)
@item
Fixed bug in range optimizer when using overlapping ranges. (Bug #2448)
@item
Limit @code{wait_timeout} to 2147483 on Windows (OS limit). (Bug #2400)
@item
Fixed bug when @code{--init-file} crashes MySQL if it contains a large
@code{SELECT}. (Bug #2526)
@item
@code{SHOW KEYS} now shows @code{NULL} in the @code{Sub_part} column for
@code{FULLTEXT} indexes.
@item
The signal thread's stack size was increased to enable @command{mysqld}
to run on Debian/IA-64 with a TLS-enabled @code{glibc}. (Bug #2599)
@item
Now only the @code{SELECT} privilege is needed for tables that are only read in
multiple-table @code{UPDATE} statements. (Bug #2377)
@item
Give proper error message if one uses @code{LOCK TABLES ... ; INSERT
... SELECT} and one used the same table in the @code{INSERT} and @code{SELECT}
part. (Bug #2296)
@item
@code{SELECT INTO ... DUMPFILE} now deletes the generated file on error.
@item
Fixed foreign key reference handling to allow references to column names that
contain spaces. (Bug #1725)
@item
Fixed problem with index reads on character columns with @code{BDB} tables. The
symptom was that data could be returned in the wrong lettercase. (Bug #2509)
@item
Fixed a spurious table corruption problem that could sometimes appear on
tables with indexed @code{TEXT} columns if these columns happened to contain
values having trailing spaces.  This bug was introduced in 4.0.17.
@item
Fixed a problem where some queries could hang if a condition like
@code{@var{indexed_TEXT_column} = @var{expr}}
was present and the column contained values having trailing spaces.
This bug was introduced in 4.0.17.
@item
Fixed a bug that could cause incorrect results from a query
that involved range conditions on indexed @code{TEXT} columns
that happened to contain values having trailing spaces. This bug was
introduced in 4.0.17. (Bug #2295)
@item
Fixed incorrect path names in some of the manual pages.
(Bug #2270)
@item
Fixed spurious ``table corrupted'' errors in parallel repair operations.
@xref{Server system variables}.
@item
Fixed a crashing bug in parallel repair operations.
@xref{Server system variables}.
@item
Fixed bug in updating @code{MyISAM} tables for @code{BLOB} values longer
than 16MB. (Bug #2159)
@item
Fixed bug in @command{mysqld_safe} when running multiple instances of
MySQL. (Bug #2114)
@item
Fixed a bug in using @code{HANDLER} statement with tables not
from a current database. (Bug #2304)
@item
Fixed a crashing bug that occurred due to the fact that multiple-table
@code{UPDATE} statements did not check that there was only one table
to be updated. (Bug #2103)
@item
Fixed a crashing bug that occurred due to @code{BLOB} column
type index size being calculated incorrectly in @code{MIN()} and @code{MAX()}
optimizations.
(Bug #2189)
@item
Fixed a bug with incorrect syntax for @code{LOCK TABLES} in
@command{mysqldump}. (Bug #2242)
@item
Fixed a bug in @command{mysqld_safe} that caused @command{mysqld} to generate a
warning about duplicate @code{user=@var{xxx}} options if this option was specified in
the @code{[mysqld]} or @code{[server]} sections of @file{my.cnf}.
(Bug #2163)
@item
@code{INSERT DELAYED ... SELECT ...} could cause table corruption because
tables were not locked properly.  This is now fixed by ignoring @code{DELAYED}
in this context. (Bug #1983)
@item
Replication: Sometimes the master gets a non-fatal error during the
execution of a statement that does not immediately succeed.  (For example,
a write to a @code{MyISAM} table may first receive ``no space left
on device,'' but later complete when disk space becomes available.
@xref{Full disk}.)  The bug was that the master forgot to reset the error
code to 0 after success, so the error code got into its binary log, thus
causing the slave to issue false alarms such as ``did not get the same
error as on master.'' (Bug #2083)
@item
Removed a misleading ``check permissions on master.info'' from a replication
error message, because the cause of the problem could be something other than
permissions. (Bug #2121)
@item
Fixed a crash when the replication slave was unable to create the first relay
log. (Bug #2145)
@item
Replication of @code{LOAD DATA INFILE} for an empty file from a 3.23 master to a
4.0 slave caused the slave to print an error. (Bug #2452)
@item
When automatically forcing @code{lower_case_table_names} to 1 if the file
system was case insensitive, @command{mysqld} could crash. This bug existed only
in MySQL 4.0.17. (Bug #2481)
@item
Restored ability to specify default values for @code{TIMESTAMP} columns
that was erroneously disabled in previous release. (Bug #2539) Fixed
@code{SHOW CREATE TABLE} to reflect these values. (Bug #1885) Note
that because of the auto-update feature for the first @code{TIMESTAMP}
column in a table, it makes no sense to specify a default value for
the column. Any such default will be silently ignored (unless another
@code{TIMESTAMP} column is added before this one).  Also fixed the meaning
of the @code{DEFAULT} keyword when it is used to specify the value to be
inserted into a @code{TIMESTAMP} column other than the first. (Bug #2464)
@item
Fixed bug for out-of-range arguments on QNX platform that caused
@code{UNIX_TIMESTAMP()} to produce incorrect results or that caused
non-zero values to be inserted into @code{TIMESTAMP} columns.  (Bug #2523)
Also, current time zone now is taken into account when checking if datetime
values satisfy both range boundaries for @code{TIMESTAMP} columns. The
range allowed for a @code{TIMESTAMP} column is time zone-dependent and
equivalent to a range of @code{1970-01-01 00:00:01} UTC to @code{2037-12-31
23:59:59} UTC.
@item
Multiple-table @code{DELETE} statements were never replicated by the slave if
there were any @code{--replicate-*-table} options. (Bug #2527)
@item
Changes to session counterparts of variables @code{query_prealloc_size},
@code{query_alloc_block_size}, @code{trans_prealloc_size},
@code{trans_alloc_block_size} now 
have an effect. (Bug #1948)
@item
Fixed bug in @code{ALTER TABLE RENAME}, when rename to the table with
the same name in another database silently dropped destination table if
it existed. (Bug #2628)
@end itemize

@node News-4.0.17, News-4.0.16, News-4.0.18, News-4.0.x
@appendixsubsec Changes in release 4.0.17 (14 Dec 2003)

Functionality added or changed:
@itemize @bullet
@item
@command{mysqldump} no longer dumps data for @code{MERGE} tables. (Bug #1846)
@item
@code{lower_case_table_names} is now forced to 1 if the database directory
is located on a case-insensitive filesystem. (Bug #1812)
@item
Symlink creation is now disabled on systems where @code{realpath()} doesn't
work. (Before one could use @code{CREATE TABLE .. DATA DIRECTORY=..} even if
@code{HAVE_BROKEN_REALPATH} was defined. This is now disabled to avoid
problems when running @code{ALTER TABLE}).
@item
Inserting a negative @code{AUTO_INCREMENT} value in a @code{MyISAM} table 
no longer updates the @code{AUTO_INCREMENT} counter to a big unsigned value.
(Bug #1366)
@item
Added four new modes to @code{WEEK(..., mode)} function.
@xref{Date and time functions, , @code{WEEK(date,mode)}}.
(Bug #1178)
@item
Allow @code{UNION DISTINCT} syntax.
@item
MySQL now syncs to disk each time @file{.frm} file is created.
@item
@code{mysql_server_init()} now returns 1 if it can't initialize the
environment. (Previously @code{mysql_server_init()} called @code{exit(1)}
if it could not create a key with @code{pthread_key_create()}. (Bug #2062)
@item
Allow spaces in Windows service names.
@item
Changed the default Windows service name for @command{mysqld} from @code{MySql}
to @code{MySQL}.
This should not affect usage, because service names are not case sensitive.
@item
When you install @command{mysqld} as a service on Windows systems, @command{mysqld}
will read startup options in option files from the option group with the same
name as the service name.
(Except when the service name is @code{MySQL}).
@end itemize

Bugs fixed:
@itemize @bullet
@item
Sending @code{SIGHUP} to @command{mysqld} crashed the server if it was running with
@code{--log-bin}. (Bug #2045)
@item
One can now configure MySQL as a Windows service as a normal
user. (Bug #1802). Thanks to Richard Hansen for fixing this.
@item
Database names are now compared in lowercase in @code{ON} clauses
when @code{lower_case_table_names} is set. (Bug #1736)
@item
@code{IGNORE ... LINES} option to @code{LOAD DATA INFILE} didn't work
when used with fixed length rows. (Bug #1704)
@item
Fixed problem with @code{UNIX_TIMESTAMP()} for timestamps close to 0.
(Bug #1998)
@item
Fixed problem with character values greater than 128 in the @code{QUOTE()}
function. (Bug #1868)
@item
Fixed searching of @code{TEXT} with endspace. (Bug #1651)
@item
Fixed caching bug in multiple-table updates where same table was used twice.
(Bug #1711)
@item
Fixed directory permissions for the MySQL-server RPM documentation directory.
(Bug #1672)
@item
Fixed server crash when updating an @code{ENUM} column that is set to the
empty string (for example, with @code{REPLACE()}).  (Bug #2023)
@item
@command{mysql} client program now correctly prints connection identifier
returned by @code{mysql_thread_id()} as unsigned integer rather than as signed
integer.  (Bug #1951)
@item
@code{FOUND_ROWS()} could return incorrect number of rows after a query
with an impossible @code{WHERE} condition. (Bug #1468)
@item
@code{SHOW DATABASES} no longer shows @code{.sym} files (on Windows) that
do not point to a valid directory. (Bug #1385)
@item
Fixed a possible memory leak on Mac OS X when using the shared
@code{libmysql.so} library. (from @code{pthread_key_create()}). (Bug #2061)
@item
Fixed bug in @code{UNION} statement with alias @code{*}. (Bug #1249)
@item
Fixed a bug in @code{DELETE ... ORDER BY ... LIMIT} where the rows where not
deleted in the proper order. (Bug #1024, Bug #1697).
@item
Fixed serious problem with multi-threaded programs on Windows that used the
embedded MySQL libraries. (Locks of tables were not handled correctly between
different threads).
@item
Code cleanup: Fixed a few code defects (potential memory leaks, null pointer
dereferences, uninitialized variables). Thanks to Reasoning Inc. for
informing us about these findings.
@item
Fixed a buffer overflow error that occurred with prepended @samp{0} characters
in some columns of type @code{DECIMAL}. (Bug #2128)
@item
Filesort was never shown in @code{EXPLAIN} if query contained an
@code{ORDER BY NULL} clause. (Bug #1335)
@item
Fixed invalidation of whole query cache on @code{DROP DATABASE}. (Bug #1898)
@item
Fixed bug in range optimizer that caused wrong results for some unlikely
@code{AND}/@code{OR} queries. (Bug #1828)
@item
Fixed a crash in @code{ORDER BY} when ordering by expression and identifier.
(Bug #1945)
@item
Fixed a crash in an open @code{HANDLER} when an @code{ALTER TABLE} was
executed in a different connection. (Bug #1826)
@item
Fixed a bug in @code{trunc*} operator of full-text search which
sometimes caused MySQL not to find all matched rows.
@item
Fixed bug in prepending @samp{0} characters to @code{DECIMAL} column values.
@item
Fixed optimizer bug, introduced in 4.0.16, when @code{REF} access plan was
preferred to more efficient @code{RANGE} on another column.
@item
Fixed problem when installing a MySQL server as a Windows service using a
command of the form @command{mysqld --install mysql --defaults-file=@var{path-to-file}.}
(Bug #1643)
@item
Fixed an incorrect result from a query that uses only @code{const} tables
(such as one-row tables) and non-constant expression
(such as @code{RAND()}). (Bug #1271)
@item
Fixed bug when the optimizer did not take @code{SQL_CALC_FOUND_ROWS} into
account if @code{LIMIT} clause was present. (Bug #1274)
@item
@command{mysqlbinlog} now asks for a password at the console when the @code{-p}
or @code{--password} option is used with no argument. This is consistent with
the way that other clients such @command{mysqladmin} and @command{mysqldump}
already behave. @strong{Note}: A consequence of this change is that it is no
longer possible to invoke @command{mysqlbinlog} as @command{mysqlbinlog -p
pass_val} (with a space between the @code{-p} option and the following
password value).
(Bug #1595)
@item
Fixed bug accidentally introduced in 4.0.16 where the slave SQL thread
deleted its replicated temporary tables when @code{STOP SLAVE} was
issued.
@item
In a ``chain'' replication setup @code{A->B->C}, if 2 sessions on A
updated temporary tables of the same name at the same time, the binary log
of @code{B} became incorrect, resulting in @code{C} becoming confused.
(Bug #1686)
@item
In a ``chain'' replication setup @code{A->B->C}, if @code{STOP SLAVE}
was issued on @code{B} while it was replicating a temporary table from
@code{A}, then when @code{START SLAVE} was issued on @code{B}, the binary log
of @code{B} became incorrect, resulting in @code{C} becoming confused.
(Bug #1240)
@item
When @code{MASTER_LOG_FILE} and @code{MASTER_LOG_POS} were not
specified, @code{CHANGE MASTER} used the coordinates of the slave I/O
thread to set up replication, which broke replication if the slave SQL
thread lagged behind the slave I/O thread. This caused the slave
SQL thread to lose some events. The new behavior is to use the
coordinates of the slave SQL thread instead.
@xref{CHANGE MASTER TO,  , @code{CHANGE MASTER TO}}.
(Bug #1870)
@item
Now if integer is stored or converted to @code{TIMESTAMP} or
@code{DATETIME} value checks of year, month, day, hour, minute
and second ranges are performed and numbers representing illegal
timestamps are converted to 0 value. This behavior is consistent 
with manual and with behavior of string to 
@code{TIMESTAMP}/@code{DATETIME} conversion. (Bug #1448)
@item
Fixed bug when @code{BIT_AND()} and @code{BIT_OR()} group functions 
returned incorrect value if @code{SELECT} used a temporary table and
no rows were found. (Bug #1790).
@item
@code{BIT_AND()} is now unsigned in all contexts. This means that it will
now return 18446744073709551615 (= 0xffffffffffffffff) instead of -1 if
there were no rows in the result.
@item
Fixed bug with @code{BIT_AND()} still returning signed value for an
empty set in some cases. (Bug #1972)
@item
Fixed bug with @code{^} (XOR) and @code{>>} (bit shift) still returning
signed value in some cases. (Bug #1993)
@item
Replication:
a rare race condition in the slave SQL thread, which could lead to a
wrong complain that the relay log is corrupted. (Bug #2011)
@item
Replication:
in the slave SQL thread, a multiple-table @code{UPDATE} could produce a
wrong complain that some record was not found in one table, if the
@code{UPDATE} was preceded by a @code{INSERT ... SELECT}. (Bug #1701)
@item
Fixed deficiency in MySQL code which is responsible for scanning 
directories. This deficiency caused @code{SHOW TABLE STATUS} to be 
very slow when a database contained a large number of tables, even if a single 
particular table were specified. (Bug #1952)
@end itemize

@node News-4.0.16, News-4.0.15, News-4.0.17, News-4.0.x
@appendixsubsec Changes in release 4.0.16 (17 Oct 2003)

Functionality added or changed:
@itemize @bullet
@item
Option values in option files now may be quoted. This is useful for values that
contain whitespace or comment characters.
@item
Write memory allocation information to error log when doing
@command{mysqladmin debug}.  This works only on systems that support the
@code{mallinfo()} call (like newer Linux systems).
@item
Added the following new system variables to allow more precise memory
allocation: @code{range_alloc_block_size}, @code{query_alloc_block_size},
@code{query_prealloc_size}, @code{transaction_alloc_block_size}, and
@code{transaction_prealloc_size}.
@item
@command{mysqlbinlog} now reads option files. To make this work, you must now
specify @code{--read-from-remote-server} when reading binary logs from
a MySQL server. (Note that using a remote server is deprecated and may
disappear in future @command{mysqlbinlog} versions).
@item
Block @code{SIGPIPE} signals also for non-threaded programs. The blocking is moved
from @code{mysql_init()} to @code{mysql_server_init()}, which is
automatically called on the first call to @code{mysql_init()}.
@item
Added @code{--libs_r} and @code{--include} options to @command{mysql_config}.
@item
New @code{`>} prompt for @command{mysql}. This prompt is similar to the
@code{'>} and @code{">} prompts, but indicates that an identifier
quoted with backticks was begun on an earlier line and the closing backtick
has not yet been seen.
@item
Updated @command{mysql_install_db} to be able to use the local machine's IP
address instead of the hostname when building the initial grant tables if
@code{skip-name-resolve} has been specified. This
option can be helpful on FreeBSD to avoid thread-safety problems with the
FreeBSD resolver libraries. (Thanks to Jeremy Zawodny for the patch.)
@item
A documentation change: Added a note that when backing up a slave, it is
necessary also to back up the @file{master.info} and @file{relay-log.info}
files, as well as any @file{SQL_LOAD-*} files located in the directory
specified by the @code{--slave-load-tmpdir} option.  All these files are
needed when the slave resumes replication after you restore the slave's data.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Fixed a spurious error @code{ERROR 14: Can't change size of file (Errcode: 2)}
on Windows in @code{DELETE FROM @var{tbl_name}} without a @code{WHERE} clause or
@code{TRUNCATE TABLE @var{tbl_name}}, when @var{tbl_name} is a @code{MyISAM}
table. (Bug #1397)
@item
Fixed a bug that resulted in @code{thr_alarm queue is full} warnings after
increasing the @code{max_connections} variable with @code{SET GLOBAL}.
(Bug #1435)
@item
Made @code{LOCK TABLES} to work when @code{Lock_tables_priv} is granted on the
database level and @code{Select_priv} is granted on the table level.
@item
Fixed crash of @code{FLUSH QUERY CACHE} on queries that use same table
several times (Bug #988).
@item
Fixed core dump bug when setting an enum system variable (such as
@code{SQL_WARNINGS}) to @code{NULL}.
@item
Extended the default timeout value for Windows clients from 30 seconds
to 1 year.  (The timeout that was added in MySQL 4.0.15 was way too
short).  This fixes a bug that caused @code{ERROR 2013: Lost connection
to MySQL server during query} for queries that lasted longer than 30 seconds,
if the client didn't specify a limit with @code{mysql_options()}. Users of
4.0.15 on Windows should upgrade to avoid this problem.
@item
More ``out of memory'' checking in range optimizer.
@item
Fixed and documented a problem when setting and using a user variable within the
same @code{SELECT} statement. (Bug #1194).
@item
Fixed bug in overrun check for @code{BLOB} values with compressed tables.
This was a bug introduced in 4.0.14.  It caused MySQL to regard some
correct tables containing @code{BLOB} values as corrupted.
(Bug #770, Bug #1304, and maybe Bug #1295)
@item
@code{SHOW GRANTS} showed @code{USAGE} instead of the real column-level
privileges when no table-level privileges were given.
@item
When copying a database from the master, @code{LOAD DATA FROM
MASTER} dropped the corresponding database on the slave, thus erroneously
dropping tables that had no counterpart on the master and tables that
may have been excluded from replication using @code{--replicate-*-table}
rules. Now @code{LOAD DATA FROM MASTER} no longer drops the database.
Instead, it drops only the tables that have a counterpart on the master
and that match the @code{--replicate-*-table}
rules. @code{--replicate-*-db} rules can still be used to include or exclude a
database as a whole from @code{LOAD DATA FROM MASTER}. A database will
also be included or excluded as a whole if there are some rules like
@code{--replicate-wild-do-table=db1.%} or
@code{--replicate-wild-ignore-table=db1.%}, as is already the case for
@code{CREATE DATABASE} and @code{DROP DATABASE} in replication. (Bug
#1248)
@item
Fixed a bug where
@command{mysqlbinlog} crashed with a segmentation fault when used with the
@code{-h} or @code{--host} option. (Bug #1258)
@item
Fixed a bug where @command{mysqlbinlog} crashed with a segmentation fault
when used on a binary log containing only final events for @code{LOAD
DATA}. (Bug #1340)
@item
@command{mysqlbinlog} will not reuse temporary filenames from previous runs.
Previously @command{mysqlbinlog} failed if was used several times on the same
binary log file that contained a @code{LOAD DATA} command.
@item
Fixed compilation problem when compiling with OpenSSL 0.9.7 with
disabled old DES support (If @code{OPENSSL_DISABLE_OLD_DES_SUPPORT} 
option was enabled).
@item
Fixed a bug when two (or more) MySQL servers were running on the same machine,
and they were both slaves, and at least one of them was replicating some
@code{LOAD DATA INFILE} command from its master.
The bug was that one slave MySQL server sometimes
deleted the @file{SQL_LOAD-*} files (used for replication of
@code{LOAD DATA INFILE} and located in the @code{slave-load-tmpdir} directory,
which defaults to @code{tmpdir}) belonging to the other slave MySQL server of
this machine, if these slaves had the same @code{slave-load-tmpdir} directory.
When that happened, the other slave could not replicate
@code{LOAD DATA INFILE} and complained about not being able to open some
@code{SQL_LOAD-*} file. (Bug #1357)
@item
If @code{LOAD DATA INFILE} failed for a small file, the master forgot to
write a marker (a @code{Delete_file} event) in its binary log, so the slave
could not delete 2 files (@file{SQL_LOAD-*.info} and
@file{SQL_LOAD-*.data} from its @code{tmpdir}. (Bug #1391)
@item
On Windows, the slave forgot to delete a @code{SQL_LOAD-*.info}
file from @code{tmpdir} after successfully replicating a @code{LOAD DATA
INFILE} command. (Bug #1392)
@item
When a connection terminates, MySQL writes @code{DROP TEMPORARY TABLE}
statements to the binary log for all temporary tables which the
connection had not explicitly dropped. MySQL forgot to use backticks to quote
the database and table names in the statement. (Bug #1345)
@item
On some 64-bit machines (some HP-UX and Solaris machines), a slave
installed with the 64-bit MySQL binary could not connect to its master
(it connected to itself instead). (Bug #1256, Bug #1381)
@item
Code was introduced in MySQL 4.0.15 for the slave to detect that the master
had died while writing a transaction to its binary log. This code reported an
error in a legal situation: When the slave I/O thread was stopped while
copying a transaction to the relay log, the slave SQL thread would later
pretend that it found an unfinished transaction. (Bug #1475)
@end itemize

@node News-4.0.15, News-4.0.14, News-4.0.16, News-4.0.x
@appendixsubsec Changes in release 4.0.15 (03 Sep 2003)

@strong{IMPORTANT}:

If you are using this release on Windows, you should upgrade at least your
clients (any program that uses @code{libmysql.lib}) to 4.0.16 or above.  This
is because the 4.0.15 release had a bug in the Windows client library that
causes Windows clients using the library to die with a @code{Lost connection
to MySQL server during query} error for queries that take more than 30
seconds.  This problem is specific to Windows; clients on other platforms are
unaffected.

Functionality added or changed:
@itemize @bullet
@item
@command{mysqldump} now correctly quotes all identifiers when communicating
with the server. This assures that during the dump process, @command{mysqldump}
will never send queries to the server that result in a syntax error.
This problem is @strong{not} related to the
@command{mysqldump} program's output, which was not changed. (Bug #1148)
@item
Change result set metadata information so that @code{MIN()} and @code{MAX()}
report that they can return @code{NULL} (this is true because an
empty set will return @code{NULL}). (Bug #324)
@item
Produce an error message on Windows if a second @command{mysqld} server is
started on the same TCP/IP port as an already running @command{mysqld} server.
@item
The @command{mysqld} system variables @code{wait_timeout},
@code{net_read_timeout}, and @code{net_write_timeout} now work on Windows.
One can now also set timeouts for read and writes in Windows clients with
@code{mysql_options()}.
@item
Added option @code{--sql-mode=NO_DIR_IN_CREATE} to make it possible for
slaves to ignore @code{INDEX DIRECTORY} and
@code{DATA DIRECTORY} options given to @code{CREATE TABLE}.
When this is mode is on, @code{SHOW CREATE TABLE} will not show the
given directories.
@item
@code{SHOW CREATE TABLE} now shows the @code{INDEX DIRECTORY} and
@code{DATA DIRECTORY} options, if they were specified when the table was
created.
@item
The @code{open_files_limit} system variable now shows the real open files limit.
@item
@code{MATCH ... AGAINST()} in natural language mode
now treats words that are present
in more than 2,000,000 rows as stopwords.
@item
The Mac OS X installation disk images now include an additional
@file{MySQLStartupItem.pkg} package that enables the automatic
startup of MySQL on system startup.
@xref{Mac OS X installation}.
@item
Most of the documentation included in the binary tarball distributions
(@code{.tar.gz}) has been moved into a subdirectory @code{docs}.
@xref{Installation layouts}.
@item
The manual is now included as an additional @code{info} file in the binary
distributions. (Bug #1019)
@item
The binary distributions now include the embedded server library 
(@code{libmysqld.a}) by default. Due to a linking problem with non-gcc
compilers, it was not included in all packages of the initial 4.0.15
release. The affected packages were rebuilt and released as 4.0.15a.
@xref{Nutshell Embedded MySQL}.
@item
MySQL can now use range optimization for @code{BETWEEN} with
non-constant limits. (Bug #991)
@item
Replication error messages now include the default database, so that
users can check which database the failing query was run for.
@item
A documentation change: Added a paragraph about how the
@code{binlog-do-db} and @code{binlog-ignore-db} options are tested
against the database on the master (@pxref{Binary log}), and a
paragraph about how @code{--replicate-do-db}, @code{--replicate-do-table}
and analogous options are tested against the database and tables on the
slave (@pxref{Replication Options}).
@item
Now the slave does not replicate @code{SET PASSWORD}
if it is configured to exclude the @code{mysql} database from
replication (using for example
@code{--replicate-wild-ignore-table=mysql.%}). This was already the
case for @code{GRANT} and @code{REVOKE} since version 4.0.13 (although
there was Bug #980 in 4.0.13 & 4.0.14, which has been fixed in
4.0.15).
@item
Rewrote the information shown in the @code{State} column of @code{SHOW
PROCESSLIST} for replication threads and for @code{MASTER_POS_WAIT()}
and added the most common states for these threads to the
documentation, @pxref{Replication Implementation Details}.
@item
Added a test in replication to detect the case where the master died
in the middle of writing a transaction to the binary log; such unfinished
transactions now trigger an error message on the slave.
@item
A @code{GRANT} command that creates an anonymous user
(that is, an account with an empty username) no longer requires
@code{FLUSH PRIVILEGES} for the account to be recognized by the server.
(Bug #473)
@item
@code{CHANGE MASTER} now flushes @file{relay-log.info}. Previously
this was deferred to the next run of @code{START SLAVE}, so if
@command{mysqld} was shutdown on the slave after @code{CHANGE MASTER}
without having run @code{START SLAVE}, the relay log's name and
position were lost. At restart they were reloaded from
@file{relay-log.info}, thus reverting to their old (incorrect) values from
before @code{CHANGE MASTER} and leading to error messages 
(as the old relay log did not exist any more) and the slave threads
refusing to start. (Bug #858)
@end itemize

Bugs fixed:
@itemize @bullet
@item
Fixed buffer overflow in password handling which could potentially be
exploited by MySQL users with @code{ALTER} privilege on the
@code{mysql.user} table to execute random code or to gain shell access with
the UID of the @command{mysqld} process (thanks to Jedi/Sector One for spotting and
reporting this bug).
@item
Fixed server crash on @code{FORCE INDEX} in a query that contained
"Range checked for each record" in the @code{EXPLAIN} output. (Bug #1172)
@item
Fixed table/column grant handling: The proper sort order (from most specific
to less specific, @pxref{Request access}) was not honored. (Bug #928)
@item
Fixed rare bug in @code{MYISAM} introduced in 4.0.3 where the index file header
was not updated directly after an @code{UPDATE} of split dynamic rows.
The symptom was that the table had a corrupted delete-link if @command{mysqld}
was shut down or the table was checked directly after the update.
@item
Fixed @code{Can't unlock file} error when running
@command{myisamchk --sort-index} on Windows. (Bug #1119)
@item
Fixed possible deadlock when changing @code{key_buffer_size} while
the key cache was actively used. (Bug #1088)
@item
Fixed overflow bug in @code{MyISAM} and @code{ISAM} when a row is updated
in a table with a large number of columns and at least one @code{BLOB/TEXT}
column.
@item
Fixed incorrect result when doing @code{UNION} and @code{LIMIT #,#} when
braces were not used around the @code{SELECT} parts.
@item
Fixed incorrect result when doing @code{UNION} and @code{ORDER BY .. LIMIT #}
when one didn't use braces around the @code{SELECT} parts.
@item
Fixed problem with @code{SELECT SQL_CALC_FOUND_ROWS ... UNION ALL ... LIMIT #}
where @code{FOUND_ROWS()} returned incorrect number of rows.
@item
Fixed unlikely stack bug when having a BIG expression of
type @code{1+1-1+1-1...} in certain combinations. (Bug #871)
@item
Fixed the bug that sometimes prevented a table with a @code{FULLTEXT} index
from being marked as "analyzed".
@item
Fixed MySQL so that the column length (in C API) for the second column in
@code{SHOW CREATE TABLE} is always larger than the data length.
The only known application that was affected by the old behavior was
Borland dbExpress, which truncated the output from the command.
(Bug #1064)
@item
Fixed crash in comparisons of strings using the @code{tis620} character
set. (Bug #1116)
@item
Fixed @code{ISAM} bug in @code{MAX()} optimization.
@item
@command{myisamchk --sort-records=N} no longer marks table as crashed if
sorting failed because of an inappropriate key. (Bug #892)
@item
Fixed a minor bug in @code{MyISAM} compressed table handling that sometimes
made it impossible to repair compressed table in "Repair by sort" mode.
"Repair with keycache" (@command{myisamchk --safe-recover}) worked, though.
(Bug #1015)
@item
Fixed bug in propagating the version number to the manual included in
the distribution files. (Bug #1020)
@item
Fixed key sorting problem (a @code{PRIMARY} key declared for a column
that is not explicitly marked @code{NOT NULL} was sorted after a
@code{UNIQUE} key for a @code{NOT NULL} column).
@item
Fixed the result of @code{INTERVAL} when applied to a @code{DATE} value.
(Bug #792)
@item
Fixed compiling of the embedded server library in the RPM spec file.
(Bug #959)
@item
Added some missing files to the RPM spec file and fixed some RPM building
errors that occurred on Red Hat Linux 9. (Bug #998)
@item
Fixed incorrect @code{XOR} evaluation in @code{WHERE} clause. (Bug #992)
@item
Fixed bug with processing in query cache merged tables constructed
from more then 255 tables. (Bug #930) 
@item
Fixed incorrect results from outer join query (for example, @code{LEFT JOIN})
when @code{ON} condition is always false, and range search in used.  
(Bug #926)
@item
Fixed a bug causing incorrect results from @code{MATCH ... AGAINST()} in some
joins. (Bug #942)
@item
@code{MERGE} tables do not ignore @code{Using index} (from @code{EXPLAIN} output)
anymore.
@item
Fixed a bug that prevented an empty table from being marked as "analyzed".
(Bug #937)
@item
Fixed @command{myisamchk --sort-records} crash when used on compressed table.
@item
Fixed slow (as compared to 3.23)
@code{ALTER TABLE} and related commands such as @code{CREATE INDEX}.
(Bug #712)
@item
Fixed segmentation fault resulting from @code{LOAD DATA FROM MASTER} when
the master was running without the @code{--log-bin} option. (Bug #934)
@item
Fixed a security bug: A server compiled without SSL support still allowed
connections by users who had the @code{REQUIRE SSL} option specified for
their accounts.
@item
Fixed a random bug: Sometimes the slave would replicate @code{GRANT}
or @code{REVOKE} queries even if it was configured to exclude the
@code{mysql} database from replication (for example, using
@code{--replicate-wild-ignore-table=mysql.%}). (Bug #980)
@item
The @code{Last_Errno} and @code{Last_Error} fields in the output of
@code{SHOW SLAVE STATUS} are now cleared by @code{CHANGE MASTER} and
when the slave SQL thread starts. (Bug #986)
@item
A documentation mistake: It said that @code{RESET SLAVE} does not change
connection information  (master host, port, user, and
password), whereas it does. The statement resets these to the startup options
(@code{master-host} etc) if there were some. (Bug #985)
@item
@code{SHOW SLAVE STATUS} now shows correct information (master host,
port, user, and password) after @code{RESET SLAVE}
(that is, it shows the new values, which are copied from the startup
options if there were some). (Bug #985)
@item
Disabled propagation of the original master's log position for events because
this caused unexpected values for @code{Exec_Master_Log_Pos} and problems
with @code{MASTER_POS_WAIT()} in A->B->C replication setup. (Bug #1086)
@item
Fixed a segfault in @command{mysqlbinlog} when
@code{--position=x} was used with @code{x} being between a
@code{Create_file} event and its fellow @code{Append_block},
@code{Exec_load} or @code{Delete_file} events. (Bug #1091)
@item
@command{mysqlbinlog} printed superfluous warnings when using
@code{--database}, which caused syntax errors when piped to
@command{mysql}. (Bug #1092)
@item
Made @command{mysqlbinlog --database} filter @code{LOAD DATA INFILE} too
(previously, it filtered all queries except @code{LOAD DATA
INFILE}). (Bug #1093)
@item
@command{mysqlbinlog} in some cases forgot to put a leading @code{'#'} in
front of the original @code{LOAD DATA INFILE} (this command is
displayed only for information, not to be run; it is later reworked to
@code{LOAD DATA LOCAL} with a different filename, for execution by
@command{mysql}). (Bug #1096)
@item
@code{binlog-do-db} and @code{binlog-ignore-db} incorrectly filtered
@code{LOAD DATA INFILE} (it was half-written to the binary log). This
resulted in a corrupted binary log, which could cause the slave to
stop with an error. (Bug #1100)
@item
When, in a transaction, a transactional table (such as an @code{InnoDB} table)
was updated, and later in the same transaction a
non-transactional table (such as a @code{MyISAM} table) was
updated using the updated content of the transactional table
(with @code{INSERT ... SELECT} for example), the queries were written
to the binary log in an incorrect order. (Bug #873)
@item
When, in a transaction, @code{INSERT ... SELECT} updated a
non-transactional table, and @code{ROLLBACK} was issued, no error was
returned to the client. Now the client is warned that some changes
could not be rolled back, as this was already the case for normal
@code{INSERT}. (Bug #1113)
@item
Fixed a potential bug: When @code{STOP SLAVE} was run while the slave
SQL thread was in the middle of a transaction, and then @code{CHANGE
MASTER} was used to point the slave to some non-transactional
statement, the slave SQL thread could get confused (because it would
still think, from the past, that it was in a transaction).
@end itemize

@node News-4.0.14, News-4.0.13, News-4.0.15, News-4.0.x
@appendixsubsec Changes in release 4.0.14 (18 Jul 2003)

Functionality added or changed:
@itemize @bullet
@item
Added @code{default_week_format} system variable. The value is used as the
default mode for the @code{WEEK()} function.
@item
@command{mysqld} now reads an additional option file group having a name
corresponding to the server's release series:
@code{[mysqld-4.0]} for 4.0.x servers, @code{[mysqld-4.1]} for 4.1.x servers,
and so forth. This allows options to be specified on a series-specific basis.
@item
The @code{CONCAT_WS()} function no longer skips empty strings. (Bug #586).
@item
@code{InnoDB} now supports indexing a prefix of a column. This means, in
particular, that @code{BLOB} and @code{TEXT} columns can be indexed in
@code{InnoDB} tables, which was not possible before.
@item
A documentation change: Function @code{INTERVAL(NULL, ...)} returns @code{-1}.
@item
Enabled @code{INSERT} from @code{SELECT} when the table into which the records
are inserted is also a table listed in the @code{SELECT}.
@item
Allow @code{CREATE TABLE} and @code{INSERT} from any @code{UNION}.
@item
The @code{SQL_CALC_FOUND_ROWS} option now always returns the total number 
of rows for any @code{UNION}.
@item
Removed @code{--table} option from @command{mysqlbinlog} 
to avoid repeating @command{mysqldump} functionality.
@item
Comment lines in option files can now start from the middle of a line, too
(like @code{basedir=c:\mysql # installation directory}).
@item
Changed optimizer slightly to prefer index lookups over full table scans
in some boundary cases.
@item
Added thread-specific @code{max_seeks_for_key} variable that can
be used to force the optimizer to use keys instead of table scans
even if the cardinality of the index is low.
@item
Added optimization that converts @code{LEFT JOIN} to normal join in
some cases.
@item
A documentation change: added a paragraph about failover in
replication (how to use a surviving slave as the new master, how to
resume to the original setup). @xref{Replication FAQ}.
@item
A documentation change: added warning notes about safe use of the
@code{CHANGE MASTER} command. @xref{CHANGE MASTER TO}.
@item
MySQL now issues a warning (not an error, as in 4.0.13)
when it opens a table that was created with MySQL 4.1.
@item
Added @code{--nice} option to @command{mysqld_safe} to allow setting the
niceness of the @command{mysqld} process. (Thanks to Christian Hammers for
providing the initial patch.) (Bug #627)
@item
Added @code{--read-only} option to cause @command{mysqld} to allow no updates
except from slave threads or from users with the @code{SUPER} privilege.
(Original patch from Markus Benning).
@item
@code{SHOW BINLOG EVENTS FROM x} where @code{x} is less than 4 now
silently converts @code{x} to 4 instead of printing an error. The same change
was done for @code{CHANGE MASTER TO MASTER_LOG_POS=x} and 
@code{CHANGE MASTER TO RELAY_LOG_POS=x}.
@item
@command{mysqld} now only adds an interrupt handler for the @code{SIGINT} signal
if you start it with the new @code{--gdb} option.  This is because some
MySQL users encountered strange problems when they accidentally sent @code{SIGINT} to
@command{mysqld} threads.
@item
@code{RESET SLAVE} now clears the @code{Last_Errno} and
@code{Last_Error} fields in the output of @code{SHOW SLAVE STATUS}.
@item
Added @code{max_relay_log_size} variable; the relay log will be rotated
automatically when its size exceeds @code{max_relay_log_size}. But if
@code{max_relay_log_size} is 0 (the default), @code{max_binlog_size}
will be used (as in older versions). @code{max_binlog_size} still
applies to binary logs in any case.
@item
@code{FLUSH LOGS} now rotates relay logs in addition to the other types of
logs it already rotated.
@item
The @code{DELAYED} keyword in @code{INSERT DELAYED} no longer causes an
error for @code{InnoDB} tables. Now it is silently ignored.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Comparison/sorting for @code{latin1_de} character set was rewritten.
The old algorithm could not handle cases like @code{"s@"a" > "@ss{}a"}.
@xref{German character set}. In rare cases it resulted in table
corruption.
@item
Fixed a problem with the password prompt on Windows. (Bug #683)
@item
@code{ALTER TABLE ... UNION=(...)} for @code{MERGE} table is now allowed
even if some underlying @code{MyISAM} tables are read-only. (Bug #702)
@item
Fixed a problem with @code{CREATE TABLE t1 SELECT x'41'}. (Bug #801)
@item
Removed some incorrect lock warnings from the error log.
@item
Fixed memory overrun when doing @code{REPAIR TABLE} on a table with a
multiple-part auto_increment key where one part was a packed @code{CHAR}.
@item
Fixed a probable race condition in the replication code that could
potentially lead to @code{INSERT} statements not being replicated in the
event of a @code{FLUSH LOGS} command or when the binary log exceeds
@code{max_binlog_size}. (Bug #791)
@item
Fixed a crashing bug in @code{INTERVAL} and @code{GROUP BY} or 
@code{DISTINCT}. (Bug #807)
@item
Fixed bug in @command{mysqlhotcopy} so it actually aborts for unsuccessful
table copying operations.  Fixed another bug so that it succeeds
when there are thousands of tables to copy. (Bug #812)
@item
Fixed problem with @command{mysqlhotcopy} failing to read options from option
files. (Bug #808)
@item
Fixed bugs in optimizer that sometimes prevented MySQL from using
@code{FULLTEXT} indexes even though it was possible (for example, in
@code{SELECT * FROM t1 WHERE MATCH a,b AGAINST("index") > 0}).
@item
Fixed a bug with ``table is full'' in @code{UNION} operations.
@item
Fixed a security problem that enabled users with no privileges to obtain
information on the list of existing databases by using @code{SHOW TABLES} and
similar commands.
@item
Fixed a stack problem on UnixWare/OpenUnix.
@item
Fixed a configuration problem on UnixWare/OpenUNIX and OpenServer.
@item
Fixed a stack overflow problem in password verification.
@item
Fixed a problem with @code{max_user_connections}.
@item
@code{HANDLER} without an index now works properly when a table has deleted 
rows. (Bug #787)
@item
Fixed a bug with @code{LOAD DATA} in @command{mysqlbinlog}. (Bug #670)
@item
Fixed that @code{SET CHARACTER SET DEFAULT} works. (Bug #462)
@item
Fixed @code{MERGE} table behavior in @code{ORDER BY ... DESC} queries.
(Bug #515)
@item
Fixed server crash on @code{PURGE MASTER LOGS} or @code{SHOW MASTER LOGS}
when the binary log is off. (Bug #733)
@item
Fixed password-checking problem on Windows. (Bug #464)
@item
Fixed the bug in comparison of a @code{DATETIME} column and an integer
constant.  (Bug #504)
@item
Fixed remote mode of @command{mysqlbinlog}. (Bug #672)
@item
Fixed @code{ERROR 1105: Unknown error} that occurred for some @code{SELECT}
queries, where a column that was declared as @code{NOT NULL} was compared
with an expression that took @code{NULL} value.
@item
Changed timeout in @code{mysql_real_connect()} to use @code{poll()} instead of
@code{select()} to work around problem with many open files in the client.
@item
Fixed incorrect results from @code{MATCH ... AGAINST} used with a
@code{LEFT JOIN} query.
@item
Fixed a bug that limited the maximum value for @command{mysqld} variables
to 4294967295 when they are specified on the command line.
@item
Fixed a bug that sometimes caused spurious ``Access denied'' errors
in @code{HANDLER ... READ} statements, when a table is referenced
via an alias.
@item
Fixed portability problem with @code{safe_malloc}, which caused MySQL to
give "Freeing wrong aligned pointer" errors on SCO 3.2.
@item
@code{ALTER TABLE ... ENABLE/DISABLE KEYS} could cause a core dump when
done after an @code{INSERT DELAYED} statement on the same table.
@item
Fixed problem with conversion of localtime to GMT where some times resulted in
different (but correct) timestamps. Now MySQL should use the smallest
possible timestamp value in this case.  (Bug #316)
@item
Very small query cache sizes could crash @command{mysqld}. (Bug #549)
@item
Fixed a bug (accidentally introduced by us but present only in version 4.0.13)
that made @code{INSERT ... SELECT} into an @code{AUTO_INCREMENT} column
not replicate well. This bug is in the master, not in the slave.
(Bug #490)
@item
Fixed a bug: When an @code{INSERT ... SELECT} statement inserted rows into a
non-transactional table, but failed at some point (for example, due to
a ``Duplicate key'' error), the query was not written to the binary log.
Now it is written to the binary log, with its error code, as all other
queries are. About the @code{slave-skip-errors} option for how to
handle partially completed queries in the slave, see @ref{Replication
Options}. (Bug #491)
@item
@code{SET FOREIGN_KEY_CHECKS=0} was not replicated properly.
The fix probably will not be backported to 3.23.
@item
On a slave, @code{LOAD DATA INFILE} which had no @code{IGNORE} or
@code{REPLACE} clause on the master, was replicated with @code{IGNORE}.
While this is not a problem if the master and slave data are identical
(a @code{LOAD} that produces no duplicate conflicts on the master will
produce none on the slave anyway), which is true in normal operation, it
is better for debugging not to silently add the @code{IGNORE}. That way,
you can get an error message on the slave and discover that for some
reason, the data on master and slave are different and investigate why.
(Bug #571)
@item
On a slave, @code{LOAD DATA INFILE} printed an incomplete ``Duplicate entry
'%-.64s' for key %d''' message (the key name and value were not mentioned)
in case of duplicate conflict (which does not happen in normal operation).
(Bug #573)
@item
When using a slave compiled with @code{--debug}, @code{CHANGE MASTER
TO RELAY_LOG_POS} could cause a debug assertion failure. (Bug #576)
@item
When doing a @code{LOCK TABLES WRITE} on an @code{InnoDB} table, commit could
not happen, if the query was not written to the binary log (for example, if
@code{--log-bin} was not used, or @code{binlog-ignore-db} was
used). (Bug #578)
@item
If a 3.23 master had open
temporary tables that had been replicated to a 4.0 slave, and
the binary log got rotated, these temporary tables were immediately 
dropped by the slave (which caused problems if the master used them
subsequently). This bug had been fixed in 4.0.13, but in a manner
which caused an unlikely inconvenience: If the 3.23 master died
brutally (power failure), without having enough time to automatically
write @code{DROP TABLE} statements to its binary log, then the 4.0.13
slave would not notice the temporary tables have to be dropped, until the
slave @command{mysqld} server is restarted. This minor inconvenience is
fixed in 3.23.57 and 4.0.14 (meaning the master must be upgraded to
3.23.57 and the slave to 4.0.14 to remove the inconvenience). (Bug #254)
@item
If @code{MASTER_POS_WAIT()} was waiting, and the slave was idle, and
the slave SQL thread terminated, @code{MASTER_POS_WAIT()} would wait
forever. Now when the slave SQL thread terminates,
@code{MASTER_POS_WAIT()} immediately returns @code{NULL} (``slave
stopped''). (Bug #651)
@item
After @code{RESET SLAVE; START SLAVE;}, the @code{Relay_Log_Space} value
displayed by @code{SHOW SLAVE STATUS} was too big by four bytes. (Bug #763)
@item
If a query was ignored on the slave (because of
@code{--replicate-ignore-table} and other similar rules), the slave
still checked if the query got the same error code (0, no error) as on
the master. So if the master had an error on the query (for example,
``Duplicate entry'' in a multiple-row insert), then the slave stopped
and warned that the error codes didn't match. (Bug #797)
@end itemize

@node News-4.0.13, News-4.0.12, News-4.0.14, News-4.0.x
@appendixsubsec Changes in release 4.0.13 (16 May 2003)

Functionality added or changed:
@itemize @bullet
@item
@code{PRIMARY KEY} now implies @code{NOT NULL}. (Bug #390)
@item
The Windows binary packages are now compiled with
@code{--enable-local-infile} to match the Unix build configuration.
@item
Removed timing of tests from @command{mysql-test-run}. @code{time} does not
accept all required parameters on many platforms (for example, QNX) and timing
the tests is not really required (it's not a benchmark anyway).
@item
@code{SHOW MASTER STATUS} and @code{SHOW SLAVE STATUS} required the
@code{SUPER} privilege; now they accept @code{REPLICATION CLIENT} as well.
(Bug #343)
@item 
Added multi-threaded @code{MyISAM} repair optimization and
@code{myisam_repair_threads} variable to enable it.
@xref{Server system variables}.
@item 
Added @code{innodb_max_dirty_pages_pct} variable which controls amount of
dirty pages allowed in @code{InnoDB} buffer pool.
@item
@code{CURRENT_USER()} and @code{Access denied} error messages now report the
hostname exactly as it was specified in the @code{GRANT} command.
@item
Removed benchmark results from the source and binary distributions. They
are still available in the BK source tree, though.
@item
@code{InnoDB} tables now support @code{ANALYZE TABLE}.
@item
MySQL now issues an error when it opens a table that was created with
MySQL 4.1.
@item
Option @code{--new} now changes binary items (@code{0xFFDF}) to be
treated as binary strings instead of numbers by default. This fixes some
problems with character sets where it's convenient to input the string
as a binary item.  After this change you have to convert the binary
string to @code{INTEGER} with a @code{CAST} if you want to compare two
binary items with each other and know which one is bigger than the other.
@code{SELECT CAST(0xfeff AS UNSIGNED) < CAST(0xff AS UNSIGNED)}.
This will be the default behavior in MySQL 4.1. (Bug #152)
@item
Enabled @code{delayed_insert_timeout} on Linux (most modern @code{glibc}
libraries have a fixed @code{pthread_cond_timedwait()}). (Bug #211)
@item
Don't create more insert delayed threads than given by
@code{max_delayed_threads}. (Bug #211)
@item
Changed @code{UPDATE ... LIMIT} to apply the limit to rows that were matched,
whether or not they actually were changed. Previously the limit was applied
as a restriction on the number of rows changed.
@item
Tuned optimizer to favor clustered index over table scan.
@item
@code{BIT_AND()} and @code{BIT_OR()} now return an unsigned 64-bit value.
@item
Added warnings to error log of why a secure connection failed (when
running with @code{--log-warnings}).
@item
Deprecated options @code{--skip-symlink} and @code{--use-symbolic-links} and
replaced these with @code{--symbolic-links}.
@item
The default option for @code{innodb_flush_log_at_trx_commit} was changed
from 0 to 1 to make @code{InnoDB} tables ACID by default.
@xref{InnoDB start, , @code{InnoDB} start}.
@item
Added a feature to @code{SHOW KEYS} to display keys that are disabled by 
@code{ALTER TABLE DISABLE KEYS} command.
@item
When using a non-existing table type with @code{CREATE TABLE}, first
try if the default table type exists before falling back to @code{MyISAM}.
@item
Added @code{MEMORY} as an alias for @code{HEAP}.
@item
Renamed function @code{rnd} to @code{my_rnd} as the name was too generic
and is an exported symbol in @code{libmysqlclient} (thanks to Dennis Haney
for the initial patch).
@item
Portability fix: renamed @file{include/dbug.h} to
@file{include/my_dbug.h}.
@item
@command{mysqldump} no longer silently deletes the binary logs when invoked with
the @code{--master-data} or @code{--first-slave} option;
while this behavior was convenient for some
users, others may suffer from it. Now you must explicitly ask for binary
logs to be deleted by using the new @code{--delete-master-logs} option.
@item
If the slave is configured (using for example
@code{--replicate-wild-ignore-table=mysql.%})
to exclude @code{mysql.user}, @code{mysql.host}, @code{mysql.db},
@code{mysql.tables_priv} and @code{mysql.columns_priv} from
replication, then @code{GRANT} and @code{REVOKE} will not be replicated.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Logged @code{Access denied} error message had incorrect @code{Using password}
value. (Bug #398)
@item
Fixed bug with @code{NATURAL LEFT JOIN}, @code{NATURAL RIGHT JOIN} and
@code{RIGHT JOIN} when using many joined tables.  The problem was that
the @code{JOIN} method was not always associated with the tables
surrounding the @code{JOIN} method.  If you have a query that uses many
@code{RIGHT JOIN} or @code{NATURAL ... JOINS} you should verify that they
work as you expected after upgrading MySQL to this version. (Bug #291)
@item
Fixed @command{mysql} parser not to erroneously interpret @samp{'} or @samp{"}
characters within @code{/* ... */} comment as beginning a quoted string.
@item
@command{mysql} command-line client no longer looks for @code{\*} commands
inside backtick-quoted strings.
@item
Fixed @code{Unknown error} when using @code{UPDATE ... LIMIT}. (Bug #373)
@item
Fixed problem with ANSI mode and @code{GROUP BY} with constants. (Bug #387)
@item
Fixed bug with @code{UNION} and @code{OUTER JOIN}. (Bug #386)
@item
Fixed bug if one used a multiple-table @code{UPDATE} and the query required a
temporary table bigger than @code{tmp_table_size}. (Bug #286)
@item
Run @command{mysql_install_db} with the @code{-IN-RPM} option for the Mac OS X
installation to not fail on systems with improperly configured hostname
configurations.
@item
@code{LOAD DATA INFILE} will now read @code{000000} as a zero date instead as
@code{"2000-00-00"}.
@item
Fixed bug that caused @code{DELETE FROM table WHERE const_expression}
always to delete the whole table (even if expression result was false).
(Bug #355)
@item
Fixed core dump bug when using @code{FORMAT('nan',#)}. (Bug #284)
@item
Fixed name resolution bug with @code{HAVING ... COUNT(DISTINCT ...)}.
@item
Fixed incorrect result from truncation operator (@code{*}) in
@code{MATCH ... AGAINST()} in some complex joins.
@item
Fixed a crash in @code{REPAIR ... USE_FRM} command, when used on read-only,
nonexisting table or a table with a crashed index file.
@item
Fixed a crashing bug in @command{mysql} monitor program.  It occurred if
program was started with @code{--no-defaults}, with a prompt that contained
the hostname and a connection to a non-existent database was requested.
@item
Fixed problem when comparing a key for a multi-byte character set. (Bug #152)
@item
Fixed bug in @code{LEFT}, @code{RIGHT} and @code{MID} when used with
multi-byte character sets and some @code{GROUP BY} queries. (Bug #314)
@item
Fix problem with @code{ORDER BY} being discarded for some
@code{DISTINCT} queries. (Bug #275)
@item
Fixed that @code{SET SQL_BIG_SELECTS=1} works as documented (This corrects
a new bug introduced in 4.0)
@item
Fixed some serious bugs in @code{UPDATE ... ORDER BY}. (Bug #241)
@item
Fixed unlikely problem in optimizing @code{WHERE} clause with constant
expression like in @code{WHERE 1 AND (a=1 AND b=1)}.
@item
Fixed that @code{SET SQL_BIG_SELECTS=1} works again.
@item
Introduced proper backtick quoting for db.table in @code{SHOW GRANTS}.
@item
@code{FULLTEXT} index stopped working after @code{ALTER TABLE}
that converts @code{TEXT} column to @code{CHAR}. (Bug #283)
@item
Fixed a security problem with @code{SELECT} and wildcarded select list,
when user only had partial column @code{SELECT} privileges on the table.
@item
Mark a @code{MyISAM} table as "analyzed" only when all the keys are indeed
analyzed.
@item
Only ignore world-writable @file{my.cnf} files that are regular files
(and not, for example, named pipes or character devices).
@item
Fixed few smaller issues with @code{SET PASSWORD}.
@item
Fixed error message which contained deprecated text.
@item
Fixed a bug with two @code{NATURAL JOIN}s in the query.
@item
@code{SUM()} didn't return @code{NULL} when there was no rows in result
or when all values was @code{NULL}.
@item
On Unix symbolic links handling was not enabled by default and there was
no way to turn this on.
@item
Added missing dashes to parameter @code{--open-files-limit} in
@command{mysqld_safe}. (Bug #264)
@item
Fixed incorrect hostname for TCP/IP connections displayed in
@code{SHOW PROCESSLIST}.
@item
Fixed a bug with @code{NAN} in @code{FORMAT(...)} function ...
@item 
Fixed a bug with improperly cached database privileges.
@item
Fixed a bug in @code{ALTER TABLE ENABLE / DISABLE KEYS} which failed to
force a refresh of table data in the cache.
@item 
Fixed bugs in replication of @code{LOAD DATA INFILE} for custom parameters 
(@code{ENCLOSED},  @code{TERMINATED} and so on) and temporary tables.
(Bug #183, Bug #222)
@item
Fixed a replication bug when the master is 3.23 and the slave 4.0: the
slave lost the replicated temporary tables if @code{FLUSH LOGS} was
issued on the master. (Bug #254)
@item
Fixed a bug when doing @code{LOAD DATA INFILE IGNORE}: When reading
the binary log, @command{mysqlbinlog} and the replication code read @code{REPLACE}
instead of @code{IGNORE}. This could make the slave's table
become different from the master's table. (Bug #218)
@item
Fixed a deadlock when @code{relay_log_space_limit} was set to a too
small value. (Bug #79)
@item
Fixed a bug in HAVING clause when an alias is used from the
@strong{select list}. 
@item
Fixed overflow bug in @code{MyISAM} when a row is inserted into a table with a 
large number of columns and at least one @code{BLOB/TEXT} column. Bug was caused
by incorrect calculation of the needed buffer to pack data.
@item
Fixed a bug when @code{SELECT} @strong{@@nonexistent_variable} caused the
error in client - server protocol due to net_printf() being sent to
the client twice.
@item 
Fixed a bug in setting @code{SQL_BIG_SELECTS} option.
@item
Fixed a bug in @code{SHOW PROCESSLIST} which only displayed a localhost
in the @code{"Host"} column. This was caused by a glitch that used only
current thread information instead of information from the linked list of threads.
@item
Removed unnecessary Mac OS X helper files from server RPM. (Bug #144)
@item
Allow optimization of multiple-table update for @code{InnoDB} tables as well.
@item
Fixed a bug in multiple-table updates that caused some rows to be
updated several times.
@item
Fixed a bug in @command{mysqldump} when it was called with
@code{--master-data}: the @code{CHANGE MASTER TO} commands appended to
the SQL dump had incorrect coordinates. (Bug #159)
@item
Fixed a bug when an updating query using @code{USER()} was replicated
on the slave; this caused segfault on the slave. (Bug #178).
@code{USER()} is still badly replicated on the slave (it is
replicated to @code{""}).
@end itemize

@node News-4.0.12, News-4.0.11, News-4.0.13, News-4.0.x
@appendixsubsec Changes in release 4.0.12 (15 Mar 2003: Production)

Functionality added or changed:
@itemize @bullet
@item
@command{mysqld} no longer reads options from world-writable config files.
@item
Integer values between 9223372036854775807 and 9999999999999999999 are now
regarded as unsigned longlongs, not as floats. This makes these values work
similar to values between 10000000000000000000 and 18446744073709551615.
@item
@code{SHOW PROCESSLIST} will now include the client TCP port after the
hostname to make it easier to know from which client the request
originated.
@item
The @code{--new} option can be used to make a 4.0 server return
@code{TIMESTAMP} as a string in @code{'YYYY-MM-DD HH:MM:SS'}
format, the way that 4.1 servers do.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Fixed @command{mysqld} crash on extremely small values of
@code{sort_buffer} variable.
@item
@code{INSERT INTO u SELECT ... FROM t} was written too late to the
binary log if t was very frequently updated during the execution of 
this query. This could cause a problem with @command{mysqlbinlog} or
replication. The master must be upgraded, not the slave. (Bug #136)
@item
Fixed checking of random part of @code{WHERE} clause. (Bug #142)
@item
Fixed a bug with multiple-table updates with @code{InnoDB}
tables. This bug occurred as, in many cases, @code{InnoDB} tables cannot
be updated ``on the fly,'' but offsets to the records have to be stored in
a temporary table. 
@item
Added missing file @code{mysql_secure_installation} to the @code{server}
RPM subpackage. (Bug #141)
@item
Fixed MySQL (and @command{myisamchk}) crash on artificially
corrupted @code{.MYI} files.
@item
Don't allow @code{BACKUP TABLE} to overwrite existing files.
@item
Fixed a bug with multiple-table @code{UPDATE} statements when user had all privileges
on the database where tables are located and there were any entries in
@code{tables_priv} table, that is, @code{grant_option} was true.
@item
Fixed a bug that allowed a user with table or column grants on some table,
@code{TRUNCATE} any table in the same database.
@item
Fixed deadlock when doing @code{LOCK TABLE} followed by @code{DROP
TABLE} in the same thread.  In this case one could still kill the thread
with @code{KILL}.
@item
@code{LOAD DATA LOCAL INFILE} was not properly written to the binary
log (hence not properly replicated). (Bug #82)
@item
@code{RAND()} entries were not read correctly by @command{mysqlbinlog} from
the binary log which caused problems when restoring a table that was
inserted with @code{RAND()}. @code{INSERT INTO t1 VALUES(RAND())}. In
replication this worked okay.
@item
@code{SET SQL_LOG_BIN=0} was ignored for @code{INSERT DELAYED}
queries. (Bug #104)
@item
@code{SHOW SLAVE STATUS} reported too old positions
(columns @code{Relay_Master_Log_File} and @code{Exec_Master_Log_Pos})
for the last executed statement from the master, if this statement
was the @code{COMMIT} of a transaction. The master must be upgraded for that,
not the slave. (Bug #52)
@item
@code{LOAD DATA INFILE} was not replicated by the slave if
@code{replicate_*_table} was set on the slave. (Bug #86)
@item
After @code{RESET SLAVE}, the coordinates displayed by @code{SHOW
SLAVE STATUS} looked un-reset (although they were, but only
internally). (Bug #70)
@item
Fixed query cache invalidation on @code{LOAD DATA}.
@item
Fixed memory leak on @code{ANALYZE} procedure with error.
@item
Fixed a bug in handling @code{CHAR(0)} columns that could cause incorrect
results from the query.
@item
Fixed rare bug with incorrect initialization of @code{AUTO_INCREMENT} column,
as a secondary column in a multi-column key (@pxref{example-AUTO_INCREMENT,
, @code{AUTO_INCREMENT} on secondary column  in a multi-column key}), when
data was inserted with @code{INSERT ... SELECT} or @code{LOAD DATA} into
an empty table.
@item
On Windows, @code{STOP SLAVE} didn't stop the slave until the slave
got one new command from the master (this bug has been fixed for MySQL 4.0.11
by releasing updated 4.0.11a Windows packages, which include this individual
fix on top of the 4.0.11 sources). (Bug #69)
@item 
Fixed a crash when no database was selected and @code{LOAD DATA} command
was issued with full table name specified, including database prefix.
@item
Fixed a crash when shutting down replication on some platforms
(for example, Mac OS X).
@item
Fixed a portability bug with @code{pthread_attr_getstacksize} on
HP-UX 10.20 (Patch was also included in 4.0.11a sources).
@item
Fixed the @code{bigint} test to not fail on some platforms (for example, HP-UX and
Tru64) due to different return values of the @code{atof()} function.
@item
Fixed the @code{rpl_rotate_logs} test to not fail on certain platforms (such as
Mac OS X) due to a too-long file name (changed @code{slave-master-info.opt}
to @code{.slave-mi}).
@end itemize

@node News-4.0.11, News-4.0.10, News-4.0.12, News-4.0.x
@appendixsubsec Changes in release 4.0.11 (20 Feb 2003)

Functionality added or changed:
@itemize @bullet
@item
@code{NULL} is now sorted @strong{LAST} if you use @code{ORDER BY ... DESC}
(as it was before MySQL 4.0.2).  This change was required to comply
with the SQL standard.  (The original change was made because we thought
that standard SQL required @code{NULL} to be always sorted at the same position,
but this was incorrect).
@item
Added @code{START TRANSACTION} (standard SQL syntax) as alias for @code{BEGIN}.
This is recommended to use instead of @code{BEGIN} to start a transaction.
@item
Added @code{OLD_PASSWORD()} as a synonym for @code{PASSWORD()}.
@item
Allow keyword @code{ALL} in group functions.
@item
Added support for some new @code{INNER JOIN} and @code{JOIN} syntaxes.
For example, @code{SELECT * FROM t1 INNER JOIN t2} didn't work before.
@item
Novell NetWare 6.0 porting effort completed, Novell patches merged into
the main source tree.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Fixed problem with multiple-table delete and @code{InnoDB} tables.
@item
Fixed a problem with @code{BLOB NOT NULL} columns used with @code{IS NULL}.
@item
Re-added missing pre- and post(un)install scripts to the Linux RPM packages
(they were missing after the renaming of the server subpackage).
@item
Fixed that table locks are not released with multiple-table updates and 
deletes with @code{InnoDB} storage engine.
@item
Fixed bug in updating @code{BLOB} columns with long strings.
@item
Fixed integer-wraparound when giving big integer (>= 10 digits) to
function that requires an unsigned argument, like @code{CREATE TABLE (...) 
AUTO_INCREMENT=#}.
@item
@code{MIN(key_column)} could in some cases return @code{NULL} on a column
with @code{NULL} and other values.
@item
@code{MIN(key_column)} and @code{MAX(key_column)} could in some cases
return incorrect values when used in @code{OUTER JOIN}.
@item
@code{MIN(key_column)} and @code{MAX(key_column)} could return incorrect
values if one of the tables was empty.
@item
Fixed rare crash in compressed @code{MyISAM} tables with blobs.
@item
Fixed bug in using aggregate functions as argument for @code{INTERVAL},
@code{CASE}, @code{FIELD}, @code{CONCAT_WS}, @code{ELT} and
@code{MAKE_SET} functions.
@item
When running with @code{--lower-case-table-names} (default on Windows)
and you had tables or databases with mixed case on disk, then
executing @code{SHOW TABLE STATUS} followed with @code{DROP DATABASE}
or @code{DROP TABLE} could fail with @code{Errcode 13}.
@end itemize

@node News-4.0.10, News-4.0.9, News-4.0.11, News-4.0.x
@appendixsubsec Changes in release 4.0.10 (29 Jan 2003)

Functionality added or changed:
@itemize @bullet
@item
Added option @code{--log-error[=@var{file_name}]} to @command{mysqld_safe} and
@command{mysqld}. This option will force all error messages to be put in a
log file if the option @code{--console} is not given. On Windows
@code{--log-error} is enabled as default, with a default name of
@file{@var{host_name}.err} if the name is not specified.
@item
Changed some things from @code{Warning:} to @code{Note:} in the log files.
@item
The @command{mysqld} server should now compile on NetWare.
@item
Added optimization that if one does @code{GROUP BY ... ORDER BY NULL}
then result is not sorted.
@item
New @code{--ft-stopword-file} command-line option for @command{mysqld} to
replace/disable the built-in stopword list that is used in full-text searches.
@xref{Server system variables}.
@item
Changed default stack size from 64KB to 192KB; This fixes a core dump
problem on Red Hat 8.0 and other systems with a @code{glibc} that requires a
stack size larger than 128K
for @code{gethostbyaddr()} to resolve a hostname. You can fix
this for earlier MySQL versions by starting @command{mysqld} with
@code{--thread-stack=192K}.
@item
Added @code{mysql_waitpid} to the binary distribution and the
@code{MySQL-client} RPM subpackage (required for @command{mysql-test-run}).
@item
Renamed the main @code{MySQL} RPM package to @code{MySQL-server}. When
updating from an older version, @code{MySQL-server.rpm} will simply replace
@code{MySQL.rpm}.
@item
If a slave is configured with @code{replicate_wild_do_table=db.%} or
@code{replicate_wild_ignore_table=db.%}, these rules will be applied to
@code{CREATE/DROP DATABASE}, too.
@item
Added timeout value for @code{MASTER_POS_WAIT()}.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Fixed initialization of the random seed for newly created threads to
give a better @code{rand()} distribution from the first call.
@item
Fixed a bug that caused @command{mysqld} to hang when a
table was opened with the @code{HANDLER} command and then
dropped without being closed.
@item
Fixed bug in logging to binary log (which affects replication) a query
that inserts a @code{NULL} in an @code{AUTO_INCREMENT} column and also
uses @code{LAST_INSERT_ID()}.
@item
Fixed an unlikely bug that could cause a memory overrun when using
@code{ORDER BY constant_expression}.
@item
Fixed a table corruption in @command{myisamchk} parallel repair mode.
@item
Fixed bug in query cache invalidation on simple table renaming.
@item
Fixed bug in @command{mysqladmin --relative}.
@item
On some 64-bit systems, @code{show status} reported a strange number for
@code{Open_files} and @code{Open_streams}.
@item
Fixed incorrect number of columns in @code{EXPLAIN} on empty table.
@item
Fixed bug in @code{LEFT JOIN} that caused zero rows to be returned in
the case the @code{WHERE} condition was evaluated as @code{FALSE} after
reading @code{const} tables. (Unlikely condition).
@item
@code{FLUSH PRIVILEGES} didn't correctly flush table/column privileges
when @code{mysql.tables_priv} is empty.
@item
Fixed bug in replication when using @code{LOAD DATA INFILE} one a file
that updated an @code{AUTO_INCREMENT} column with @code{NULL} or @code{0}. This
bug only affected MySQL 4.0 masters (not slaves or MySQL 3.23 masters).
@strong{Note}: If you have a slave that has replicated a file with
generated @code{AUTO_INCREMENT} columns then the slave data is corrupted and you
should reinitialize the affected tables from the master.
@item
Fixed possible memory overrun when sending a @code{BLOB} value larger than 16M
to the client.
@item
Fixed incorrect error message when setting a @code{NOT NULL} column to an
expression that returned @code{NULL}.
@item
Fixed core dump bug in @code{@var{str} LIKE "%@var{other_str}%"} where @var{str} or
@var{other_str} contained characters >= 128.
@item
Fixed bug: When executing on master @code{LOAD DATA} and @code{InnoDB} failed
with @code{table full} error the binary log was corrupted.
@end itemize

@node News-4.0.9, News-4.0.8, News-4.0.10, News-4.0.x
@appendixsubsec Changes in release 4.0.9 (09 Jan 2003)

Functionality added or changed:
@itemize @bullet
@item
@code{OPTIMIZE TABLE} will for @code{MyISAM} tables treat all @code{NULL}
values as different when calculating cardinality.  This helps in
optimizing joins between tables where one of the tables has a lot of
@code{NULL} values in a indexed column:
@example
SELECT * from t1, t2 where t1.a=t2.key_with_a_lot_of_null;
@end example
@item
Added join operator @code{FORCE INDEX (key_list)}. This acts likes
@code{USE INDEX (key_list)} but with the addition that a table scan is
assumed to be VERY expensive.  One bad thing with this is that it makes
@code{FORCE} a reserved word.
@item
Reset internal row buffer in @code{MyISAM} after each query. This will reduce
memory in the case you have a lot of big blobs in a table.
@end itemize

Bugs fixed:
@itemize @bullet
@item
A security patch in 4.0.8 causes the @command{mysqld} server to die if the remote
hostname can't be resolved. This is now fixed.
@item
Fixed crash when replication big @code{LOAD DATA INFILE} statement that
caused log rotation.
@end itemize

@node News-4.0.8, News-4.0.7, News-4.0.9, News-4.0.x
@appendixsubsec Changes in release 4.0.8 (07 Jan 2003)

Functionality added or changed:
@itemize @bullet
@item
Default @code{max_packet_length} for @file{libmysqld.c} is now 1024*1024*1024.
@item
You can now specify @code{max_allowed_packet} in a file read by
@code{mysql_options(MYSQL_READ_DEFAULT_FILE)}.
for clients.
@item
When sending a too big packet to the server with the not compressed
protocol, the client now gets an error message instead of a lost
connection.
@item
We now send big queries/result rows in bigger hunks, which should give a
small speed improvement.
@item
Fixed some bugs with the compressed protocol for rows > 16MB.
@item
@code{InnoDB} tables now also support @code{ON UPDATE CASCADE} in
@code{FOREIGN KEY} constraints. See the @code{InnoDB} section in the manual
for the @code{InnoDB} changelog.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Fixed bug in @code{ALTER TABLE} with @code{BDB} tables.
@item
Fixed core dump bug in @code{QUOTE()} function.
@item
Fixed a bug in handling communication packets bigger than
16MB. Unfortunately this required a protocol change; If you upgrade the
server to 4.0.8 and above and have clients that uses packets >=
255*255*255 bytes (=16581375) you must also upgrade your clients to at
least 4.0.8.  If you don't upgrade, the clients will hang when sending a
big packet.
@item
Fixed bug when sending blobs longer than 16MB to client.
@item
Fixed bug in @code{GROUP BY} when used on BLOB column with @code{NULL} values.
@item
Fixed a bug in handling @code{NULL} values in @code{CASE} ... WHEN ...
@end itemize

@node News-4.0.7, News-4.0.6, News-4.0.8, News-4.0.x
@appendixsubsec Changes in release 4.0.7 (20 Dec 2002)

Functionality added or changed:
@itemize @bullet
@item
@command{mysqlbug} now also reports the compiler version used for building
the binaries (if the compiler supports the option @code{--version}).
@end itemize

Bugs fixed:
@itemize @bullet
@item
Fixed compilation problems on OpenUnix and HPUX 10.20.
@item
Fixed some optimization problems when compiling MySQL with @code{-DBIG_TABLES}
on a 32-bit system.
@item
@code{mysql_drop_db()} didn't check permissions properly so anyone could
drop another users database.  @code{DROP DATABASE} is checked properly.
@end itemize

@node News-4.0.6, News-4.0.5, News-4.0.7, News-4.0.x
@appendixsubsec Changes in release 4.0.6 (14 Dec 2002: Gamma)

Functionality added or changed:

@itemize @bullet
@item
Added syntax support for @code{CHARACTER SET @var{xxx}} and @code{CHARSET=@var{xxx}}
table options (to be able to read table dumps from 4.1).
@item
Fixed replication bug that caused the slave to loose its position in
some cases when the replication log was rotated.
@item
Fixed that a slave will restart from the start of a transaction if
it's killed in the middle of one.
@item
Moved the manual pages from @file{man} to @file{man/man1} in the
binary distributions.
@item
The default type returned by @code{IFNULL(A,B)} is now set to be the
more 'general' of the types of @code{A} and @code{B}. (The order is
@code{STRING}, @code{REAL} or @code{INTEGER}).
@item
Moved the @command{mysql.server} startup script in the RPM packages from
@file{/etc/rc.d/init.d/mysql} to @file{/etc/init.d/mysql}
(which almost all current Linux distributions support for LSB compliance).
@item
Added @code{Qcache_lowmem_prunes} status variable (number of queries that were
deleted from the cache because of low memory).
@item
Fixed @command{mysqlcheck} so it can deal with table names containing dashes.
@item
Bulk insert optimization
(@pxref{Server system variables, ,@code{bulk_insert_buffer_size}})
is no longer used when inserting small (less than 100) number of rows.
@item
Optimization added for queries like
@code{SELECT ... FROM merge_table WHERE indexed_column=constant_expr}.
@item
Added functions @code{LOCALTIME} and @code{LOCALTIMESTAMP} as synonyms for
@code{NOW()}.
@item
@code{CEIL} is now an alias for @code{CEILING}.
@item
The @code{CURRENT_USER()} function can be used to get a @code{user@@host}
value as it was matched in the @code{GRANT} system.
@xref{Information functions, ,@code{CURRENT_USER()}}.
@item
Fixed @code{CHECK} constraints to be compatible with standard SQL. This made
@code{CHECK} a reserved word. (Checking of @code{CHECK} constraints is
still not implemented).
@item
Added @code{CAST(... as CHAR)}.
@item
Added PostgreSQL compatible @code{LIMIT} syntax:
@code{SELECT ... LIMIT @var{row_count} OFFSET @var{offset}}
@item
@code{mysql_change_user()} will now reset the connection to the state
of a fresh connect (Ie, @code{ROLLBACK} any active transaction, close
all temporary tables, reset all user variables etc..)
@item
@code{CHANGE MASTER} and @code{RESET SLAVE} now require that slave
threads be both already stopped; these commands will return an error
if at least one of these two threads is running.
@end itemize

Bugs fixed:

@itemize @bullet
@item
Fixed number of found rows returned in @code{multi table updates}
@item
Make @code{--lower-case-table-names} default on Mac OS X as the default
filesystem (HFS+) is case insensitive.
@xref{Name case sensitivity}.
@item
Transactions in @code{AUTOCOMMIT=0} mode didn't rotate binary log.
@item
A fix for the bug in a @code{SELECT} with joined tables with
@code{ORDER BY} and @code{LIMIT} clause when @code{filesort} had to be used.
In that case @code{LIMIT} was applied to @code{filesort} of one of the tables,
although it could not be.
This fix also solved problems with @code{LEFT JOIN}.
@item
@code{mysql_server_init()} now makes a copy of all arguments. This fixes
a problem when using the embedded server in C# program.
@item
Fixed buffer overrun in @code{libmysqlclient} library
that allowed a malicious MySQL server to crash the client
application.
@item
Fixed security-related bug in @code{mysql_change_user()} handling.
All users are strongly recommended to upgrade to version 4.0.6.
@item
Fixed bug that prevented @code{--chroot} command-line option of
@command{mysqld} from working.
@item
Fixed bug in phrase operator @code{"..."} in boolean full-text search.
@item
Fixed bug that caused @code{OPTIMIZE TABLE} to corrupt the table
under some rare circumstances.
@item
Part rewrite of multiple-table-update to optimize it, make it safer and
more bug-free.
@item
@code{LOCK TABLES} now works together with multiple-table-update and
multiple-table-delete.
@item
@code{--replicate-do=@var{xxx}} didn't work for @code{UPDATE} commands.
(Bug introduced in 4.0.0)
@item
Fixed shutdown problem on Mac OS X.
@item Major @code{InnoDB} bugs in @code{REPLACE, AUTO_INCREMENT,
INSERT INTO ... SELECT ...} were fixed. See the @code{InnoDB} changelog
in the @code{InnoDB} section of the manual.
@item
@code{RESET SLAVE} caused a crash if the slave threads were running.
@end itemize

@node News-4.0.5, News-4.0.4, News-4.0.6, News-4.0.x
@appendixsubsec Changes in release 4.0.5 (13 Nov 2002)

Functionality added or changed:

@itemize @bullet
@item
Port number was added to hostname (if it is known) in @code{SHOW PROCESSLIST}
command
@item
Changed handling of last argument in @code{WEEK()} so that you can get
week number according to the ISO 8601 specification.
(Old code should still work).
@item
Fixed that @code{INSERT DELAYED} threads don't hang on @code{Waiting for
INSERT} when one sends a @code{SIGHUP} to @command{mysqld}.
@item
Change that @code{AND} works according to standard SQL when it comes to
@code{NULL} handling. In practice, this affects only queries where you
do something like @code{WHERE ... NOT (NULL AND 0)}.
@item
@command{mysqld} will now resolve @code{basedir} to its full path (with
@code{realpath()}). This enables one to use relative symlinks to the
MySQL installation directory.  This will however cause @code{show
variables} to report different directories on systems where there is
a symbolic link in the path.
@item
Fixed that MySQL will not use index scan on index disabled with
@code{IGNORE INDEX} or @code{USE INDEX}.
to be ignored.
@item
Added @code{--use-frm} option to @command{mysqlcheck}. When used with
@code{REPAIR TABLE}, it gets the table structure from the @file{.frm} file, so the
table can be repaired even if the @code{.MYI} header is corrupted.
@item
Fixed bug in @code{MAX()} optimization when used with @code{JOIN} and
@code{ON} expressions.
@item
Added support for reading of MySQL 4.1 table definition files.
@item
@code{BETWEEN} behavior changed (@pxref{Comparison Operators}).
Now @code{datetime_col BETWEEN timestamp AND timestamp} should work
as expected.
@item
One can create @code{TEMPORARY} @code{MERGE} tables now.
@item
@code{DELETE FROM myisam_table} now shrinks not only the @file{.MYD} file but
also the @file{.MYI} file.
@item
When one uses the @code{--open-files-limit=#} option to @command{mysqld_safe}
it's now passed on to @command{mysqld}.
@item
Changed output from @code{EXPLAIN} from @code{'where used'} to
@code{'Using where'} to make it more in line with other output.
@item
Removed variable @code{safe_show_database} as it was no longer used.
@item
Updated source tree to be built using @command{automake} 1.5 and 
@command{libtool} 1.4.
@item
Fixed an inadvertently changed option (@code{--ignore-space}) back to the
original @code{--ignore-spaces} in @code{mysqlclient}. (Both syntaxes will
work).
@item
Don't require @code{UPDATE} privilege when using @code{REPLACE}.
@item
Added support for @code{DROP TEMPORARY TABLE ...}, to be used to make
replication safer.
@item
When transactions are enabled, all commands that update temporary tables
inside a @code{BEGIN/COMMIT} are now stored in the binary log on
@code{COMMIT} and not stored if one does @code{ROLLBACK}.  This fixes
some problems with non-transactional temporary tables used inside
transactions.
@item
Allow braces in joins in all positions. Formerly, things like
@code{SELECT * FROM (t2 LEFT JOIN t3 USING (a)), t1} worked, but
not @code{SELECT * FROM t1, (t2 LEFT JOIN t3 USING (a))}. Note that
braces are simply removed, they do not change the way the join is
executed.
@item
@code{InnoDB} now supports also isolation levels
@code{READ UNCOMMITTED} and @code{READ COMMITTED}.
For a detailed @code{InnoDB} changelog, see @ref{InnoDB change history}
in this manual. 
@end itemize

Bugs fixed:

@itemize @bullet
@item
Fixed bug in @code{MAX()} optimization when used with @code{JOIN} and
@code{ON} expressions.
@item
Fixed that @code{INSERT DELAY} threads don't hang on @code{Waiting for
INSERT} when one sends a @code{SIGHUP} to @command{mysqld}.
@item
Fixed that MySQL will not use an index scan on an index that has been
disabled with @code{IGNORE INDEX} or @code{USE INDEX}.
@item
Corrected test for @code{root} user in @command{mysqld_safe}.
@item
Fixed error message issued when storage engine cannot do @code{CHECK TABLE}
or @code{REPAIR TABLE}.
@item
Fixed rare core dump problem in complicated @code{GROUP BY} queries that
didn't return any result.
@item
Fixed @command{mysqlshow} to work properly with wildcarded database names and
with database names that contain underscores.
@item
Portability fixes to get MySQL to compile cleanly with Sun Forte 5.0.
@item
Fixed @code{MyISAM} crash when using dynamic-row tables with huge numbers of
packed columns.
@item
Fixed query cache behavior with @code{BDB} transactions.
@item
Fixed possible floating point exception in @code{MATCH}
relevance calculations.
@item
Fixed bug in full-text search @code{IN BOOLEAN MODE} that made @code{MATCH}
to return incorrect relevance value in some complex joins.
@item
Fixed a bug that limited @code{MyISAM} key length to a value
slightly less that 500. It is exactly 500 now.
@item
Fixed that @code{GROUP BY} on columns that may have a @code{NULL} value
doesn't always use disk based temporary tables.
@item
The filename argument for the @code{--des-key-file} argument to @command{mysqld}
is interpreted relative to the data directory if given as a relative pathname.
@item
Removed a condition that temp table with index on column that can be
@code{NULL} has to be @code{MyISAM}. This was okay for 3.23, but not
needed in 4.*. This resulted in slowdown in many queries since 4.0.2.
@item
Small code improvement in multiple-table updates.
@item
Fixed a newly introduced bug that caused @code{ORDER BY ... LIMIT @var{row_count}}
to not return all rows.
@item
Fixed a bug in multiple-table deletes when outer join is used on an empty
table, which gets first to be deleted.
@item
Fixed a bug in multiple-table updates when a single table is updated.
@item
Fixed bug that caused @code{REPAIR TABLE} and @command{myisamchk}
to corrupt @code{FULLTEXT} indexes.
@item
Fixed bug with caching the @code{mysql} grant table database. Now queries
in this database are not cached in the query cache.
@item
Small fix in @command{mysqld_safe} for some shells.
@item
Give error if a @code{MyISAM} @code{MERGE} table has more than 2 ^ 32 rows and
MySQL was not compiled with @code{-DBIG_TABLES}.
@item
Fixed some @code{ORDER BY ... DESC} problems with @code{InnoDB} tables.
@end itemize

@node News-4.0.4, News-4.0.3, News-4.0.5, News-4.0.x
@appendixsubsec Changes in release 4.0.4 (29 Sep 2002)

@itemize @bullet
@item
Fixed bug where @code{GRANT}/@code{REVOKE} failed if hostname was given in
non-matching case.
@item
Don't give warning in @code{LOAD DATA INFILE} when setting a
@code{timestamp} to a string value of @code{'0'}.
@item
Fixed bug in @command{myisamchk -R} mode.
@item
Fixed bug that caused @command{mysqld} to crash on @code{REVOKE}.
@item
Fixed bug in @code{ORDER BY} when there is a constant in the @code{SELECT}
statement.
@item
One didn't get an error message if @command{mysqld} couldn't open the
privilege tables.
@item
@code{SET PASSWORD FOR ...} closed the connection in case of errors (bug
from 4.0.3).
@item
Increased maximum possible @code{max_allowed_packet} in @command{mysqld} to 1GB.
@item
Fixed bug when doing a multiple-row @code{INSERT} on a table with an
@code{AUTO_INCREMENT} key which was not in the first part of the key.
@item
Changed @code{LOAD DATA INFILE} to not re-create index if the table had
rows from before.
@item
Fixed overrun bug when calling @code{AES_DECRYPT()} with incorrect arguments.
@item
@code{--skip-ssl} can now be used to disable SSL in the MySQL clients,
even if one is using other SSL options in an option file or previously
on the command line.
@item
Fixed bug in @code{MATCH ... AGAINST( ... IN BOOLEAN MODE)}
used with @code{ORDER BY}.
@item
Added @code{LOCK TABLES} and @code{CREATE TEMPORARY TABLES} privilege on
the database level.  You must run the @command{mysql_fix_privilege_tables}
script on old installations to activate these.
@item
In @code{SHOW TABLE ... STATUS}, compressed tables sometimes showed up as
@code{dynamic}.
@item
@code{SELECT @@@@[global|session].@var{var_name}} didn't report
@code{global | session} in the result column name.
@item
Fixed problem in replication that @code{FLUSH LOGS} in a circular
replication setup created an infinite number of binary log files.
Now a @code{rotate-binary-log} command in the binary log will not cause slaves
to rotate logs.
@item
Removed @code{STOP EVENT} from binary log when doing @code{FLUSH LOGS}.
@item
Disable the use of @code{SHOW NEW MASTER FOR SLAVE} as this needs to be
completely reworked in a future release.
@item
Fixed a bug with constant expression (for example, column of a one-row table,
or column
from a table, referenced by a @code{UNIQUE} key) appeared in @code{ORDER BY}
part of @code{SELECT DISTINCT}.
@item
@code{--log-binary=a.b.c} now properly strips off @code{.b.c}.
@item
@code{FLUSH LOGS} removed numerical extension for all future update logs.
@item
@code{GRANT ... REQUIRE} didn't store the SSL information in the
@code{mysql.user} table if SSL was not enabled in the server.
@item
@code{GRANT ... REQUIRE NONE} can now be used to remove SSL information.
@item
@code{AND} is now optional between @code{REQUIRE} options.
@item
@code{REQUIRE} option was not properly saved, which could cause strange
output in @code{SHOW GRANTS}.
@item
Fixed that @command{mysqld --help} reports correct values for @code{--datadir}
and @code{--bind-address}.
@item
Fixed that one can drop UDFs that didn't exist when @command{mysqld} was started.
@item
Fixed core dump problem with @code{SHOW VARIABLES} on some 64-bit systems
(like Solaris SPARC).
@item
Fixed a bug in @code{my_getopt()}; @code{--set-variable} syntax didn't work for
those options that didn't have a valid variable in the @code{my_option} struct.
This affected at least the @code{default-table-type} option.
@item
Fixed a bug from 4.0.2 that caused @code{REPAIR TABLE} and
@command{myisamchk --recover} to fail on tables with duplicates in a unique
key.
@item
Fixed a bug from 4.0.3 in calculating the default data type for some
functions. This affected queries of type @code{CREATE TABLE @var{tbl_name}
SELECT @var{expression}(),...}
@item
Fixed bug in queries of type
@code{SELECT * FROM table-list GROUP BY ...} and
@code{SELECT DISTINCT * FROM ...}.
@item
Fixed bug with the @code{--slow-log} when logging an administrator command
(like @code{FLUSH TABLES}).
@item
Fixed a bug that @code{OPTIMIZE TABLE} of locked and modified table,
reported table corruption.
@item
Fixed a bug in @code{my_getopt()} in handling of special prefixes
(@code{--skip-}, @code{--enable-}). @code{--skip-external-locking} didn't
work and the bug may have affected other similar options.
@item
Fixed bug in checking for output file name of the @code{tee} option.
@item
Added some more optimization to use index for
@code{SELECT ... FROM many_tables .. ORDER BY key limit #}
@item
Fixed problem in @code{SHOW OPEN TABLES} when a user didn't have access
permissions to one of the opened tables.
@end itemize

@node News-4.0.3, News-4.0.2, News-4.0.4, News-4.0.x
@appendixsubsec Changes in release 4.0.3 (26 Aug 2002: Beta)

@itemize @bullet
@item
Fixed problem with types of user variables. (Bug #551)
@item
Fixed problem with @code{configure ... --localstatedir=...}.
@item
Cleaned up @command{mysql.server} script.
@item
Fixed a bug in @command{mysqladmin shutdown} when pid file was modified
while @command{mysqladmin} was still waiting for the previous one to
disappear. This could happen during a very quick restart and caused
@command{mysqladmin} to hang until @code{shutdown_timeout} seconds had
passed.
@item
Don't increment warnings when setting @code{AUTO_INCREMENT} columns to
@code{NULL} in @code{LOAD DATA INFILE}.
@item
Fixed all boolean type variables/options to work with the old syntax,
for example, all of these work: @code{--lower-case-table-names},
@code{--lower-case-table-names=1},
@code{-O lower-case-table-names=1},
@code{--set-variable=lower-case-table-names=1}
@item
Fixed shutdown problem (SIGTERM signal handling) on Solaris. (Bug from 4.0.2).
@item
@code{SHOW MASTER STATUS} now returns an empty set if binary log is not
enabled.
@item
@code{SHOW SLAVE STATUS} now returns an empty set if slave is not initialized.
@item
Don't update @code{MyISAM} index file on update if not strictly necessary.
@item
Fixed bug in @code{SELECT DISTINCT ... FROM many_tables ORDER BY
not-used-column}.
@item
Fixed a bug with @code{BIGINT} values and quoted strings.
@item
Added @code{QUOTE()} function that performs SQL quoting to produce values
that can be used as data values in queries.
@item
Changed variable @code{DELAY_KEY_WRITE} to an enumeration to allow it to be
set for all tables without taking down the server.
@item
Changed behavior of @code{IF(condition,column,NULL)} so that it returns
the value of the column type.
@item
Made @command{safe_mysqld} a symlink to @command{mysqld_safe} in binary distribution.
@item
Fixed security bug when having an empty database name in the @code{user.db}
table.
@item
Fixed some problems with @code{CREATE TABLE ... SELECT function()}.
@item
@command{mysqld} now has the option @code{--temp-pool} enabled by default as this
gives better performance with some operating systems.
@item
Fixed problem with too many allocated alarms on slave when connecting to
master many times (normally not a very critical error).
@item
Fixed hang in @code{CHANGE MASTER TO} if the slave thread died very quickly.
@item
Big cleanup in replication code (less logging, better error messages, etc..)
@item
If the @code{--code-file} option is specified, the server calls
@code{setrlimit()} to set the maximum allowed core file size to unlimited,
so core files can be generated.
@item
Fixed bug in query cache after temporary table creation.
@item
Added @code{--count=@var{N}} (@code{-c}) option to @command{mysqladmin}, to make the
program do only @var{N} iterations. To be used with @code{--sleep} (@code{-i}).
Useful in scripts.
@item
Fixed bug in multiple-table @code{UPDATE}: when updating a table,
@code{do_select()} became confused about reading records from a cache.
@item
Fixed bug in multiple-table @code{UPDATE} when several columns were referenced
from a single table
@item
Fixed bug in truncating nonexisting table.
@item
Fixed bug in @code{REVOKE} that caused user resources to be randomly set.
@item
Fixed bug in @code{GRANT} for the new @code{CREATE TEMPORARY TABLE} privilege.
@item
Fixed bug in multiple-table @code{DELETE} when tables are re-ordered in the
table initialization method and ref_lengths are of different sizes.
@item 
Fixed two bugs in @code{SELECT DISTINCT} with large tables.
@item
Fixed bug in query cache initialization with very small query cache size.
@item
Allow @code{DEFAULT} with @code{INSERT} statement.
@item
The startup parameters @code{myisam_max_sort_file_size} and
@code{myisam_max_extra_sort_file_size} are now given in bytes, not megabytes.
@item
External system locking of @code{MyISAM}/@code{ISAM} files is now turned
off by default.  One can turn this on with @code{--external-locking}.
(For most users this is never needed).
@item
Fixed core dump bug with @code{INSERT ... SET @var{db_name.tbl_name.col_name}=''}.
@item
Fixed client hangup bug when using some SQL commands with incorrect syntax.
@item
Fixed a timing bug in @code{DROP DATABASE}
@item
New @code{SET [GLOBAL | SESSION]} syntax to change thread-specific and global
system variables at runtime.
@item
Added variable @code{slave_compressed_protocol}.
@item
Renamed variable @code{query_cache_startup_type} to @code{query_cache_type},
@code{myisam_bulk_insert_tree_size} to @code{bulk_insert_buffer_size},
@code{record_buffer} to @code{read_buffer_size} and
@code{record_rnd_buffer} to @code{read_rnd_buffer_size}.
@item
Renamed some SQL variables, but old names will still work until 5.0.
@xref{Upgrading-from-3.23}.
@item
Renamed @code{--skip-locking} to @code{--skip-external-locking}.
@item
Removed unused variable @code{query_buffer_size}.
@item
Fixed a bug that made the pager option in the @command{mysql} client
non-functional.
@item
Added full @code{AUTO_INCREMENT} support to @code{MERGE} tables.
@item
Extended @code{LOG()} function to accept an optional arbitrary base
parameter.
@xref{Mathematical functions}.
@item
Added @code{LOG2()} function (useful for finding out how many bits
a number would require for storage).
@item
Added @code{LN()} natural logarithm function for compatibility with
other databases. It is synonymous with @code{LOG(@var{X})}.
@end itemize


@node News-4.0.2, News-4.0.1, News-4.0.3, News-4.0.x
@appendixsubsec Changes in release 4.0.2 (01 Jul 2002)

@itemize @bullet
@item
Cleaned up @code{NULL} handling for default values in @code{DESCRIBE
tbl_name}.
@item
Fixed @code{TRUNCATE()} to round up negative values to the nearest integer.
@item
Changed @code{--chroot=path} option to execute @code{chroot()} immediately
after all options have been parsed.
@item
Don't allow database names that contain @samp{\}.
@item
@code{lower_case_table_names} now also applies to database names.
@item
Added @code{XOR} operator (logical and bitwise @code{XOR}) with @code{^}
as a synonym for bitwise @code{XOR}.
@item
Added function @code{IS_FREE_LOCK("lock_name")}.
Based on code contributed by Hartmut Holzgraefe @email{hartmut@@six.de}.
@item
Removed @code{mysql_ssl_clear()} from C API, as it was not needed.
@item
@code{DECIMAL} and @code{NUMERIC} types can now read exponential numbers.
@item
Added @code{SHA1()} function to calculate 160 bit hash value as described
in RFC 3174 (Secure Hash Algorithm). This function can be considered a
cryptographically more secure equivalent of @code{MD5()}.
@xref{Encryption functions}.
@item
Added @code{AES_ENCRYPT()} and @code{AES_DECRYPT()} functions to perform
encryption according to AES standard (Rijndael).
@xref{Encryption functions}.
@item
Added @code{--single-transaction} option to @command{mysqldump}, allowing a
consistent dump of @code{InnoDB} tables.
@xref{mysqldump}.
@item
Fixed bug in @code{innodb_log_group_home_dir} in @code{SHOW VARIABLES}.
@item
Fixed a bug in optimizer with merge tables when non-unique values are 
used in summing up (causing crashes).
@item
Fixed a bug in optimizer when a range specified makes index grouping
impossible (causing crashes).
@item
Fixed a rare bug when @code{FULLTEXT} index is present and no tables are used.
@item
Added privileges @code{CREATE TEMPORARY TABLES}, @code{EXECUTE},
@code{LOCK TABLES}, @code{REPLICATION CLIENT}, @code{REPLICATION SLAVE},
@code{SHOW DATABASES} and @code{SUPER}. To use these, you must have
run the @command{mysql_fix_privilege_tables} script after upgrading.
@item
Fixed query cache align data bug.
@item
Fixed mutex bug in replication when reading from master fails.
@item
Added missing mutex in @code{TRUNCATE TABLE};  This fixes some core
dump/hangup problems when using @code{TRUNCATE TABLE}.
@item
Fixed bug in multiple-table @code{DELETE} when optimizer uses only indexes.
@item
Fixed that @code{ALTER TABLE @var{tbl_name} RENAME @var{new_tbl_name}} is as fast
as @code{RENAME TABLE}.
@item
Fixed bug in @code{GROUP BY} with two or more columns, where at least one
column can contain @code{NULL} values.
@item
Use @code{Turbo Boyer-Moore} algorithm to speed up @code{LIKE "%keyword%"}
searches.
@item
Fixed bug in @code{DROP DATABASE} with symlink.
@item
Fixed crash in @code{REPAIR ... USE_FRM}.
@item
Fixed bug in @code{EXPLAIN} with @code{LIMIT offset != 0}.
@item
Fixed bug in phrase operator @code{"..."} in boolean full-text search.
@item
Fixed bug that caused duplicated rows when using truncation operator
@code{*} in boolean full-text search.
@item
Fixed bug in truncation operator of boolean full-text search (incorrect results
when there are only @code{+word*}s in the query).
@item
Fixed bug in boolean full-text search that caused a crash when an identical
@code{MATCH} expression that did not use an index appeared twice.
@item
Query cache is now automatically disabled in @command{mysqldump}.
@item
Fixed problem on Windows 98 that made sending of results very slow.
@item
Boolean full-text search weighting scheme changed to something more reasonable.
@item
Fixed bug in boolean full-text search that caused MySQL to ignore queries of
@code{ft_min_word_len} characters.
@item
Boolean full-text search now supports ``phrase searches.''
@item
New configure option @code{--without-query-cache}. 
@item
Memory allocation strategy for ``root memory'' changed. Block size now grows 
with number of allocated blocks.
@item
@code{INET_NTOA()} now returns @code{NULL} if you give it an argument that
is too large (greater than the value corresponding to @code{255.255.255.255}).
@item
Fix @code{SQL_CALC_FOUND_ROWS} to work with @code{UNION}. It will work only
if the first @code{SELECT} has this option and if there is global @code{LIMIT}
for the entire statement. For the moment, this requires using parentheses for
individual @code{SELECT} queries within the statement.
@item
Fixed bug in @code{SQL_CALC_FOUND_ROWS} and @code{LIMIT}.
@item
Don't give an error for @code{CREATE TABLE ...(... VARCHAR(0))}.
@item
Fixed @code{SIGINT} and @code{SIGQUIT} problems in @file{mysql.cc} on Linux
with some @code{glibc} versions.
@item
Fixed bug in @file{convert.cc}, which is caused by having an incorrect
@code{net_store_length()} linked in the @code{CONVERT::store()} method.
@item
@code{DOUBLE} and @code{FLOAT} columns now honor the @code{UNSIGNED} flag
on storage.
@item
@code{InnoDB} now retains foreign key constraints through @code{ALTER TABLE}
and @code{CREATE/DROP INDEX}.
@item
@code{InnoDB} now allows foreign key constraints to be added through the
@code{ALTER TABLE} syntax.
@item
@code{InnoDB} tables can now be set to automatically grow in size (autoextend).
@item
Added @code{--ignore-lines=n} option to @command{mysqlimport}.  This has the
same effect as the @code{IGNORE n LINES} clause for @code{LOAD DATA}.
@item
Fixed bug in @code{UNION} with last offset being transposed to total result
set.
@item
@code{REPAIR ... USE_FRM} added.
@item
Fixed that @code{DEFAULT_SELECT_LIMIT} is always imposed on @code{UNION}
result set.
@item
Fixed that some @code{SELECT} options can appear only in the first
@code{SELECT}.
@item
Fixed bug with @code{LIMIT} with @code{UNION}, where last select is in
the braces.
@item
Fixed that full-text works fine with @code{UNION} operations.
@item
Fixed bug with indexless boolean full-text search.
@item
Fixed bug that sometimes appeared when full-text search was used
with @code{const} tables.
@item
Fixed incorrect error value when doing a @code{SELECT} with an empty
@code{HEAP} table.
@item
Use @code{ORDER BY column DESC} now sorts @code{NULL} values first.
(In other words, @code{NULL} values sort first in all cases, whether or
not @code{DESC} is specified.)  This is changed back in 4.0.10.
@item
Fixed bug in @code{WHERE key_name='constant' ORDER BY key_name DESC}.
@item
Fixed bug in @code{SELECT DISTINCT ... ORDER BY DESC} optimization.
@item
Fixed bug in @code{... HAVING 'GROUP_FUNCTION'(@var{xxx}) IS [NOT] NULL}.
@item
Fixed bug in truncation operator for boolean full-text search.
@item
Allow value of @code{--user=#} option for @command{mysqld} to be specified
as a numeric user ID.
@item
Fixed a bug where @code{SQL_CALC_ROWS} returned an incorrect value when used
with one table and @code{ORDER BY} and with @code{InnoDB} tables.
@item
Fixed that @code{SELECT 0 LIMIT 0} doesn't hang thread.
@item
Fixed some problems with @code{USE/IGNORE INDEX} when using
many keys with the same start column.
@item
Don't use table scan with @code{BerkeleyDB} and @code{InnoDB} tables when
we can use an index that covers the whole row.
@item
Optimized @code{InnoDB} sort-buffer handling to take less memory.
@item
Fixed bug in multiple-table @code{DELETE} and @code{InnoDB} tables.
@item
Fixed problem with @code{TRUNCATE} and @code{InnoDB} tables that produced the
error @code{Can't execute the given command because you have active locked
tables or an active transaction}.
@item
Added @code{NO_UNSIGNED_SUBTRACTION} to the set of flags that may be
specified with the @code{--sql-mode} option for @command{mysqld}.  It disables
unsigned arithmetic rules when it comes to subtraction. (This will make
MySQL 4.0 behave more like 3.23 with @code{UNSIGNED} columns).
@item
The result returned for all bit functions (@code{|}, @code{<<}, ...) is now of
type @code{unsigned integer}.
@item
Added detection of @code{nan} values in @code{MyISAM} to make it possible to
repair tables with @code{nan} in float or double columns.
@item
Fixed new bug in @command{myisamchk} where it didn't correctly update number of
``parts'' in the @code{MyISAM} index file.
@item
Changed to use @command{autoconf} 2.52 (from @command{autoconf} 2.13).
@item
Fixed optimization problem where the MySQL Server was in ``preparing'' state
for a long time when selecting from an empty table which had contained
a lot of rows.
@item
Fixed bug in complicated join with @code{const} tables. This fix also
improves performance a bit when referring to another table from a
@code{const} table.
@item
First pre-version of multiple-table @code{UPDATE} statement.
@item
Fixed bug in multiple-table @code{DELETE}.
@item
Fixed bug in @code{SELECT CONCAT(argument_list) ... GROUP BY 1}.
@item
@code{INSERT ... SELECT} did a full rollback in case of an error. Fixed
so that we only roll back the last statement in the current transaction.
@item
Fixed bug with empty expression for boolean full-text search.
@item
Fixed core dump bug in updating full-text key from/to @code{NULL}.
@item
ODBC compatibility: Added @code{BIT_LENGTH()} function.
@item
Fixed core dump bug in @code{GROUP BY BINARY column}.
@item
Added support for @code{NULL} keys in @code{HEAP} tables.
@item
Use index for @code{ORDER BY} in queries of type:
@code{SELECT * FROM t WHERE key_part1=1 ORDER BY key_part1 DESC, key_part2 DESC}
@item
Fixed bug in @code{FLUSH QUERY CACHE}.
@item
Added @code{CAST()} and @code{CONVERT()} functions. The @code{CAST} and
@code{CONVERT} functions are nearly identical and mainly useful when you
want to create a column with a specific type in a @code{CREATE ... SELECT}
statement.  For more information, read @ref{Cast Functions}.
@item
@code{CREATE ... SELECT} on @code{DATE} and @code{TIME} functions now
create columns of the expected type.
@item
Changed order in which keys are created in tables.
@item
Added new columns @code{Null} and @code{Index_type} to @code{SHOW INDEX}
output.
@item
Added @code{--no-beep} and @code{--prompt} options to @command{mysql} command-line client.
@item
New feature: management of user resources.
@example
GRANT ... WITH MAX_QUERIES_PER_HOUR N1
               MAX_UPDATES_PER_HOUR N2
               MAX_CONNECTIONS_PER_HOUR N3;
@end example
@xref{User resources}.

@item
Added @code{mysql_secure_installation} to the @file{scripts/} directory.
@end itemize


@node News-4.0.1, News-4.0.0, News-4.0.2, News-4.0.x
@appendixsubsec Changes in release 4.0.1 (23 Dec 2001)

@itemize @bullet
@item
Added @code{system} command to @command{mysql}.
@item
Fixed bug when @code{HANDLER} was used with some unsupported table type.
@item
@command{mysqldump} now puts @code{ALTER TABLE @var{tbl_name} DISABLE KEYS} and
@code{ALTER TABLE @var{tbl_name} ENABLE KEYS} in the sql dump.
@item
Added @command{mysql_fix_extensions} script.
@item
Fixed stack overrun problem with @code{LOAD DATA FROM MASTER} on OSF/1.
@item
Fixed shutdown problem on HP-UX.
@item
Added @code{DES_ENCRYPT()} and @code{DES_DECRYPT()} functions.
@item
Added @code{FLUSH DES_KEY_FILE} statement.
@item
Added @code{--des-key-file} option to @command{mysqld}.
@item
@code{HEX(@var{str})} now returns the characters in @var{str} converted to
hexadecimal.
@item
Fixed problem with @code{GRANT} when using @code{lower_case_table_names=1}.
@item
Changed @code{SELECT ... IN SHARE MODE} to
@code{SELECT ... LOCK IN SHARE MODE} (as in MySQL 3.23).
@item
A new query cache to cache results from identical @code{SELECT} queries.
@item
Fixed core dump bug on 64-bit machines when it got an incorrect communication
packet.
@item
@code{MATCH ... AGAINST(... IN BOOLEAN MODE)} can now work
without @code{FULLTEXT} index.
@item
Fixed slave to replicate from 3.23 master.
@item
Miscellaneous replication fixes/cleanup.
@item
Got shutdown to work on Mac OS X.
@item
Added @code{myisam/ft_dump} utility for low-level inspection
of @code{FULLTEXT} indexes.
@item
Fixed bug in @code{DELETE ... WHERE ... MATCH ...}.
@item
Added support for @code{MATCH ... AGAINST(... IN BOOLEAN MODE)}.
@strong{Note}: You must rebuild your tables with
@code{ALTER TABLE @var{tbl_name} TYPE=MyISAM} to be
able to use boolean full-text search.
@item
@code{LOCATE()} and @code{INSTR()} are now case sensitive if either
argument is a binary string.
@item
Changed @code{RAND()} initialization so that @code{RAND(N)} and
@code{RAND(N+1)} are more distinct.
@item
Fixed core dump bug in @code{UPDATE ... ORDER BY}.
@item
In 3.23, @code{INSERT INTO ... SELECT} always had @code{IGNORE} enabled.
Now MySQL will stop (and possibly roll back) by default in case of an error
unless you specify @code{IGNORE}.
@item
Ignore @code{DATA DIRECTORY} and @code{INDEX DIRECTORY} directives on Windows.
@item
Added boolean full-text search code. It should be considered early alpha.
@item
Extended @code{MODIFY} and @code{CHANGE} in @code{ALTER TABLE} to accept
the @code{FIRST} and @code{AFTER} keywords.
@item
Indexes are now used with @code{ORDER BY} on a whole @code{InnoDB} table.
@end itemize


@node News-4.0.0,  , News-4.0.1, News-4.0.x
@appendixsubsec Changes in release 4.0.0 (Oct 2001: Alpha)

@itemize @bullet
@item
Added @code{--xml} option to @command{mysql} for producing XML output.
@item
Added full-text variables @code{ft_min_word_len}, @code{ft_max_word_len}, and
@code{ft_max_word_len_for_sort} system variables.
@item
Added full-text variables @code{ft_min_word_len}, @code{ft_max_word_len}, and
@code{ft_max_word_len_for_sort} variables to @command{myisamchk}.
@item
Added documentation for @code{libmysqld}, the embedded MySQL server
library.  Also added example programs (a @command{mysql} client and
@command{mysqltest} test program) which use @code{libmysqld}.
@item
Removed all Gemini hooks from MySQL server.
@item
Removed @code{my_thread_init()} and @code{my_thread_end()}
from @file{mysql_com.h}, and added @code{mysql_thread_init()} and
@code{mysql_thread_end()} to @file{mysql.h}.
@item
Support for communication packets > 16MB.  In 4.0.1 we will extend
@code{MyISAM} to be able to handle these.
@item
Secure connections (with SSL).
@item
Unsigned @code{BIGINT} constants now work. @code{MIN()} and @code{MAX()}
now handle signed and unsigned @code{BIGINT} numbers correctly.
@item
New character set @code{latin1_de} which provides correct German sorting.
@item
@code{STRCMP()} now uses the current character set when doing comparisons,
which means that the default comparison behavior now is case insensitive.
@item
@code{TRUNCATE TABLE} and @code{DELETE FROM @var{tbl_name}} are now separate
functions. One bonus is that @code{DELETE FROM @var{tbl_name}} now returns
the number of deleted rows, rather than zero.
@item
@code{DROP DATABASE} now executes a @code{DROP TABLE} on all tables in
the database, which fixes a problem with @code{InnoDB} tables.
@item
Added support for @code{UNION}.
@item
Added support for multiple-table @code{DELETE} operations.
@item
A new @code{HANDLER} interface to @code{MyISAM} tables.
@item
Added support for @code{INSERT} on @code{MERGE} tables. Patch from
Benjamin Pflugmann.
@item
Changed @code{WEEK(date,0)} to match the calendar in the USA.
@item
@code{COUNT(DISTINCT)} is about 30% faster.
@item
Speed up all internal list handling.
@item
Speed up @code{IS NULL}, @code{ISNULL()} and some other internal primitives.
@item
Full-text index creation now is much faster.
@item
Tree-like cache to speed up bulk inserts and
@code{myisam_bulk_insert_tree_size} variable.
@item
Searching on packed (@code{CHAR}/@code{VARCHAR}) keys is now much faster.
@item
Optimized queries of type:
@code{SELECT DISTINCT * FROM @var{tbl_name} ORDER by @var{key_part1} LIMIT @var{row_count}}.
@item
@code{SHOW CREATE TABLE} now shows all table attributes.
@item
@code{ORDER BY ... DESC} can now use keys.
@item
@code{LOAD DATA FROM MASTER} ``automatically'' sets up a slave.
@item
Renamed @command{safe_mysqld} to @command{mysqld_safe} to make this name more
in line with other MySQL scripts/commands.
@item
Added support for symbolic links to @code{MyISAM} tables. Symlink handling is
now enabled by default for Windows.
@item
Added @code{SQL_CALC_FOUND_ROWS} and @code{FOUND_ROWS()}. This makes it
possible to know how many rows a query would have returned
without a @code{LIMIT} clause.
@item
Changed output format of @code{SHOW OPEN TABLES}.
@item
Allow @code{SELECT expression LIMIT ...}.
@c commented out IDENTITY until someone explains what it means
@c @item
@c Added @code{IDENTITY} as a synonym for @code{AUTO_INCREMENT} (like Sybase).
@item
Added @code{ORDER BY} syntax to @code{UPDATE} and @code{DELETE}.
@item
@code{SHOW INDEXES} is now a synonym for @code{SHOW INDEX}.
@item
Added @code{ALTER TABLE @var{tbl_name} DISABLE KEYS} and
@code{ALTER TABLE @var{tbl_name} ENABLE KEYS} commands.
@item
Allow use of @code{IN} as a synonym for @code{FROM} in @code{SHOW} commands.
@item
Implemented ``repair by sort'' for @code{FULLTEXT} indexes.
@code{REPAIR TABLE}, @code{ALTER TABLE}, and @code{OPTIMIZE TABLE}
for tables with @code{FULLTEXT} indexes are now up to 100 times faster.
@item
Allow standard SQL syntax @code{X'@var{hexadecimal-number}'}.
@item
Cleaned up global lock handling for @code{FLUSH TABLES WITH READ LOCK}.
@item
Fixed problem with @code{DATETIME = constant} in @code{WHERE} optimization.
@item
Added @code{--master-data} and @code{--no-autocommit} options to
@command{mysqldump}. (Thanks to Brian Aker for this.)
@item
Added script @code{mysql_explain_log.sh} to distribution.
(Thanks to mobile.de).
@end itemize


@node News-3.23.x, News-3.22.x, News-4.0.x, News
@appendixsec Changes in release 3.23.x (Recent; still supported)

@cindex changes, version 3.23

Please note that since release 4.0 is now production level, only critical
fixes are done in the 3.23 release series. You are recommended to upgrade
when possible, to take advantage of all speed and feature improvements in
4.0. @xref{Upgrading-from-3.23}.

The 3.23 release has several major features that are not
present in previous versions.  We have added three new
table types:

@table @asis
@item @code{MyISAM}
A new @code{ISAM} library which is tuned for SQL and supports large files.
@item @code{InnoDB}
A transaction-safe storage engine that supports row level locking, and many
Oracle-like features.
@item @code{BerkeleyDB} or @code{BDB}
Uses the Berkeley DB library from Sleepycat Software to implement
transaction-safe tables.
@end table

Note that only @code{MyISAM} is available in the standard binary distribution.

The 3.23 release also includes support for database replication between
a master and many slaves, full-text indexing, and much more.

All new features are being developed in the 4.x version.  Only
bugfixes and minor enhancements to existing features will be
added to 3.23.

The replication code and BerkeleyDB code is still not as tested and as
the rest of the code, so we will probably need to do a couple of future
releases of 3.23 with small fixes for this part of the code. As long as
you don't use these features, you should be quite safe with
MySQL 3.23!

Note that the preceding remarks don't mean that replication or Berkeley DB don't
work.  We have done a lot of testing of all code, including replication
and @code{BDB} without finding any problems.  It only means that not as many
users use this code as the rest of the code and because of this we are
not yet 100% confident in this code.

@menu
* News-3.23.59::                Changes in release 3.23.59 (not released yet)
* News-3.23.58::                Changes in release 3.23.58 (11 Sep 2003)
* News-3.23.57::                Changes in release 3.23.57 (06 Jun 2003)
* News-3.23.56::                Changes in release 3.23.56 (13 Mar 2003)
* News-3.23.55::                Changes in release 3.23.55 (23 Jan 2003)
* News-3.23.54::                Changes in release 3.23.54 (05 Dec 2002)
* News-3.23.53::                Changes in release 3.23.53 (09 Oct 2002)
* News-3.23.52::                Changes in release 3.23.52 (14 Aug 2002)
* News-3.23.51::                Changes in release 3.23.51 (31 May 2002)
* News-3.23.50::                Changes in release 3.23.50 (21 Apr 2002)
* News-3.23.49::                Changes in release 3.23.49 (14 Feb 2002)
* News-3.23.48::                Changes in release 3.23.48 (07 Feb 2002)
* News-3.23.47::                Changes in release 3.23.47 (27 Dec 2001)
* News-3.23.46::                Changes in release 3.23.46 (29 Nov 2001)
* News-3.23.45::                Changes in release 3.23.45 (22 Nov 2001)
* News-3.23.44::                Changes in release 3.23.44 (31 Oct 2001)
* News-3.23.43::                Changes in release 3.23.43 (04 Oct 2001)
* News-3.23.42::                Changes in release 3.23.42 (08 Sep 2001)
* News-3.23.41::                Changes in release 3.23.41 (11 Aug 2001)
* News-3.23.40::                Changes in release 3.23.40 (18 Jul 2001)
* News-3.23.39::                Changes in release 3.23.39 (12 Jun 2001)
* News-3.23.38::                Changes in release 3.23.38 (09 May 2001)
* News-3.23.37::                Changes in release 3.23.37 (17 Apr 2001)
* News-3.23.36::                Changes in release 3.23.36 (27 Mar 2001)
* News-3.23.35::                Changes in release 3.23.35 (15 Mar 2001)
* News-3.23.34a::               Changes in release 3.23.34a (11 Mar 2001)
* News-3.23.34::                Changes in release 3.23.34 (10 Mar 2001)
* News-3.23.33::                Changes in release 3.23.33 (09 Feb 2001)
* News-3.23.32::                Changes in release 3.23.32 (22 Jan 2001)
* News-3.23.31::                Changes in release 3.23.31 (17 Jan 2001: Production)
* News-3.23.30::                Changes in release 3.23.30 (04 Jan 2001)
* News-3.23.29::                Changes in release 3.23.29 (16 Dec 2000)
* News-3.23.28::                Changes in release 3.23.28 (22 Nov 2000: Gamma)
* News-3.23.27::                Changes in release 3.23.27 (24 Oct 2000)
* News-3.23.26::                Changes in release 3.23.26 (18 Oct 2000)
* News-3.23.25::                Changes in release 3.23.25 (29 Sep 2000)
* News-3.23.24::                Changes in release 3.23.24 (08 Sep 2000)
* News-3.23.23::                Changes in release 3.23.23 (01 Sep 2000)
* News-3.23.22::                Changes in release 3.23.22 (31 Jul 2000)
* News-3.23.21::                Changes in release 3.23.21 (04 Jul 2000)
* News-3.23.20::                Changes in release 3.23.20 (28 Jun 2000: Beta)
* News-3.23.19::                Changes in release 3.23.19
* News-3.23.18::                Changes in release 3.23.18 (11 Jun 2000)
* News-3.23.17::                Changes in release 3.23.17 (07 Jun 2000)
* News-3.23.16::                Changes in release 3.23.16 (16 May 2000)
* News-3.23.15::                Changes in release 3.23.15 (08 May 2000)
* News-3.23.14::                Changes in release 3.23.14 (09 Apr 2000)
* News-3.23.13::                Changes in release 3.23.13 (14 Mar 2000)
* News-3.23.12::                Changes in release 3.23.12 (07 Mar 2000)
* News-3.23.11::                Changes in release 3.23.11 (16 Feb 2000)
* News-3.23.10::                Changes in release 3.23.10 (30 Jan 2000)
* News-3.23.9::                 Changes in release 3.23.9 (29 Jan 2000)
* News-3.23.8::                 Changes in release 3.23.8 (02 Jan 2000)
* News-3.23.7::                 Changes in release 3.23.7 (10 Dec 1999)
* News-3.23.6::                 Changes in release 3.23.6 (15 Nov 1999)
* News-3.23.5::                 Changes in release 3.23.5 (20 Oct 1999)
* News-3.23.4::                 Changes in release 3.23.4 (28 Sep 1999)
* News-3.23.3::                 Changes in release 3.23.3 (13 Sep 1999)
* News-3.23.2::                 Changes in release 3.23.2 (09 Aug 1999)
* News-3.23.1::                 Changes in release 3.23.1 (08 Jul 1999)
* News-3.23.0::                 Changes in release 3.23.0 (05 Jul 1999: Alpha)
@end menu

@node News-3.23.59, News-3.23.58, News-3.23.x, News-3.23.x
@appendixsubsec Changes in release 3.23.59 (not released yet)

@c NOTE: References to bug numbers should be written after the sentence
@c NOTE: describing the bugfix, like this:
@c NOTE: This sentence describes the fix. (Bug #nnnn)

@itemize @bullet
@item
Fixed an old bug in concurrent accesses to @code{MERGE} tables
(even one @code{MERGE} table and @code{MyISAM} tables), that could've
resulted in a crash or hang of the server. (Bug #2408)
@item
Fixed incorrect destruction of expression which led to crash of server on
complex @code{AND}/@code{OR} expressions if query was ignored (either by a
replication server because of @code{--replicate-*-table} rules, or by any MySQL
server because of a syntax error). (Bug #3969, Bug #4494)
@item
Fixed problem with parsing complex queries on 64-bit architectures.
(Bug #4204)
@item
Fixed a symlink vulnerability in @file{mysqlbug} script
(vulnerability ID CAN-2004-0381). (Bug #3284)
@item
Fixed bug in privilege checking of @code{ALTER TABLE RENAME}. (Bug #3270)
@item
Fixed bugs in @code{ACOS()}, @code{ASIN()} (Bug #2338) 
and in @code{FLOOR()} (Bug #3051).
The cause of the problem is an overly strong optimization done by @command{gcc}
in this case.
@item
Fixed bug in @code{INSERT ... SELECT} statements where, if a @code{NOT NULL}
column is assigned a value of @code{NULL}, the following columns in the row
might be assigned a value of zero.  (Bug #2012)
@item
If a query was ignored on the slave (because of
@code{--replicate-ignore-table} and other similar rules), the slave
still checked if the query got the same error code (0, no error) as on
the master. So if the master had an error on the query (for example,
``Duplicate entry'' in a multiple-row insert), then the slave stopped
and warned that the error codes didn't match. This is a backport of the
fix for MySQL 4.0. (Bug #797)
@item
@command{mysqlbinlog} now asks for a password at console when the
@code{-p/--password} option is used with no argument. This is how the
other clients (@command{mysqladmin}, @command{mysqldump}..) already
behave. Note that one now has to use @command{mysqlbinlog -p<my_password>};
@command{mysqlbinlog -p <my_password>} will not work anymore (in other
words, put no space after @code{-p}). (Bug #1595)
@item
On some 64-bit machines (some HP-UX and Solaris machines), a slave
installed with the 64-bit MySQL binary could not connect to its master
(it connected to itself instead). (Bug #1256, Bug #1381)
@item
Fixed a Windows-specific bug present since MySQL 3.23.57 and
3.23.58 that caused Windows slaves to crash when they started
replication if a @file{master.info} file existed. (Bug #1720)
@item
Fixed bug in @code{ALTER TABLE RENAME}, when rename to the table with
the same name in another database silently dropped destination table if
it existed. (Bug #2628)
@item
Fixed potential memory overrun in @code{mysql_real_connect()} (which
required a compromised DNS server and certain operating systems). (Bug #4017)
@end itemize

@node News-3.23.58, News-3.23.57, News-3.23.59, News-3.23.x
@appendixsubsec Changes in release 3.23.58 (11 Sep 2003)

@itemize @bullet
@item
Fixed buffer overflow in password handling which could potentially be
exploited by MySQL users with @code{ALTER} privilege on the
@code{mysql.user} table to execute random code or to gain shell access with
the UID of the @command{mysqld} process (thanks to Jedi/Sector One for spotting and
reporting this bug).
@item
@command{mysqldump} now correctly quotes all identifiers when communicating
with the server. This assures that during the dump process, @command{mysqldump}
will never send queries to the server that result in a syntax error. This
problem is @strong{not} related to the @command{mysqldump} program's output,
which was not changed. (Bug #1148)
@item
Fixed table/column grant handling: The proper sort order (from most specific
to less specific, @pxref{Request access}) was not honored. (Bug #928)
@item
Fixed overflow bug in @code{MyISAM} and @code{ISAM} when a row is updated
in a table with a large number of columns and at least one @code{BLOB/TEXT}
column.
@item
Fixed MySQL so that field length (in C API) for the second column in
@code{SHOW CREATE TABLE} is always larger than the data length.
The only known application that was affected by the old behavior was
Borland dbExpress, which truncated the output from the command.
(Bug #1064)
@item
Fixed @code{ISAM} bug in @code{MAX()} optimization.
@item
Fixed @code{Unknown error} when doing @code{ORDER BY} on reference table which
was used with @code{NULL} value on @code{NOT NULL} column. (Bug #479)
@end itemize

@node News-3.23.57, News-3.23.56, News-3.23.58, News-3.23.x
@appendixsubsec Changes in release 3.23.57 (06 Jun 2003)

@itemize @bullet
@item
Fixed problem in alarm handling that could cause problems when getting a
packet that is too large.
@item
Fixed problem when installing MySQL as a service on Windows when two
arguments were specified to @command{mysqld} (option file group name and
service name).
@item
Fixed @code{kill pid-of-mysqld} to work on Mac OS X.
@item
@code{SHOW TABLE STATUS} displayed incorrect @code{Row_format} value for
tables that have been compressed with @command{myisampack}.
(Bug #427)
@item
@code{SHOW VARIABLES LIKE 'innodb_data_file_path'} displayed only the
name of the first data file. (Bug #468)
@item
Fixed security problem where @command{mysqld} didn't allow one to @code{UPDATE}
rows in a table even if one had a global @code{UPDATE} privilege and a
database @code{SELECT} privilege.
@item
Fixed a security problem with @code{SELECT} and wildcarded select list,
when user only had partial column @code{SELECT} privileges on the table.
@item
Fixed unlikely problem in optimizing @code{WHERE} clause with a constant
expression such as in @code{WHERE 1 AND (a=1 AND b=1)}.
@item
Fixed problem on IA-64 with timestamps that caused @command{mysqlbinlog} to fail.
@item
The default option for @code{innodb_flush_log_at_trx_commit} was changed
from 0 to 1 to make @code{InnoDB} tables ACID by default.
@xref{InnoDB start, , @code{InnoDB} start}.
@item
Fixed problem with too many allocated alarms on slave when connecting to
master many times (normally not a very critical error).
@item
Fixed a bug in replication of temporary tables. (Bug #183)
@item
Fixed 64-bit bug that affected at least AMD hammer systems.
@item
Fixed a bug when doing @code{LOAD DATA INFILE IGNORE}: When reading
the binary log, @command{mysqlbinlog} and the replication code read @code{REPLACE}
instead of @code{IGNORE}. This could make the slave's table
become different from the master's table. (Bug #218)
@item
Fixed overflow bug in @code{MyISAM} when a row is inserted into a table with a 
large number of columns and at least one @code{BLOB/TEXT} column. Bug was caused
by incorrect calculation of the needed buffer to pack data.
@item
The binary log was not locked during @code{TRUNCATE @var{tbl_name}} or
@code{DELETE FROM @var{tbl_name}} statements, which could cause an @code{INSERT} to
@var{tbl_name} to be written to the log before the
@code{TRUNCATE} or @code{DELETE} statements.
@item
Fixed rare bug in @code{UPDATE} of @code{InnoDB} tables where one row could be
updated multiple times.
@item
Produce an error for empty table and column names.
@item
Changed @code{PROCEDURE ANALYSE()} to report @code{DATE} instead of
@code{NEWDATE}.
@item
Changed @code{PROCEDURE ANALYSE(#)} to restrict the number of values in an
@code{ENUM} column to @code{#} also for string values.
@item
@command{mysqldump} no longer silently deletes the binary logs when invoked with
the @code{--master-data} or @code{--first-slave} option;
while this behavior was convenient for some
users, others may suffer from it. Now you must explicitly ask for binary
logs to be deleted by using the new @code{--delete-master-logs} option.
@item
Fixed a bug in @command{mysqldump} when it was invoked with the
@code{--master-data} option: The @code{CHANGE MASTER TO} statements that were
appended to the SQL dump had incorrect coordinates. (Bug #159)
@end itemize

@node News-3.23.56, News-3.23.55, News-3.23.57, News-3.23.x
@appendixsubsec Changes in release 3.23.56 (13 Mar 2003)
@itemize @bullet
@item
Fixed @command{mysqld} crash on extremely small values of
@code{sort_buffer} variable.
@item
Fixed a bug in privilege system for @code{GRANT UPDATE} on the column level.
@item
Fixed a rare bug when using a date in @code{HAVING} with @code{GROUP BY}.
@item
Fixed checking of random part of @code{WHERE} clause. (Bug #142)
@item
Fixed MySQL (and @command{myisamchk}) crash on artificially
corrupted @file{.MYI} files.
@item
Security enhancement:
@command{mysqld} no longer reads options from world-writable config files.
@item
Security enhancement:
@command{mysqld} and @command{safe_mysqld} now use only the first @code{--user}
option specified on the command line. (Normally this comes from
@file{/etc/my.cnf})
@item
Security enhancement:
Don't allow @code{BACKUP TABLE} to overwrite existing files.
@item
Fixed unlikely deadlock bug when one thread did a @code{LOCK TABLE} and
another thread did a @code{DROP TABLE}.  In this case one could do
a @code{KILL} on one of the threads to resolve the deadlock.
@item
@code{LOAD DATA INFILE} was not replicated by slave if
@code{replicate_*_table} was set on the slave.
@item
Fixed a bug in handling @code{CHAR(0)} columns that could cause incorrect
results from the query.
@item
Fixed a bug in @code{SHOW VARIABLES} on 64-bit platforms. The bug was
caused by incorrect declaration of variable @code{server_id}.
@item
The Comment column in @code{SHOW TABLE STATUS} now reports that it can
contain @code{NULL} values (which is the case for a crashed @file{.frm} file).
@item
Fixed the @code{rpl_rotate_logs} test to not fail on certain platforms (such as
Mac OS X) due to a too-long file name (changed @code{slave-master-info.opt}
to @code{.slave-mi}).
@item
Fixed a problem with @code{BLOB NOT NULL} columns used with @code{IS NULL}.
@item
Fixed bug in @code{MAX()} optimization in @code{MERGE} tables.
@item
Better @code{RAND()} initialization for new connections.
@item
Fixed bug with connect timeout. This bug was manifested on OS's with 
@code{poll()} system call, which resulted in timeout the value specified as
it was executed in both @code{select()} and @code{poll()}.
@item
Fixed bug in
@code{SELECT * FROM table WHERE datetime1 IS NULL OR datetime2 IS NULL}.
@item
Fixed bug in using aggregate functions as argument for @code{INTERVAL},
@code{CASE}, @code{FIELD}, @code{CONCAT_WS}, @code{ELT} and
@code{MAKE_SET} functions.
@item
When running with @code{--lower-case-table-names=1} (default on Windows)
and you had tables or databases with mixed case on disk, then
executing @code{SHOW TABLE STATUS} followed with @code{DROP DATABASE}
or @code{DROP TABLE} could fail with @code{Errcode 13}.
@item
Fixed bug in logging to binary log (which affects replication) a query
that inserts a @code{NULL} in an @code{auto_increment} field and also
uses @code{LAST_INSERT_ID()}.
@item
Fixed bug in @command{mysqladmin --relative}.
@item
On some 64-bit systems, @code{show status} reported a strange number for
@code{Open_files} and @code{Open_streams}.
@end itemize

@node News-3.23.55, News-3.23.54, News-3.23.56, News-3.23.x
@appendixsubsec Changes in release 3.23.55 (23 Jan 2003)
@itemize @bullet
@item
Fixed double @code{free}'d pointer bug in @code{mysql_change_user()}
handling, that enabled a specially hacked version of MySQL client
to crash @command{mysqld}. @strong{Note} that you must log in to the server
by using a valid user account to be able to exploit this bug.
@item
Fixed bug with the @code{--slow-log} when logging an administrator command
(like @code{FLUSH TABLES}).
@item
Fixed bug in @code{GROUP BY} when used on BLOB column with @code{NULL} values.
@item
Fixed a bug in handling @code{NULL} values in @code{CASE ... WHEN ...}.
@item
Bugfix for @code{--chroot} (@pxref{News-3.23.54, @code{--chroot}})
is reverted. Unfortunately, there is no way to make it to work, without
introducing backward-incompatible changes in @file{my.cnf}.
Those who need @code{--chroot} functionality, should upgrade to MySQL 4.0.
(The fix in the 4.0 branch did not break backward-compatibility).
@item
Make @code{--lower-case-table-names} default on Mac OS X as the default
filesystem (HFS+) is case insensitive.
@item
Fixed a bug in @file{scripts/mysqld_safe.sh} in @code{NOHUP_NICENESS}
testing.
@item
Transactions in @code{AUTOCOMMIT=0} mode didn't rotate binary log.
@item
Fixed a bug in @code{scripts/make_binary_distribution} that resulted in
a remaining @code{@@HOSTNAME@@} variable instead of replacing it with the
correct path to the @code{hostname} binary.
@item
Fixed a very unlikely bug that could cause @code{SHOW PROCESSLIST} to core
dump in pthread_mutex_unlock() if a new thread was connecting.
@item
Forbid @code{SLAVE STOP} if the thread executing the query has locked
tables.  This removes a possible deadlock situation.
@end itemize

@node News-3.23.54, News-3.23.53, News-3.23.55, News-3.23.x
@appendixsubsec Changes in release 3.23.54 (05 Dec 2002)
@itemize @bullet
@item
Fixed a bug, that allowed to crash @command{mysqld}
with a specially crafted packet.
@item
Fixed a rare crash (double @code{free}'d pointer) when altering a
temporary table.
@item
Fixed buffer overrun in @code{libmysqlclient} library
that allowed malicious MySQL server to crash the client
application.
@item
Fixed security-related bug in @code{mysql_change_user()} handling.
All users are strongly recommended to upgrade to the version 3.23.54.
@item
Fixed bug that prevented @code{--chroot} command-line option of @command{mysqld}
from working.
@item
Fixed bug that made @code{OPTIMIZE TABLE} to corrupt the table
under some rare circumstances.
@item
Fixed @command{mysqlcheck} so it can deal with table names containing dashes.
@item
Fixed shutdown problem on Mac OS X.
@item
Fixed bug with comparing an indexed @code{NULL} field with @code{<=> NULL}.
@item
Fixed bug that caused @code{IGNORE INDEX} and @code{USE INDEX} sometimes
to be ignored.
@item
Fixed rare core dump problem in complicated @code{GROUP BY} queries that
didn't return any result.
@item
Fixed a bug where @code{MATCH ... AGAINST () >=0} was treated as if it was
@code{>}.
@item
Fixed core dump in @code{SHOW PROCESSLIST} when running with an
active slave (unlikely timing bug).
@item
Make it possible to use  multiple MySQL servers on Windows (code backported
from 4.0.2).
@item
One can create @code{TEMPORARY} @code{MERGE} tables now.
@item
Fixed that @code{--core-file} works on Linux (at least on kernel 2.4.18).
@item
Fixed a problem with @code{BDB} and @code{ALTER TABLE}.
@item
Fixed reference to freed memory when doing complicated @code{GROUP BY
... ORDER BY} queries.  Symptom was that @command{mysqld} died in function
@code{send_fields}.
@item
Allocate heap rows in smaller blocks to get better memory usage.
@item
Fixed memory allocation bug when storing @code{BLOB} values in internal
temporary tables used for some (unlikely) @code{GROUP BY} queries.
@item
Fixed a bug in key optimizing handling where the expression
@code{WHERE @var{col_name} = @var{key_col_name}} was calculated as true
for @code{NULL} values.
@item
Fixed core dump bug when doing @code{LEFT JOIN ... WHERE @var{key_column}=NULL}.
@item
Fixed @code{MyISAM} crash when using dynamic-row tables with huge numbers of
packed fields.
@item
Updated source tree to be built using @command{automake} 1.5 and 
@command{libtool} 1.4.
@end itemize

@node News-3.23.53, News-3.23.52, News-3.23.54, News-3.23.x
@appendixsubsec Changes in release 3.23.53 (09 Oct 2002)
@itemize @bullet
@item
Fixed crash when @code{SHOW INNODB STATUS} was used and @code{skip-innodb}
was defined.
@item
Fixed possible memory corruption bug in binary log file handling when
slave rotated the logs (only affected 3.23, not 4.0).
@item
Fixed problem in @code{LOCK TABLES} on Windows when one connects to a
database that contains uppercase letters.
@item
Fixed that @code{--skip-show-database} doesn't reset the @code{--port} option.
@item
Small fix in @command{safe_mysqld} for some shells.
@item
Fixed that @code{FLUSH STATUS} doesn't reset @code{delayed_insert_threads}.
@item
Fixed core dump bug when using the @code{BINARY} cast on a @code{NULL} value.
@item
Fixed race condition when someone did a @code{GRANT} at the same time a new
user logged in or did a @code{USE database}.
@item
Fixed bug in @code{ALTER TABLE} and @code{RENAME TABLE} when running with
@code{-O lower_case_table_names=1} (typically on Windows) when giving the
table name in uppercase.
@item
Fixed that @code{-O lower_case_table_names=1} also converts database
names to lowercase.
@item
Fixed unlikely core dump with @code{SELECT ... ORDER BY ... LIMIT}.
@item
Changed @code{AND/OR} to report that they can return NULL. This fixes a
bug in @code{GROUP BY} on @code{AND/OR} expressions that return
@code{NULL}.
@item
Fixed a bug that @code{OPTIMIZE TABLE} of locked and modified @code{MyISAM} table,
reported table corruption.
@item
Fixed a @code{BDB}-related @code{ALTER TABLE} bug with dropping a column
and shutting down immediately thereafter.
@item
Fixed problem with @code{configure ... --localstatedir=...}.
@item
Fixed problem with @code{UNSIGNED BIGINT} on AIX (again).
@item
Fixed bug in pthread_mutex_trylock() on HPUX 11.0.
@item
Multi-threaded stress tests for @code{InnoDB}.
@end itemize

@node News-3.23.52, News-3.23.51, News-3.23.53, News-3.23.x
@appendixsubsec Changes in release 3.23.52 (14 Aug 2002)
@itemize @bullet
@item
Wrap @code{BEGIN}/@code{COMMIT} around transaction in the binary log.
This makes replication honor transactions.
@item
Fixed security bug when having an empty database name in the @code{user.db}
table.
@item
Changed initialization of @code{RAND()} to make it less predicatable.
@item
Fixed problem with @code{GROUP BY} on result with expression that created a
@code{BLOB} field.
@item
Fixed problem with @code{GROUP BY} on columns that have @code{NULL} values.
To solve this we now create an @code{MyISAM} temporary table when doing a
@code{GROUP BY} on a possible @code{NULL} item.
From MySQL 4.0.5 we can use in memory @code{HEAP} tables for this case.
@item
Fixed problem with privilege tables when downgrading from 4.0.2 to 3.23.
@item
Fixed thread bug in @code{SLAVE START}, @code{SLAVE STOP} and automatic repair
of @code{MyISAM} tables that could cause table cache to be corrupted.
@item
Fixed possible thread related key-cache-corruption problem with
@code{OPTIMIZE TABLE} and @code{REPAIR TABLE}.
@item
Added name of 'administrator command' logs.
@item
Fixed bug with creating an auto-increment value on second part of a
@code{UNIQUE()} key where first part could contain @code{NULL} values.
@item
Don't write slave-timeout reconnects to the error log.
@item
Fixed bug with slave net read timeouting
@item
Fixed a core-dump bug with @code{MERGE} tables and @code{MAX()} function.
@item
Fixed bug in @code{ALTER TABLE} with @code{BDB} tables.
@item
Fixed bug when logging @code{LOAD DATA INFILE} to binary log with no 
active database.
@item
Fixed a bug in range optimizer (causing crashes).
@item
Fixed possible problem in replication when doing @code{DROP DATABASE} on a
database with @code{InnoDB} tables.
@item
Fixed @code{mysql_info()} to return 0 for @code{Duplicates} value when using
@code{INSERT DELAYED IGNORE}.
@item
Added @code{-DHAVE_BROKEN_REALPATH} to the Mac OS X (darwin) compile
options in @file{configure.in} to fix a failure under high load.
@end itemize

@node News-3.23.51, News-3.23.50, News-3.23.52, News-3.23.x
@appendixsubsec Changes in release 3.23.51 (31 May 2002)

@itemize @bullet
@item
Fix bug with closing tags missing slash for @command{mysqldump} XML output.
@item
Remove endspace from @code{ENUM} values. (This fixed a problem with
@code{SHOW CREATE TABLE}.)
@item
Fixed bug in @code{CONCAT_WS()} that cut the result.
@item
Changed name of server variables @code{Com_show_master_stat} to
@code{Com_show_master_status} and @code{Com_show_slave_stat} to
@code{Com_show_slave_status}.
@item
Changed handling of @code{gethostbyname()} to make the client library
thread-safe even if @code{gethostbyname_r} doesn't exist.
@item
Fixed core-dump problem when giving a wrong password string to @code{GRANT}.
@item
Fixed bug in @code{DROP DATABASE} with symlinked directory.
@item
Fixed optimization problem with @code{DATETIME} and value outside
@code{DATETIME} range.
@item
Removed Sleepycat's @code{BDB} doc files from the source tree, as they're not
needed (MySQL covers @code{BDB} in its own documentation).
@item
Fixed MIT-pthreads to compile with @code{glibc} 2.2 (needed for
@command{make dist}).
@item
Fixed the @code{FLOAT(X+1,X)} is not converted to @code{FLOAT(X+2,X)}.
(This also affected @code{DECIMAL}, @code{DOUBLE} and @code{REAL} types)
@item
Fixed the result from @code{IF()} is case in-sensitive if the second and
third arguments are case sensitive.
@item
Fixed core dump problem on OSF/1 in @code{gethostbyname_r}.
@item
Fixed that underflowed decimal fields are not zero filled.
@item
If we get an overflow when inserting @code{'+11111'} for
@code{DECIMAL(5,0) UNSIGNED} columns, we will just drop the sign.
@item
Fixed optimization bug with @code{ISNULL(@var{expression_which_cannot_be_null})} and
@code{ISNULL(@var{constant_expression})}.
@item
Fixed host lookup bug in the @code{glibc} library that we used with the 3.23.50
Linux-x86 binaries.
@end itemize

@node News-3.23.50, News-3.23.49, News-3.23.51, News-3.23.x
@appendixsubsec Changes in release 3.23.50 (21 Apr 2002)

@itemize @bullet
@item
Fixed buffer overflow problem if someone specified a too-long @code{datadir}
parameter to @command{mysqld}.
@item
Add missing @code{<row>} tags for @command{mysqldump} XML output.
@item
Fixed problem with @code{crash-me} and @command{gcc} 3.0.4.
@item
Fixed that @code{@@@@unknown_variable} doesn't hang server.
@item
Added @code{@@@@VERSION} as a synonym for @code{VERSION()}.
@item
@code{SHOW VARIABLES LIKE '@var{xxx}'} is now case-insensitive.
@item
Fixed timeout for @code{GET_LOCK()} on HP-UX with DCE threads.
@item
Fixed memory allocation bug in the glibc library used to build Linux
binaries, which caused @command{mysqld} to die in @code{free()}.
@item
Fixed @code{SIGINT} and @code{SIGQUIT} problems in @command{mysql}.
@item
Fixed bug in character table converts when used with big (larger than 64KB)
strings.
@item
@code{InnoDB} now retains foreign key constraints through @code{ALTER TABLE}
and @code{CREATE/DROP INDEX}.
@item
@code{InnoDB} now allows foreign key constraints to be added through the
@code{ALTER TABLE} syntax.
@item
@code{InnoDB} tables can now be set to automatically grow in size (autoextend).
@item
Our Linux RPMS and binaries are now compiled with @command{gcc} 3.0.4, which
should make them a bit faster.
@item
Fixed some buffer overflow problems when reading startup parameters.
@item
Because of problems on shutdown we have now disabled named pipes on
Windows by default.  One can enable named pipes by starting @command{mysqld} with
@code{--enable-named-pipe}.
@item
Fixed bug when using @code{WHERE key_column = 'J' or key_column='j'}.
@item
Fixed core-dump bug when using @code{--log-bin} with @code{LOAD DATA
INFILE} without an active database.
@item
Fixed bug in @code{RENAME TABLE} when used with
@code{lower_case_table_names=1} (default on Windows).
@item
Fixed unlikely core-dump bug when using @code{DROP TABLE} on a table
that was in use by a thread that also used queries on only temporary tables.
@item
Fixed problem with @code{SHOW CREATE TABLE} and @code{PRIMARY KEY} when using
32 indexes.
@item
Fixed that one can use @code{SET PASSWORD} for the anonymous user.
@item
Fixed core dump bug when reading client groups from option files using
@code{mysql_options()}.
@item
Memory leak (16 bytes per every @strong{corrupted} table) closed.
@item
Fixed binary builds to use @code{--enable-local-infile}.
@item
Update source to work with new version of @command{bison}.
@item
Updated shell scripts to now agree with new POSIX standard.
@item
Fixed bug where @code{DATE_FORMAT()} returned empty string when used
with @code{GROUP BY}.
@end itemize

@node News-3.23.49, News-3.23.48, News-3.23.50, News-3.23.x
@appendixsubsec Changes in release 3.23.49 (14 Feb 2002)

@itemize @bullet
@item
For a @code{MERGE} table, @code{DELETE FROM merge_table} used without a
@code{WHERE} clause no longer clears the mapping for the table by emptying
the @file{.MRG} file. Instead, it deletes records from the mapped tables.
@item
Don't give warning for a statement that is only a comment; this is needed for
@command{mysqldump --disable-keys} to work.
@item
Fixed unlikely caching bug when doing a join without keys. In this case,
the last used field for a table always returned @code{NULL}.
@item
Added options to make @code{LOAD DATA LOCAL INFILE} more secure.
@item
MySQL binary release 3.23.48 for Linux contained a new @code{glibc} library,
which has serious problems under high load and Red Hat 7.2.  The 3.23.49 binary
release doesn't have this problem.
@item
Fixed shutdown problem on NT.
@end itemize

@node News-3.23.48, News-3.23.47, News-3.23.49, News-3.23.x
@appendixsubsec Changes in release 3.23.48 (07 Feb 2002)

@itemize @bullet
@item
Added @code{--xml} option to @command{mysqldump} for producing XML output.
@item
Changed to use @command{autoconf} 2.52 (from @command{autoconf} 2.13)
@item
Fixed bug in complicated join with @code{const} tables.
@item
Added internal safety checks for @code{InnoDB}.
@item
Some @code{InnoDB} variables were always shown in @code{SHOW VARIABLES} as
@code{OFF} on high-byte-first systems (like SPARC).
@item
Fixed problem with one thread using an @code{InnoDB} table and another
thread doing an @code{ALTER TABLE} on the same table. Before that,
@command{mysqld} could crash with an assertion failure in @file{row0row.c},
line 474.
@item
Tuned the @code{InnoDB} SQL optimizer to favor index searches more often
over table scans.
@item
Fixed a performance problem with @code{InnoDB} tables when several large
@code{SELECT} queries are run concurrently on a multiprocessor Linux
computer.  Large CPU-bound @code{SELECT} queries will now also generally
run faster on all platforms.
@item
If MySQL binary logging is used, @code{InnoDB} now prints after crash recovery the
latest MySQL binary log name and the offset @code{InnoDB} was able to recover
to. This is useful, for example, when resynchronizing a master and a
slave database in replication.
@item
Added better error messages to help in installation problems of @code{InnoDB}
tables.
@item
It is now possible to recover MySQL temporary tables that have become
orphaned inside the @code{InnoDB} tablespace.
@item
@code{InnoDB} now prevents a @code{FOREIGN KEY} declaration where the
signedness is not the same in the referencing and referenced integer columns.
@item
Calling @code{SHOW CREATE TABLE} or @code{SHOW TABLE STATUS} could cause
memory corruption and make @command{mysqld} crash.  Especially at risk was
@command{mysqldump}, because it frequently calls @code{SHOW CREATE TABLE}.
@item
If inserts to several tables containing an @code{AUTO_INCREMENT} column were
wrapped inside one @code{LOCK TABLES}, @code{InnoDB} asserted in
@file{lock0lock.c}.
@item
In 3.23.47 we allowed several @code{NULL} values in a @code{UNIQUE} secondary
index for an @code{InnoDB} table.  But @code{CHECK TABLE} was not relaxed: it
reports the table as corrupt.  @code{CHECK TABLE} no longer complains in
this situation.
@item
@code{SHOW GRANTS} now shows @code{REFERENCES} instead of @code{REFERENCE}.
@end itemize

@node News-3.23.47, News-3.23.46, News-3.23.48, News-3.23.x
@appendixsubsec Changes in release 3.23.47 (27 Dec 2001)

@itemize @bullet
@item
Fixed bug when using the following construct:
@code{SELECT ... WHERE @var{key}=@@@var{var_name} OR @var{key}=@@@var{var_name2}}
@item
Restrict @code{InnoDB} keys to 500 bytes.
@item
@code{InnoDB} now supports @code{NULL} in keys.
@item
Fixed shutdown problem on HP-UX. (Introduced in 3.23.46)
@item
Fixed core dump bug in replication when using @code{SELECT RELEASE_LOCK()}.
@item
Added new statement: @code{DO @var{expr}[,@var{expr}]...}
@item
Added @code{slave-skip-errors} option.
@item
Added statistics variables for all MySQL commands. (@code{SHOW STATUS} is
now much longer.)
@item
Fixed default values for @code{InnoDB} tables.
@item
Fixed that @code{GROUP BY @var{expr} DESC} works.
@item
Fixed bug when using @code{t1 LEFT JOIN t2 ON t2.key=constant}.
@item
@command{mysql_config} now also works with binary (relocated) distributions.
@end itemize

@node News-3.23.46, News-3.23.45, News-3.23.47, News-3.23.x
@appendixsubsec Changes in release 3.23.46 (29 Nov 2001)

@itemize @bullet
@item
Fixed problem with aliased temporary table replication.
@item
@code{InnoDB} and @code{BDB} tables will now use index when doing an
@code{ORDER BY} on the whole table.
@item
Fixed bug where one got an empty set instead of a DEADLOCK error when using
@code{BDB} tables.
@item
One can now kill @code{ANALYZE TABLE}, @code{REPAIR TABLE}, and @code{OPTIMIZE TABLE} when
the thread is waiting to get a lock on the table.
@item
Fixed race condition in @code{ANALYZE TABLE}.
@item
Fixed bug when joining with caching (unlikely to happen).
@item
Fixed race condition when using the binary log and @code{INSERT DELAYED}
which could cause the binary log to have rows that were not yet written
to @code{MyISAM} tables.
@item
Changed caching of binary log to make replication slightly faster.
@item
Fixed bug in replication on Mac OS X.
@end itemize

@node News-3.23.45, News-3.23.44, News-3.23.46, News-3.23.x
@appendixsubsec Changes in release 3.23.45 (22 Nov 2001)

@itemize @bullet
@item
@code{(UPDATE|DELETE) ...WHERE MATCH} bugfix.
@item
shutdown should now work on Darwin (Mac OS X).
@item
Fixed core dump when repairing corrupted packed @code{MyISAM} files.
@item
@code{--core-file} now works on Solaris.
@item
Fix a bug which could cause @code{InnoDB} to complain if it cannot find
free blocks from the buffer cache during recovery.
@item
Fixed bug in @code{InnoDB} insert buffer B-tree handling that could cause
crashes.
@item
Fixed bug in @code{InnoDB} lock timeout handling.
@item
Fixed core dump bug in @code{ALTER TABLE} on a @code{TEMPORARY} @code{InnoDB}
table.
@item
Fixed bug in @code{OPTIMIZE TABLE} that reset index cardinality if it
was up to date.
@item
Fixed problem with @code{t1 LEFT_JOIN t2 ... WHERE t2.date_column IS NULL} when
date_column was declared as @code{NOT NULL}.
@item
Fixed bug with @code{BDB} tables and keys on @code{BLOB} columns.
@item
Fixed bug in @code{MERGE} tables on OS with 32-bit file pointers.
@item
Fixed bug in @code{TIME_TO_SEC()} when using negative values.
@end itemize

@node News-3.23.44, News-3.23.43, News-3.23.45, News-3.23.x
@appendixsubsec Changes in release 3.23.44 (31 Oct 2001)

@itemize @bullet
@item
Fixed @code{Rows_examined} count in slow query log.
@item
Fixed bug when using a reference to an @code{AVG()} column in @code{HAVING}.
@item
Fixed that date functions that require correct dates, like
@code{DAYOFYEAR(column)}, will return @code{NULL} for @code{0000-00-00} dates.
@item
Fixed bug in const-propagation when comparing columns of different
types. (@code{SELECT * FROM date_col="2001-01-01" and date_col=time_col})
@item
Fixed bug that caused error message @code{Can't write, because of unique
constraint} with some @code{GROUP BY} queries.
@item
Fixed problem with @code{sjis} character strings used within quoted table
names.
@item
Fixed core dump when using @code{CREATE ... FULLTEXT} keys with other
storage engines than @code{MyISAM}.
@item
Don't use @code{signal()} on Windows because this appears to not be
100% reliable.
@item
Fixed bug when doing @code{WHERE col_name=NULL} on an indexed column
that had @code{NULL} values.
@item
Fixed bug when doing @code{LEFT JOIN ...  ON (col_name = constant) WHERE col_name = constant}.
@item
When using replications, aborted queries that contained @code{%} could cause
a core dump.
@item
@code{TCP_NODELAY} was not used on some systems. (Speed problem.)
@item
Applied portability fixes for OS/2. (Patch by Yuri Dario.)
@end itemize

The following changes are for @code{InnoDB} tables:

@itemize @bullet
@item
Add missing @code{InnoDB} variables to @code{SHOW VARIABLES}.
@item
Foreign key checking is now done for @code{InnoDB} tables.
@item
@code{DROP DATABASE} now works also for @code{InnoDB} tables.
@item
@code{InnoDB} now supports data files and raw disk partitions bigger
than 4GB on those operating systems that have big files.
@item
@code{InnoDB} calculates better table cardinality estimates for the
MySQL optimizer.
@item
Accent characters in the default character set @code{latin1} are ordered
according to the MySQL ordering.

Note: If you are using @code{latin1} and have inserted characters whose
code is greater than 127 into an indexed @code{CHAR} column, you should
run @code{CHECK TABLE} on your table when you upgrade to 3.23.44, and
drop and reimport the table if @code{CHECK TABLE} reports an error!
@item
A new @file{my.cnf} parameter, @code{innodb_thread_concurrency}, helps in
performance tuning in heavily concurrent environments.
@item
A new @file{my.cnf} parameter, @code{innodb_fast_shutdown}, speeds up
server shutdown.
@item
A new @file{my.cnf} parameter, @code{innodb_force_recovery}, helps to save
your data in case the disk image of the database becomes corrupt.
@item
@code{innodb_monitor} has been improved and a new
@code{innodb_table_monitor} added.
@item
Increased maximum key length from 500 to 7000 bytes.
@item
Fixed a bug in replication of @code{AUTO_INCREMENT} columns with
multiple-line inserts.
@item
Fixed a bug when the case of letters changes in an update of an indexed
secondary column.
@item
Fixed a hang when there are more than 24 data files.
@item
Fixed a crash when @code{MAX(col)} is selected from an empty table, and
@code{col} is not the first column in a multi-column index.
@item
Fixed a bug in purge which could cause crashes.
@end itemize

@node News-3.23.43, News-3.23.42, News-3.23.44, News-3.23.x
@appendixsubsec Changes in release 3.23.43 (04 Oct 2001)

@itemize @bullet
@item
Fixed a bug in @code{INSERT DELAYED} and @code{FLUSH TABLES} introduced
in 3.23.42.
@item
Fixed unlikely bug, which returned non-matching rows, in @code{SELECT} with
many tables and multi-column indexes and 'range' type.
@item
Fixed an unlikely core dump bug when doing @code{EXPLAIN SELECT} when using
many tables and @code{ORDER BY}.
@item
Fixed bug in @code{LOAD DATA FROM MASTER} when using table with
@code{CHECKSUM=1}.
@item
Added unique error message when a DEADLOCK occurs during a transaction with
@code{BDB} tables.
@item
Fixed problem with @code{BDB} tables and @code{UNIQUE} columns defined
as @code{NULL}.
@item
Fixed problem with @command{myisampack} when using pre-space filled @code{CHAR}
columns.
@item
Applied patch from Yuri Dario for OS/2.
@item
Fixed bug in @code{--safe-user-create}.
@end itemize

@node News-3.23.42, News-3.23.41, News-3.23.43, News-3.23.x
@appendixsubsec Changes in release 3.23.42 (08 Sep 2001)

@itemize @bullet
@item
Fixed problem when using @code{LOCK TABLES} and @code{BDB} tables.
@item
Fixed problem with @code{REPAIR TABLE} on @code{MyISAM} tables with row
lengths in the range from 65517 to 65520 bytes.
@item
Fixed rare hang when doing @command{mysqladmin shutdown} when there was
a lot of activity in other threads.
@item
Fixed problem with @code{INSERT DELAYED} where delayed thread could be
hanging on @code{upgrading locks} for no apparent reason.
@item
Fixed problem with @command{myisampack} and @code{BLOB}.
@item
Fixed problem when one edited @file{.MRG} tables by hand.
(Patch from Benjamin Pflugmann).
@item
Enforce that all tables in a @code{MERGE} table come from the same
database.
@item
Fixed bug with @code{LOAD DATA INFILE} and transactional tables.
@item
Fix bug when using @code{INSERT DELAYED} with wrong column definition.
@item
Fixed core dump during @code{REPAIR TABLE} of some particularly broken tables.
@item
Fixed bug in @code{InnoDB} and @code{AUTO_INCREMENT} columns.
@item
Fixed bug in @code{InnoDB} and @code{RENAME TABLE} columns.
@item
Fixed critical bug in @code{InnoDB} and @code{BLOB} columns.  If you have
used @code{BLOB} columns larger than 8000 bytes in an @code{InnoDB}
table, it is necessary to dump the table with @command{mysqldump}, drop it and
restore it from the dump.
@item
Applied large patch for OS/2 from Yuri Dario.
@item
Fixed problem with @code{InnoDB} when one could get the error @code{Can't
execute the given command...} even when no transaction was active.
@item
Applied some minor fixes that concern Gemini.
@item
Use real arithmetic operations even in integer context if not
all arguments are integers. (Fixes uncommon bug in some integer
contexts).
@item
Don't force everything to lowercase on Windows. (To fix problem
with Windows and @code{ALTER TABLE}.)  Now @code{--lower_case_table_names}
also works on Unix.
@item
Fixed that automatic rollback is done when thread end doesn't lock
other threads.
@end itemize

@node News-3.23.41, News-3.23.40, News-3.23.42, News-3.23.x
@appendixsubsec Changes in release 3.23.41 (11 Aug 2001)

@itemize @bullet
@item
Added @code{--sql-mode=@var{value}[,@var{value}[,@var{value}]]} option to @command{mysqld}.
@xref{Server options}.
@item
Fixed possible problem with @code{shutdown} on Solaris where the
@file{.pid} file wasn't deleted.
@item
@code{InnoDB} now supports < 4GB rows. The former limit was 8000 bytes.
@item
The @code{doublewrite} file flush method is used in @code{InnoDB}.
It reduces the need for Unix @code{fsync()} calls to a fraction and
improves performance on most Unix flavors.
@item
You can now use the @code{InnoDB} Monitor to print a lot of @code{InnoDB} state
information, including locks, to the standard output.  This is useful in
performance tuning.
@item
Several bugs which could cause hangs in @code{InnoDB} have been fixed.
@item
Split @code{record_buffer} to @code{record_buffer} and
@code{record_rnd_buffer}.  To make things compatible to previous MySQL
versions, if @code{record_rnd_buffer} is not set, then it takes the
value of @code{record_buffer}.
@item
Fixed optimizing bug in @code{ORDER BY} where some @code{ORDER BY} parts
where wrongly removed.
@item
Fixed overflow bug with @code{ALTER TABLE} and @code{MERGE} tables.
@item
Added prototypes for @code{my_thread_init()} and @code{my_thread_end()} to
@file{mysql_com.h}
@item
Added @code{--safe-user-create} option to @command{mysqld}.
@item
Fixed bug in @code{SELECT DISTINCT ... HAVING} that caused error message
@code{Can't find record in #...}
@end itemize


@node News-3.23.40, News-3.23.39, News-3.23.41, News-3.23.x
@appendixsubsec Changes in release 3.23.40 (18 Jul 2001)

@itemize @bullet
@item
Fixed problem with @code{--low-priority-updates} and @code{INSERT} statements.
@item
Fixed bug in slave thread when under some rare circumstances it could
get 22 bytes ahead on the offset in the master.
@item
Added @code{slave_net_timeout} for replication.
@item
Fixed problem with @code{UPDATE} and @code{BDB} tables.
@item
Fixed hard bug in @code{BDB} tables when using key parts.
@item
Fixed problem when using @code{GRANT FILE ON database.* ...}; previously
we added the @code{DROP} privilege for the database.
@item
Fixed @code{DELETE FROM @var{tbl_name} ... LIMIT 0} and
@code{UPDATE FROM @var{tbl_name} ... LIMIT 0}, which acted as though the
@code{LIMIT} clause was not present (they deleted or updated all selected
rows).
@item
@code{CHECK TABLE} now checks whether an @code{AUTO_INCREMENT} column contains
the value 0.
@item
Sending a @code{SIGHUP} to @command{mysqld} will now only flush the logs,
not reset the replication.
@item
Fixed parser to allow floats of type @code{1.0e1} (no sign after @code{e}).
@item
Option @code{--force} to @command{myisamchk} now also updates states.
@item
Added option @code{--warnings} to @command{mysqld}. Now @command{mysqld}
prints the error @code{Aborted connection} only if this option is used.
@item
Fixed problem with @code{SHOW CREATE TABLE} when you didn't have a
@code{PRIMARY KEY}.
@item
Properly fixed the rename of @code{innodb_unix_file_flush_method} variable to
@code{innodb_flush_method}.
@item
Fixed bug when converting @code{BIGINT UNSIGNED} to @code{DOUBLE}. This caused
a problem when doing comparisons with @code{BIGINT} values outside of the
signed range.
@item
Fixed bug in @code{BDB} tables when querying empty tables.
@item
Fixed a bug when using @code{COUNT(DISTINCT)} with @code{LEFT JOIN} and
there weren't any matching rows.
@item
Removed all documentation referring to the @code{GEMINI} table
type. @code{GEMINI} is not released under an Open Source license.
@end itemize


@node News-3.23.39, News-3.23.38, News-3.23.40, News-3.23.x
@appendixsubsec Changes in release 3.23.39 (12 Jun 2001)

@itemize @bullet
@item
The @code{AUTO_INCREMENT} sequence wasn't reset when dropping
and adding an @code{AUTO_INCREMENT} column.
@item
@code{CREATE ... SELECT} now creates non-unique indexes delayed.
@item
Fixed problem where @code{LOCK TABLES @var{tbl_name} READ} followed by
@code{FLUSH TABLES} put an exclusive lock on the table.
@item
@code{REAL @@variable} values were represented with only 2 digits when
converted to strings.
@item
Fixed problem that client ``hung'' when @code{LOAD TABLE FROM MASTER} failed.
@item
@command{myisamchk --fast --force} will no longer repair tables
that only had the open count wrong.
@item
Added functions to handle symbolic links to make life easier in 4.0.
@item
We are now using the @code{-lcma} thread library on HP-UX 10.20 so
that MySQL will be more stable on HP-UX.
@item
Fixed problem with @code{IF()} and number of decimals in the result.
@item
Fixed date-part extraction functions to work with dates where day
and/or month is 0.
@item
Extended argument length in option files from 256 to 512 chars.
@item
Fixed problem with shutdown when @code{INSERT DELAYED} was waiting for
a @code{LOCK TABLE}.
@item
Fixed core dump bug in @code{InnoDB} when tablespace was full.
@item
Fixed problem with @code{MERGE} tables and big tables (larger than 4GB)
when using @code{ORDER BY}.
@end itemize


@node News-3.23.38, News-3.23.37, News-3.23.39, News-3.23.x
@appendixsubsec Changes in release 3.23.38 (09 May 2001)

@itemize @bullet
@item
Fixed a bug when @code{SELECT} from @code{MERGE} table
sometimes results in incorrectly ordered rows.
@item
Fixed a bug in @code{REPLACE()} when using the @code{ujis} character set.
@item
Applied Sleepycat @code{BDB} patches 3.2.9.1 and 3.2.9.2.
@item
Added @code{--skip-stack-trace} option to @command{mysqld}.
@item
@code{CREATE TEMPORARY} now works with @code{InnoDB} tables.
@item
@code{InnoDB} now promotes sub keys to whole keys.
@item
Added option @code{CONCURRENT} to @code{LOAD DATA}.
@item
Better error message when slave @code{max_allowed_packet} is too low to
read a very long log event from the master.
@item
Fixed bug when too many rows where removed when using
@code{SELECT DISTINCT ... HAVING}.
@item
@code{SHOW CREATE TABLE} now returns @code{TEMPORARY} for temporary tables.
@item
Added @code{Rows_examined} to slow query log.
@item
Fixed problems with function returning empty string when used together with
a group function and a @code{WHERE} that didn't match any rows.
@item
New program @command{mysqlcheck}.
@item
Added database name to output for administrative commands like @code{CHECK
TABLE}, @code{REPAIR TABLE}, @code{OPTIMIZE TABLE}.
@item
Lots of portability fixes for @code{InnoDB}.
@item
Changed optimizer so that queries like
@code{SELECT * FROM @var{tbl_name}, @var{tbl_name2} ... ORDER BY @var{key_part1} LIMIT @var{row_count}}
will use an index on @var{key_part1} instead of @code{filesort}.
@item
Fixed bug when doing
@code{LOCK TABLE @var{to_table} WRITE,...; INSERT INTO @var{to_table}... SELECT ...}
when @var{to_table} was empty.
@item
Fixed bug with @code{LOCK TABLE} and @code{BDB} tables.
@end itemize


@node News-3.23.37, News-3.23.36, News-3.23.38, News-3.23.x
@appendixsubsec Changes in release 3.23.37 (17 Apr 2001)

@itemize @bullet
@item
Fixed a bug when using @code{MATCH()} in @code{HAVING} clause.
@item
Fixed a bug when using @code{HEAP} tables with @code{LIKE}.
@item
Added @code{--mysql-version} option to @command{safe_mysqld}
@item
Changed @code{INNOBASE} to @code{InnoDB} (because the @code{INNOBASE}
name was already used). All @command{configure} options and @command{mysqld}
start options now use @code{innodb} instead of @code{innobase}. This
means that before upgrading to this version, you have to change any
configuration files where you have used @code{innobase} options!
@item
Fixed bug when using indexes on @code{CHAR(255) NULL} columns.
@item
Slave thread will now be started even if @code{master-host} is not set, as
long as @code{server-id} is set and valid @file{master.info} is present.
@item
Partial updates (terminated with kill) are now logged with a special error
code to the binary log. Slave will refuse to execute them if the error code
indicates the update was terminated abnormally, and will have to be recovered
with @code{SET SQL_SLAVE_SKIP_COUNTER=1; SLAVE START} after a manual sanity
check/correction of data integrity.
@item
Fixed bug that erroneously logged a drop of internal temporary table
on thread termination to the binary log --- this bug affected replication.
@item
Fixed a bug in @code{REGEXP} on 64-bit machines.
@item
@code{UPDATE} and @code{DELETE} with @code{WHERE unique_key_part IS NULL}
didn't update/delete all rows.
@item
Disabled @code{INSERT DELAYED} for tables that support transactions.
@item
Fixed bug when using date functions on @code{TEXT}/@code{BLOB} column
with wrong date format.
@item
UDFs now also work on Windows. (Patch by Ralph Mason.)
@item
Fixed bug in @code{ALTER TABLE} and @code{LOAD DATA INFILE} that disabled
key-sorting. These commands should now be faster in most cases.
@item
Fixed performance bug where reopened tables (tables that had been
waiting for @code{FLUSH} or @code{REPAIR TABLE}) would not use indexes for the
next query.
@item
Fixed problem with @code{ALTER TABLE} to @code{InnoDB} tables on FreeBSD.
@item
Added @command{mysqld} variables @code{myisam_max_sort_file_size} and
@code{myisam_max_extra_sort_file_size}.
@item
Initialize signals early to avoid problem with signals in @code{InnoDB}.
@item
Applied patch for the @code{tis620} character set to make comparisons
case-independent and to fix a bug in @code{LIKE} for this character set.
@strong{Note}: All tables that uses the @code{tis620} character set must be
fixed with  @command{myisamchk -r} or @code{REPAIR TABLE} !
@item
Added @code{--skip-safemalloc} option to @command{mysqld}.
@end itemize


@node News-3.23.36, News-3.23.35, News-3.23.37, News-3.23.x
@appendixsubsec Changes in release 3.23.36 (27 Mar 2001)

@itemize @bullet
@item
Fixed a bug that allowed use of database names containing a @samp{.}
character.  This fixes a serious security issue when @command{mysqld} is run
as root.
@item
Fixed bug when thread creation failed (could happen when doing a @strong{lot}
of connections in a short time).
@item
Fixed some problems with @code{FLUSH TABLES} and @code{TEMPORARY} tables.
(Problem with freeing the key cache and error @code{Can't reopen table...}.)
@item
Fixed a problem in @code{InnoDB} with other character sets than @code{latin1}
and another problem when using many columns.
@item
Fixed bug that caused a core dump when using a very complex query involving
@code{DISTINCT} and summary functions.
@item
Added @code{SET TRANSACTION ISOLATION LEVEL ...}
@item
Added @code{SELECT ... FOR UPDATE}.
@item
Fixed bug where the number of affected rows was not returned when MySQL
was compiled without transaction support.
@item
Fixed a bug in @code{UPDATE} where keys weren't always used to find the
rows to be updated.
@item
Fixed a bug in @code{CONCAT_WS()} where it returned incorrect results.
@item
Changed @code{CREATE ... SELECT} and @code{INSERT ... SELECT} to not
allow concurrent inserts as this could make the binary log hard to repeat.
(Concurrent inserts are enabled if you are not using the binary or update log.)
@item
Changed some macros to be able to use fast mutex with @code{glibc} 2.2.
@end itemize


@node News-3.23.35, News-3.23.34a, News-3.23.36, News-3.23.x
@appendixsubsec Changes in release 3.23.35 (15 Mar 2001)

@itemize @bullet
@item
Fixed newly introduced bug in @code{ORDER BY}.
@item
Fixed wrong define @code{CLIENT_TRANSACTIONS}.
@item
Fixed bug in @code{SHOW VARIABLES} when using @code{INNOBASE} tables.
@item
Setting and using user variables in @code{SELECT DISTINCT} didn't work.
@item
Tuned @code{SHOW ANALYZE} for small tables.
@item
Fixed handling of arguments in the benchmark script @code{run-all-tests}.
@end itemize


@node News-3.23.34a, News-3.23.34, News-3.23.35, News-3.23.x
@appendixsubsec Changes in release 3.23.34a (11 Mar 2001)

@itemize @bullet
@item
Added extra files to the distribution to allow @code{INNOBASE} support
to be compiled.
@end itemize


@node News-3.23.34, News-3.23.33, News-3.23.34a, News-3.23.x
@appendixsubsec Changes in release 3.23.34 (10 Mar 2001)

@itemize @bullet
@item
Added the @code{INNOBASE} storage engine and the @code{BDB} storage engine
to the MySQL source distribution.
@item
Updated the documentation about @code{GEMINI} tables.
@item
Fixed a bug in @code{INSERT DELAYED} that caused threads to hang when
inserting @code{NULL} into an @code{AUTO_INCREMENT} column.
@item
Fixed a bug in @code{CHECK TABLE} / @code{REPAIR TABLE} that could cause
a thread to hang.
@item
Fixed problem that @code{REPLACE} would not replace a row that conflicts
with an @code{AUTO_INCREMENT} generated key.
@item
@command{mysqld} now only sets @code{CLIENT_TRANSACTIONS} in
@code{mysql->server_capabilities} if the server supports a
transaction-safe storage engine.
@item
Fixed @code{LOAD DATA INFILE} to allow numeric values to be read into
@code{ENUM} and @code{SET} columns.
@item
Improved error diagnostic for slave thread exit.
@item
Fixed bug in @code{ALTER TABLE ... ORDER BY}.
@item
Added @code{max_user_connections} variable to @command{mysqld}.
@item
Limit query length for replication by @code{max_allowed_packet}, not the
arbitrary limit of 4MB.
@item
Allow space around @code{=} in argument to @code{--set-variable}.
@item
Fixed problem in automatic repair that could leave some threads in state
@code{Waiting for table}.
@item
@code{SHOW CREATE TABLE} now displays the @code{UNION=()} for @code{MERGE}
tables.
@item
@code{ALTER TABLE} now remembers the old @code{UNION=()} definition.
@item
Fixed bug when replicating timestamps.
@item
Fixed bug in bidirectional replication.
@item
Fixed bug in the @code{BDB} storage engine that occurred when using an index
on multiple-part key where a key part may be @code{NULL}.
@item
Fixed @code{MAX()} optimization on sub-key for @code{BDB} tables.
@item
Fixed problem where garbage results were returned when using @code{BDB}
tables and @code{BLOB} or @code{TEXT} fields when joining many tables.
@item
Fixed a problem with @code{BDB} tables and @code{TEXT} columns.
@item
Fixed bug when using a @code{BLOB} key where a const row wasn't found.
@item
Fixed that @command{mysqlbinlog} writes the timestamp value for each query.
This ensures that one gets same values for date functions like @code{NOW()}
when using @command{mysqlbinlog} to pipe the queries to another server.
@item
Allow @code{--skip-gemini}, @code{--skip-bdb}, and @code{--skip-innodb}
options to be specified when invoking @command{mysqld}, even if these storage
engines are not compiled in to @command{mysqld}.
@item
You can now use @code{ASC} and @code{DESC} with @code{GROUP BY} columns
to specify a sort order.
@item
Fixed a deadlock in the @code{SET} code, when one ran @code{SET @@foo=bar},
where @code{bar} is a column reference, an error was not properly generated.
@end itemize


@node News-3.23.33, News-3.23.32, News-3.23.34, News-3.23.x
@appendixsubsec Changes in release 3.23.33 (09 Feb 2001)

@itemize @bullet
@item
Fixed DNS lookups not to use the same mutex as the hostname
cache.  This will enable known hosts to be quickly resolved even if a
DNS lookup takes a long time.
@item
Added @code{--character-sets-dir} option to @command{myisampack}.
@item
Removed warnings when running @code{REPAIR TABLE ... EXTENDED}.
@item
Fixed a bug that caused a core dump when using @code{GROUP BY} on an alias,
where the alias was the same as an existing column name.
@item
Added @code{SEQUENCE()} as an example UDF function.
@item
Changed @command{mysql_install_db} to use @code{BINARY} for @code{CHAR}
columns in the privilege tables.
@item
Changed @code{TRUNCATE @var{tbl_name}} to @code{TRUNCATE TABLE @var{tbl_name}}
to use the same syntax as Oracle.  Until 4.0 we will also allow
@code{TRUNCATE @var{tbl_name}} to not crash old code.
@item
Fixed ``no found rows'' bug in @code{MyISAM} tables when a @code{BLOB} was
first part of a multiple-part key.
@item
Fixed bug where @code{CASE} didn't work with @code{GROUP BY}.
@item
Added @code{--sort-recover} option to @command{myisamchk}.
@item
@command{myisamchk -S} and @code{OPTIMIZE TABLE} now work on Windows.
@item
Fixed bug when using @code{DISTINCT} on results from functions that referred
to a group function, like:
@example
SELECT a, DISTINCT SEC_TO_TIME(SUM(a))
FROM @var{tbl_name} GROUP BY a, b;
@end example
@item
Fixed buffer overrun in @code{libmysqlclient} library.
Fixed bug in handling @code{STOP} event after @code{ROTATE} event in
replication.
@item
Fixed another buffer overrun in @code{DROP DATABASE}.
@item
Added @code{Table_locks_immediate} and @code{Table_locks_waited} status
variables.
@item
Fixed bug in replication that broke slave server start with existing
@file{master.info}. This fixes a bug introduced in 3.23.32.
@item
Added @code{SET SQL_SLAVE_SKIP_COUNTER=n} command to recover from
replication glitches without a full database copy.
@item
Added @code{max_binlog_size} variable; the binary log will be rotated
automatically when the size crosses the limit.
@item
Added @code{Last_Error}, @code{Last_Errno}, and @code{Slave_skip_counter}
variables to @code{SHOW SLAVE STATUS}.
@item
Fixed bug in @code{MASTER_POS_WAIT()} function.
@item
Execute core dump handler on @code{SIGILL}, and @code{SIGBUS} in addition to
@code{SIGSEGV}.
@item
On x86 Linux, print the current query and thread (connection) id, if
available, in the core dump handler.
@item
Fixed several timing bugs in the test suite.
@item
Extended @command{mysqltest} to take care of the timing issues in the test
suite.
@item
@code{ALTER TABLE} can now be used to change the definition for a
@code{MERGE} table.
@item
Fixed creation of @code{MERGE} tables on Windows.
@item
Portability fixes for OpenBSD and OS/2.
@item
Added @code{--temp-pool} option to @command{mysqld}.  Using this option
will cause most temporary files created to use a small set of names,
rather than a unique name for each new file.  This is to work around a
problem in the Linux kernel dealing with creating a bunch of new files
with different names.  With the old behavior, Linux seems to "leak"
memory, as it's being allocated to the directory entry cache instead of
the disk cache.
@end itemize


@node News-3.23.32, News-3.23.31, News-3.23.33, News-3.23.x
@appendixsubsec Changes in release 3.23.32 (22 Jan 2001)

@itemize @bullet
@item
Changed code to get around compiler bug in Compaq C++ on OSF/1, that broke
@code{BACKUP TABLE}, @code{RESTORE TABLE}, @code{CHECK TABLE}, @code{REPAIR TABLE}, and
@code{ANALYZE TABLE}.
@item
Added option @code{FULL} to @code{SHOW COLUMNS}. Now we show the
privilege list for the columns only if this option is given.
@item
Fixed bug in @code{SHOW LOGS} when there weren't any @code{BDB} logs.
@item
Fixed a timing problem in replication that could delay sending an update
to the client until a new update was done.
@item
Don't convert field names when using @code{mysql_list_fields()}.  This is
to keep this code compatible with @code{SHOW FIELDS}.
@item
@code{MERGE} tables didn't work on Windows.
@item
Fixed problem with @code{SET PASSWORD=...} on Windows.
@item
Added missing @file{my_config.h} to RPM distribution.
@item
@code{TRIM("foo" from "foo")} didn't return an empty string.
@item
Added @code{--with-version-suffix} option to @command{configure}.
@item
Fixed core dump when client aborted connection without @code{mysql_close()}.
@item
Fixed a bug in @code{RESTORE TABLE} when trying to restore from a non-existent
directory.
@item
Fixed a bug which caused a core dump on the slave when replicating
@code{SET PASSWORD}.
@item
Added @code{MASTER_POS_WAIT()} function.
@end itemize


@node News-3.23.31, News-3.23.30, News-3.23.32, News-3.23.x
@appendixsubsec Changes in release 3.23.31 (17 Jan 2001: Production)

@itemize @bullet
@item
The test suite now tests all reachable @code{BDB} interface code.  During
testing we found and fixed many errors in the interface code.
@item
Using @code{HAVING} on an empty table could produce one result row when
it shouldn't.
@item
Fixed the MySQL RPM so it no longer depends on Perl5.
@item
Fixed some problems with @code{HEAP} tables on Windows.
@item
@code{SHOW TABLE STATUS} didn't show correct average row length for tables
larger than 4GB.
@item
@code{CHECK TABLE ... EXTENDED} didn't check row links for fixed size tables.
@item
Added option @code{MEDIUM} to @code{CHECK TABLE}.
@item
Fixed problem when using @code{DECIMAL()} keys on negative numbers.
@item
@code{HOUR()} (and some other @code{TIME} functions) on a @code{CHAR} column
always returned @code{NULL}.
@item
Fixed security bug in something (please upgrade if you are using an earlier
MySQL 3.23 version).
@item
Fixed buffer overflow bug when writing a certain error message.
@item
Added usage of @code{setrlimit()} on Linux to get
@code{-O --open_files_limit=#} to work on Linux.
@item
Added @code{bdb_version} variable to @command{mysqld}.
@item
Fixed bug when using expression of type:
@example
SELECT ... FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=t2.a
@end example
In this case the test in the @code{WHERE} clause was wrongly optimized away.
@item
Fixed bug in @code{MyISAM} when deleting keys with possible @code{NULL}
values, but the first key-column was not a prefix-compressed text column.
@item
Fixed @command{mysql.server} to read the @code{[mysql.server]} option file group
rather than the @code{[mysql_server]} group.
@item
Fixed @command{safe_mysqld} and @command{mysql.server} to also read the
@code{server} option section.
@item
Added @code{Threads_created} status variable to @command{mysqld}.
@end itemize


@node News-3.23.30, News-3.23.29, News-3.23.31, News-3.23.x
@appendixsubsec Changes in release 3.23.30 (04 Jan 2001)

@itemize @bullet
@item
Added @code{SHOW OPEN TABLES} command.
@item
Fixed that @code{myisamdump} works against old @command{mysqld} servers.
@item
Fixed @command{myisamchk -k#} so that it works again.
@item
Fixed a problem with replication when the binary log file went over 2G
on 32-bit systems.
@item
@code{LOCK TABLES} will now automatically start a new transaction.
@item
Changed @code{BDB} tables to not use internal subtransactions and reuse
open files to get more speed.
@item
Added @code{--mysqld=#} option to @command{safe_mysqld}.
@item
Allow hex constants in the @code{--fields-*-by} and
@code{--lines-terminated-by} options to @command{mysqldump} and
@command{mysqlimport}. By Paul DuBois.
@item
Added @code{--safe-show-database} option to @command{mysqld}.
@item
Added @code{have_bdb}, @code{have_gemini}, @code{have_innobase},
@code{have_raid} and @code{have_openssl} to @code{SHOW VARIABLES} to make it
easy to test for supported extensions.
@item
Added @code{--open-files-limit} option to @command{mysqld}.
@item
Changed @code{--open-files} option to @code{--open-files-limit} in
@command{safe_mysqld}.
@item
Fixed a bug where some rows were not found with @code{HEAP} tables
that had many keys.
@item
Fixed that @code{--bdb-no-sync} works.
@item
Changed @code{--bdb-recover} to @code{--bdb-no-recover} as recover should
be on by default.
@item
Changed the default number of @code{BDB} locks to 10000.
@item
Fixed a bug from 3.23.29 when allocating the shared structure needed
for @code{BDB} tables.
@item
Changed @command{mysqld_multi.sh} to use configure variables. Patch by
Christopher McCrory.
@item
Added fixing of include files for Solaris 2.8.
@item
Fixed bug with @code{--skip-networking} on Debian Linux.
@item
Fixed problem that some temporary files where reported as having the
name @code{UNOPENED} in error messages.
@item
Fixed bug when running two simultaneous @code{SHOW LOGS} queries.
@end itemize


@node News-3.23.29, News-3.23.28, News-3.23.30, News-3.23.x
@appendixsubsec Changes in release 3.23.29 (16 Dec 2000)

@itemize @bullet
@item
Configure updates for Tru64, large file support, and better TCP wrapper
support. By Albert Chin-A-Young.
@item
Fixed bug in @code{<=>} operator.
@item
Fixed bug in @code{REPLACE} with @code{BDB} tables.
@item
@code{LPAD()} and @code{RPAD()} will shorten the result string if it's longer
than the length argument.
@item
Added @code{SHOW LOGS} command.
@item
Remove unused @code{BDB} logs on shutdown.
@item
When creating a table, put @code{PRIMARY} keys first, followed by
@code{UNIQUE} keys.
@item
Fixed a bug in @code{UPDATE} involving multiple-part keys where you
specified all key parts both in the update and the @code{WHERE} part. In
this case MySQL could try to update a record that didn't match
the whole @code{WHERE} part.
@item
Changed drop table to first drop the tables and then the @file{.frm} file.
@item
Fixed a bug in the hostname cache which caused @command{mysqld} to report the
hostname as @code{''} in some error messages.
@item
Fixed a bug with @code{HEAP} type tables; the variable
@code{max_heap_table_size} wasn't used. Now either @code{MAX_ROWS} or
@code{max_heap_table_size} can be used to limit the size of a @code{HEAP}
type table.
@item
Changed the default @code{server-id} value to 1 for masters and 2 for slaves
to make it easier to use the binary log.
@item
Renamed @code{bdb_lock_max} variable to @code{bdb_max_lock}.
@item
Added support for @code{AUTO_INCREMENT} on sub-fields for @code{BDB} tables.
@item
Added @code{ANALYZE TABLE} of @code{BDB} tables.
@item
In @code{BDB} tables, we now store the number of rows; this helps to optimize
queries when we need an approximation of the number of rows.
@item
If we get an error in a multiple-row statement, we now only roll back the
last statement, not the entire transaction.
@item
If you do a @code{ROLLBACK} when you have updated a non-transactional table
you will get an error as a warning.
@item
Added @code{--bdb-shared-data} option to @command{mysqld}.
@item
Added @code{Slave_open_temp_tables} status variable to @command{mysqld}
@item
Added @code{binlog_cache_size} and @code{max_binlog_cache_size} variables to
@command{mysqld}.
@item
@code{DROP TABLE}, @code{RENAME TABLE}, @code{CREATE INDEX} and
@code{DROP INDEX} are now transaction endpoints.
@item
If you do a @code{DROP DATABASE} on a symbolically linked database, both
the link and the original database are deleted.
@item
Fixed @code{DROP DATABASE} to work on OS/2.
@item
Fixed bug when doing a @code{SELECT DISTINCT ... table1 LEFT JOIN
table2 ...} when @code{table2} was empty.
@item
Added @code{--abort-slave-event-count} and
@code{--disconnect-slave-event-count} options to @command{mysqld} for
debugging and testing of replication.
@item
Fixed replication of temporary tables. Handles everything except
slave server restart.
@item
@code{SHOW KEYS} now shows whether key is @code{FULLTEXT}.
@item
New script @command{mysqld_multi}. @xref{mysqld_multi, , @command{mysqld_multi}}.
@item
Added new script, @code{mysql-multi.server.sh}.  Thanks to
Tim Bunce @email{Tim.Bunce@@ig.co.uk} for modifying @command{mysql.server} to
easily handle hosts running many @command{mysqld} processes.
@item
@command{safe_mysqld}, @command{mysql.server}, and @command{mysql_install_db} have
been modified to use @code{mysql_print_defaults} instead of various hacks
to read the @file{my.cnf} files.  In addition, the handling of various
paths has been made more consistent with how @command{mysqld} handles them
by default.
@item
Automatically remove Berkeley DB transaction logs that no longer are in
use.
@item
Fixed bug with several @code{FULLTEXT} indexes in one table.
@item
Added a warning if number of rows changes on @code{REPAIR
TABLE}/@code{OPTIMIZE TABLE}.
@item
Applied patches for OS/2 by @code{Yuri Dario}.
@item
@code{FLUSH TABLES @var{tbl_name}} didn't always flush the index tree
to disk properly.
@item
@code{--bootstrap} is now run in a separate thread. This fixes a problem
that caused @command{mysql_install_db} to core dump on some Linux machines.
@item
Changed @code{mi_create()} to use less stack space.
@item
Fixed bug with optimizer trying to over-optimize @code{MATCH()} when used
with @code{UNIQUE} key.
@item
Changed @code{crash-me} and the MySQL benchmarks to also work
with FrontBase.
@item
Allow @code{RESTRICT} and @code{CASCADE} after @code{DROP TABLE} to make
porting easier.
@item
Reset status variable which could cause problem if one used @code{--slow-log}.
@item
Added @code{connect_timeout} variable to @command{mysql} and @command{mysqladmin}.
@item
Added @code{connect-timeout} as an alias for @code{timeout} for option files
read by @code{mysql_options()}.
@end itemize


@node News-3.23.28, News-3.23.27, News-3.23.29, News-3.23.x
@appendixsubsec Changes in release 3.23.28 (22 Nov 2000: Gamma)

@itemize @bullet
@item
Added new options @code{--pager[=...]}, @code{--no-pager},
@code{--tee=...} and @code{--no-tee} to the @command{mysql} client.  The
new corresponding interactive commands are @code{pager}, @code{nopager},
@code{tee} and @code{notee}. @xref{mysql, , @command{mysql}}, @command{mysql --help}
and the interactive help for more information.
@item
Fixed crash when automatic repair of @code{MyISAM} table failed.
@item
Fixed a major performance bug in the table locking code when a lot
of @code{SELECT}, @code{UPDATE} and @code{INSERT} statements
constantly were running. The symptom was that the @code{UPDATE} and
@code{INSERT} queries were locked for a long time while new @code{SELECT}
statements were executed before the updates.
@item
When reading @code{options_files} with @code{mysql_options()} the
@code{return-found-rows} option was ignored.
@item
You can now specify @code{interactive-timeout} in the option file that
is read by @code{mysql_options()}. This makes it possible to force
programs that run for a long time (like @command{mysqlhotcopy}) to use the
@code{interactive_timeout} time instead of the @code{wait_timeout} time.
@item
Added to the slow query log the time and the username for each logged
query. If you are using @code{--log-long-format} then also queries that
do not use an index are logged, even if the query takes less than
@code{long_query_time} seconds.
@item
Fixed a problem in @code{LEFT JOIN} which caused all columns in a reference
table to be @code{NULL}.
@item
Fixed a problem when using @code{NATURAL JOIN} without keys.
@item
Fixed a bug when using a multiple-part keys where the first part was of type
@code{TEXT} or @code{BLOB}.
@item
@code{DROP} of temporary tables wasn't stored in the update/binary log.
@item
Fixed a bug where @code{SELECT DISTINCT * ... LIMIT @var{row_count}} only returned one row.
@item
Fixed a bug in the assembler code in @code{strstr()} for SPARC and cleaned up
the @file{global.h} header file to avoid a problem with bad aliasing with
the compiler submitted with Red Hat 7.0. (Reported by Trond Eivind Glomsr@o{}d)
@item
The @code{--skip-networking} option now works properly on NT.
@item
Fixed a long outstanding bug in the @code{ISAM} tables when a row with a length
of more than 65KB was shortened by a single byte.
@item
Fixed a bug in @code{MyISAM} when running multiple updating processes on
the same table.
@item
Allow one to use @code{FLUSH TABLE @var{tbl_name}}.
@item
Added @code{--replicate-ignore-table}, @code{--replicate-do-table},
@code{--replicate-wild-ignore-table}, and @code{--replicate-wild-do-table}
options to @command{mysqld}.
@item
Changed all log files to use our own @code{IO_CACHE} mechanism instead of
@code{FILE} to avoid OS problems when there are many files open.
@item
Added @code{--open-files} and @code{--timezone} options to @command{safe_mysqld}.
@item
Fixed a fatal bug in @code{CREATE TEMPORARY TABLE ... SELECT ...}.
@item
Fixed a problem with @code{CREATE TABLE ... SELECT NULL}.
@item
Added variables @code{large_file_support},@code{net_read_timeout},
@code{net_write_timeout} and @code{query_buffer_size} to @code{SHOW VARIABLES}.
@item
Added status variables @code{Created_tmp_files} and @code{Sort_merge_passes}
to @code{SHOW STATUS}.
@item
Fixed a bug where we didn't allow an index name after the
@code{FOREIGN KEY} definition.
@item
Added @code{TRUNCATE @var{tbl_name}} as a synonym for
@code{DELETE FROM @var{tbl_name}}.
@item
Fixed a bug in a @code{BDB} key compare function when comparing part keys.
@item
Added @code{bdb_lock_max} variable to @command{mysqld}.
@item
Added more tests to the benchmark suite.
@item
Fixed an overflow bug in the client code when using overly long database names.
@item
@code{mysql_connect()} now aborts on Linux if the server doesn't answer in
@code{timeout} seconds.
@item
@code{SLAVE START} did not work if you started with
@code{--skip-slave-start} and had not explicitly run @code{CHANGE MASTER TO}.
@item
Fixed the output of @code{SHOW MASTER STATUS} to be consistent with
@code{SHOW SLAVE STATUS}. (It now has no directory in the log name.)
@item
Added @code{PURGE MASTER LOGS TO}.
@item
Added @code{SHOW MASTER LOGS} statement to display a list of binary log files.
@item
Added @code{--safemalloc-mem-limit} option to @command{mysqld} to simulate memory
shortage when compiled with the @code{--with-debug=full} option.
@item
Fixed several core dumps in out-of-memory conditions.
@item
@code{SHOW SLAVE STATUS} was using an uninitialized mutex if the slave had
not been started yet.
@item
Fixed bug in @code{ELT()} and @code{MAKE_SET()} when the query used
a temporary table.
@item
@code{CHANGE MASTER TO} without specifying @code{MASTER_LOG_POS} would
set it to 0 instead of 4 and hit the magic number in the master binary log.
@item
@code{ALTER TABLE ... ORDER BY ...} syntax added.  This will create the
new table with the rows in a specific order.
@end itemize


@node News-3.23.27, News-3.23.26, News-3.23.28, News-3.23.x
@appendixsubsec Changes in release 3.23.27 (24 Oct 2000)

@itemize @bullet
@item
Fixed a bug where the automatic repair of @code{MyISAM} tables sometimes failed
when the data file was corrupt.
@item
Fixed a bug in @code{SHOW CREATE} when using @code{AUTO_INCREMENT} columns.
@item
Changed @code{BDB} tables to use new compare function in Berkeley DB 3.2.3.
@item
You can now use Unix socket files with MIT-pthreads.
@item
Added the @code{latin5} (turkish) character set.
@item
Small portability fixes.
@end itemize


@node News-3.23.26, News-3.23.25, News-3.23.27, News-3.23.x
@appendixsubsec Changes in release 3.23.26 (18 Oct 2000)

@itemize @bullet
@item
Renamed @code{FLUSH MASTER} and @code{FLUSH SLAVE} to @code{RESET MASTER}
and @code{RESET SLAVE}.
@item
Fixed @code{<>} to work properly with @code{NULL}.
@item
Fixed a problem with @code{SUBSTRING_INDEX()} and @code{REPLACE()}.
(Patch by Alexander Igonitchev)
@item
Fix @code{CREATE TEMPORARY TABLE IF NOT EXISTS} not to produce an error
if the table exists.
@item
If you don't create a @code{PRIMARY KEY} in a @code{BDB} table, a hidden
@code{PRIMARY KEY} will be created.
@item
Added read-only-key optimization to @code{BDB} tables.
@item
@code{LEFT JOIN} in some cases preferred a full table scan when there was
no @code{WHERE} clause.
@item
When using @code{--log-slow-queries}, don't count the time waiting for a lock.
@item
Fixed bug in lock code on Windows which could cause the key cache
to report that the key file was crashed even if it was okay.
@item
Automatic repair of @code{MyISAM} tables if you start @command{mysqld} with
@code{--myisam-recover}.
@item
Removed the @code{TYPE=} keyword from @code{CHECK TABLE} and
@code{REPAIR TABLE}. Allow @code{CHECK TABLE} options to be combined. (You can still
use @code{TYPE=}, but this usage is deprecated.)
@item
Fixed mutex bug in the binary replication log --- long update queries could
be read only in part by the slave if it did it at the wrong time, which
was not fatal, but resulted in a performance-degrading reconnect and
a scary message in the error log.
@item
Changed the format of the binary log --- added magic number, server
version, binary log version. Added the server ID and query error code for each
query event.
@item
Replication thread from the slave now will kill all the stale threads
from the same server.
@item
Long replication usernames were not being handled properly.
@item
Added @code{--replicate-rewrite-db} option to @command{mysqld}.
@item
Added @code{--skip-slave-start} option to @command{mysqld}.
@item
Updates that generated an error code (such as @code{INSERT INTO foo(some_key)
values (1),(1)}) erroneously terminated the slave thread.
@item
Added optimization of queries where @code{DISTINCT} is used only on columns
from some of the tables.
@item
Allow floating-point numbers where there is no sign after the exponent
(like @code{1e1}).
@item
@code{SHOW GRANTS} didn't always show all column grants.
@item
Added @code{--default-extra-file=#} option to all MySQL clients.
@item
Columns referenced in @code{INSERT} statements now are initialized properly.
@item
@code{UPDATE} didn't always work when used with a range on a timestamp that
was part of the key that was used to find rows.
@item
Fixed a bug in @code{FULLTEXT} index when inserting a @code{NULL} column.
@item
Changed to use @code{mkstemp()} instead of @code{tempnam()}. Based
on a patch from John Jones.
@end itemize


@node News-3.23.25, News-3.23.24, News-3.23.26, News-3.23.x
@appendixsubsec Changes in release 3.23.25 (29 Sep 2000)

@itemize @bullet
@item
Fixed that @code{databasename} works as second argument to @command{mysqlhotcopy}.
@item
The values for the @code{UMASK} and @code{UMASK_DIR} environment variables
now can be specified in octal by beginning the value with a zero.
@item
Added @code{RIGHT JOIN}. This makes @code{RIGHT} a reserved word.
@item
Added @code{@@@@IDENTITY} as a synonym for @code{LAST_INSERT_ID()}.
(This is for MSSQL compatibility.)
@item
Fixed a bug in @command{myisamchk} and @code{REPAIR TABLE} when using @code{FULLTEXT}
index.
@item
@code{LOAD DATA INFILE} now works with FIFOs.
(Patch by Toni L. Harbaugh-Blackford.)
@item
@code{FLUSH LOGS} broke replication if you specified a log name with an
explicit extension as the value of the @code{log-bin} option.
@item
Fixed a bug in @code{MyISAM} with packed multiple-part keys.
@item
Fixed crash when using @code{CHECK TABLE} on Windows.
@item
Fixed a bug where @code{FULLTEXT} index always used the @code{koi8_ukr}
character set.
@item
Fixed privilege checking for @code{CHECK TABLE}.
@item
The @code{MyISAM} repair/reindex code didn't use the @code{--tmpdir}
option for its temporary files.
@item
Added @code{BACKUP TABLE} and @code{RESTORE TABLE}.
@item
Fixed core dump on @code{CHANGE MASTER TO} when the slave did not have
the master to start with.
@item
Fixed incorrect @code{Time} in the processlist for @code{Connect} of
the slave thread.
@item
The slave now logs when it connects to the master.
@item
Fixed a core dump bug when doing @code{FLUSH MASTER} if you didn't specify
a filename argument to @code{--log-bin}.
@item
Added missing @file{ha_berkeley.x} files to the MySQL Windows distribution.
@item
Fixed some mutex bugs in the log code that could cause thread blocks if new
log files couldn't be created.
@item
Added lock time and number of selected processed rows to slow query log.
@item
Added @code{--memlock} option to @command{mysqld} to lock @command{mysqld}
in memory on systems with the @code{mlockall()} call (as in Solaris).
@item
@code{HEAP} tables didn't use keys properly. (Bug from 3.23.23.)
@item
Added better support for @code{MERGE} tables (keys, mapping, creation,
documentation...). @xref{MERGE storage engine, , @code{MERGE} storage engine}.
@item
Fixed bug in @command{mysqldump} from 3.23 which caused some @code{CHAR} columns
not to be quoted.
@item
Merged @code{analyze}, @code{check}, @code{optimize} and repair code.
@item
@code{OPTIMIZE TABLE} is now mapped to @code{REPAIR TABLE} with statistics and
sorting of the index tree.  This means that for the moment it only
works on @code{MyISAM} tables.
@item
Added a pre-alloced block to root_malloc to get fewer mallocs.
@item
Added a lot of new statistics variables.
@item
Fixed @code{ORDER BY} bug with @code{BDB} tables.
@item
Removed warning that @command{mysqld} couldn't remove the @file{.pid} file
under Windows.
@item
Changed @code{--log-isam} to log @code{MyISAM} tables instead of isam
tables.
@item
Fixed @code{CHECK TABLE} to work on Windows.
@item
Added file mutexes to make @code{pwrite()} safe on Windows.
@end itemize


@node News-3.23.24, News-3.23.23, News-3.23.25, News-3.23.x
@appendixsubsec Changes in release 3.23.24 (08 Sep 2000)

@itemize @bullet
@item
Added @code{Created_tmp_disk_tables} variable to @command{mysqld}.
@item
To make it possible to reliably dump and restore tables with
@code{TIMESTAMP(@var{X})} columns, MySQL now reports columns with @var{X}
other than 14 or 8 to be strings.
@item
Changed sort order for @code{latin1} as it was before MySQL 3.23.23.
Any table that was created or modified with 3.23.22 must be repaired if it has
@code{CHAR} columns that may contain characters with ASCII values greater than
128!
@item
Fixed small memory leak introduced from 3.23.22 when creating a
temporary table.
@item
Fixed problem with @code{BDB} tables and reading on a unique (not primary) key.
@item
Restored the @code{win1251} character set (it's now only marked deprecated).
@end itemize


@node News-3.23.23, News-3.23.22, News-3.23.24, News-3.23.x
@appendixsubsec Changes in release 3.23.23 (01 Sep 2000)

@itemize @bullet
@item
Changed sort order for 'German'; all tables created with 'German' sortorder
must be repaired with @code{REPAIR TABLE} or @command{myisamchk} before use!
@item
Added @code{--core-file} option to @command{mysqld} to get a core file on
Linux if @command{mysqld} dies on the @code{SIGSEGV} signal.
@item
MySQL client @command{mysql} now starts with option
@code{--no-named-commands} (@code{-g}) by default. This option can be
disabled with @code{--enable-named-commands} (@code{-G}). This may cause
incompatibility problems in some cases, for example, in SQL scripts that
use named commands without a semicolon, etc.!  Long format commands
still work from the first line.
@item
Fixed a problem when using many pending @code{DROP TABLE} statements at
the same time.
@item
Optimizer didn't use keys properly when using @code{LEFT JOIN} on an
empty table.
@item
Added shorter help text when invoking @command{mysqld} with incorrect options.
@item
Fixed non-fatal @code{free()} bug in @command{mysqlimport}.
@item
Fixed bug in @code{MyISAM} index handling of
@code{DECIMAL}/@code{NUMERIC} keys.
@item
Fixed a bug in concurrent insert in @code{MyISAM} tables.  In some contexts,
usage of @code{MIN(key_part)} or @code{MAX(key_part)} returned an empty set.
@item
Updated @command{mysqlhotcopy} to use the new @code{FLUSH TABLES table_list}
syntax. Only tables which are being backed up are flushed now.
@item
Changed behavior of @code{--enable-thread-safe-client} so
that both non-threaded (@code{-lmysqlclient}) and threaded
(@code{-lmysqlclient_r}) libraries are built.  Users who linked
against a threaded @code{-lmysqlclient} will need to link against
@code{-lmysqlclient_r} now.
@item
Added atomic @code{RENAME TABLE} command.
@item
Don't count @code{NULL} values in @code{COUNT(DISTINCT ...)}.
@item
Changed @code{ALTER TABLE}, @code{LOAD DATA INFILE} on empty tables and
@code{INSERT ... SELECT ...} on empty tables to create non-unique indexes
in a separate batch with sorting. This will make these statements much
faster when you have many indexes.
@item
@code{ALTER TABLE} now logs the first used insert_id correctly.
@item
Fixed crash when adding a default value to a @code{BLOB} column.
@item
Fixed a bug with @code{DATE_ADD/DATE_SUB} where it returned a datetime instead
of a date.
@item
Fixed a problem with the thread cache which made some threads show up as
@code{***DEAD***} in @code{SHOW PROCESSLIST}.
@item
Fixed a lock in our thr_rwlock code, which could make selects that run
at the same time as concurrent inserts crash. This affects only systems
that don't have the @code{pthread_rwlock_rdlock} code.
@item
When deleting rows with a non-unique key in a @code{HEAP} table, all rows
weren't always deleted.
@item
Fixed bug in range optimizer for @code{HEAP} tables for searches on a part
index.
@item
Fixed @code{SELECT} on part keys to work with @code{BDB} tables.
@item
Fixed @code{INSERT INTO bdb_table ... SELECT} to work with @code{BDB} tables.
@item
@code{CHECK TABLE} now updates key statistics for the table.
@item
@code{ANALYZE TABLE} will now only update tables that have been changed
since the last @code{ANALYZE TABLE}. Note that this is a new feature and tables
will not be marked to be analyzed until they are updated in any way with
3.23.23 or newer.  For older tables, you have to do @code{CHECK TABLE}
to update the key distribution.
@item
Fixed some minor privilege problems with @code{CHECK TABLE}, @code{ANALYZE
TABLE},
@code{REPAIR TABLE} and @code{SHOW CREATE} commands.
@item
Added @code{CHANGE MASTER TO} statement.
@item
Added @code{FAST}, @code{QUICK} @code{EXTENDED} check types to
@code{CHECK TABLES}.
@item
Changed @command{myisamchk} so that @code{--fast} and
@code{--check-only-changed} are also honored with @code{--sort-index} and
@code{--analyze}.
@item
Fixed fatal bug in @code{LOAD TABLE FROM MASTER} that did not lock the
table during index re-build.
@item
@code{LOAD DATA INFILE} broke replication if the database was excluded
from replication.
@item
More variables in @code{SHOW SLAVE STATUS} and @code{SHOW MASTER STATUS}.
@item
@code{SLAVE STOP} now will not return until the slave thread actually exits.
@item
Full-text search via the @code{MATCH()} function and @code{FULLTEXT} index type
(for @code{MyISAM} files).  This makes @code{FULLTEXT} a reserved word.
@end itemize


@node News-3.23.22, News-3.23.21, News-3.23.23, News-3.23.x
@appendixsubsec Changes in release 3.23.22 (31 Jul 2000)

@itemize @bullet
@item
Fixed that @code{lex_hash.h} is created properly for each MySQL
distribution.
@item
Fixed that @code{MASTER} and @code{COLLECTION} are not reserved words.
@item
The log generated by @code{--slow-query-log} didn't contain the whole queries.
@item
Fixed that open transactions in @code{BDB} tables are rolled back if the
connection is closed unexpectedly.
@item
Added workaround for a bug in @command{gcc} 2.96 (intel) and @command{gcc} 2.9
(IA-64) in @code{gen_lex_hash.c}.
@item
Fixed memory leak in the client library when using @code{host=} in the
@file{my.cnf} file.
@item
Optimized functions that manipulate the hours/minutes/seconds.
@item
Fixed bug when comparing the result of @code{DATE_ADD()}/@code{DATE_SUB()}
against a number.
@item
Changed the meaning of @code{-F, --fast} for @command{myisamchk}. Added
@code{-C, --check-only-changed} option to @command{myisamchk}.
@item
Added @code{ANALYZE @var{tbl_name}} to update key statistics for tables.
@item
Changed binary items @code{0x...} to be regarded as integers by default.
@item
Fix for SCO and @code{SHOW PROCESSLIST}.
@item
Added @code{auto-rehash} on reconnect for the @command{mysql} client.
@item
Fixed a newly introduced bug in @code{MyISAM}, where the index file couldn't
get bigger than 64MB.
@item
Added @code{SHOW MASTER STATUS} and @code{SHOW SLAVE STATUS}.
@end itemize


@node News-3.23.21, News-3.23.20, News-3.23.22, News-3.23.x
@appendixsubsec Changes in release 3.23.21 (04 Jul 2000)

@itemize @bullet
@item
Added @code{mysql_character_set_name()} function to the
MySQL C API.
@item
Made the update log ASCII 0 safe.
@item
Added the @command{mysql_config} script.
@item
Fixed problem when using @code{<} or @code{>} with a char column that was only
partly indexed.
@item
One would get a core dump if the log file was not readable by the MySQL user.
@item
Changed @command{mysqladmin} to use @code{CREATE DATABASE} and @code{DROP
DATABASE} statements instead of the old deprecated API calls.
@item
Fixed @code{chown} warning in @command{safe_mysqld}.
@item
Fixed a bug in @code{ORDER BY} that was introduced in 3.23.19.
@item
Only optimize the @code{DELETE FROM @var{tbl_name}} to do a drop+create of
the table if we are in @code{AUTOCOMMIT} mode (needed for @code{BDB} tables).
@item
Added extra checks to avoid index corruption when the @code{ISAM}/@code{MyISAM}
index files get full during an @code{INSERT}/@code{UPDATE}.
@item
@command{myisamchk} didn't correctly update row checksum when used with
@code{-ro} (this only gave a warning in subsequent runs).
@item
Fixed bug in @code{REPAIR TABLE} so that it works with tables without indexes.
@item
Fixed buffer overrun in @code{DROP DATABASE}.
@item
@code{LOAD TABLE FROM MASTER} is sufficiently bug-free to announce it as
a feature.
@item
@code{MATCH} and @code{AGAINST} are now reserved words.
@end itemize


@node News-3.23.20, News-3.23.19, News-3.23.21, News-3.23.x
@appendixsubsec Changes in release 3.23.20 (28 Jun 2000: Beta)

@itemize @bullet
@item
Fixed bug in 3.23.19; @code{DELETE FROM @var{tbl_name}} removed the @file{.frm} file.
@item
Added @code{SHOW CREATE TABLE}.
@end itemize


@node News-3.23.19, News-3.23.18, News-3.23.20, News-3.23.x
@appendixsubsec Changes in release 3.23.19

@itemize @bullet
@item
Changed copyright for all files to GPL for the server code and utilities and
to LGPL for the client libraries.
See @uref{http://www.fsf.org/licenses/}.
@item
Fixed bug where all rows matching weren't updated on a @code{MyISAM} table
when doing update based on key on a table with many keys and some key changed
values.
@item
The Linux MySQL RPMs and binaries are now statically linked with
a linuxthread version that has faster mutex handling when used with
MySQL.
@item
@code{ORDER BY} can now use @code{REF} keys to find subsets of the rows
that need to be sorted.
@item
Changed name of @command{print_defaults} program to @command{my_print_defaults}
to avoid name confusion.
@item
Fixed @code{NULLIF()} to work as required by standard SQL.
@item
Added @code{net_read_timeout} and @code{net_write_timeout} as startup
parameters to @command{mysqld}.
@item
Fixed bug that destroyed index when doing @command{myisamchk --sort-records}
on a table with prefix compressed index.
@item
Added @command{pack_isam} and @command{myisampack} to the standard MySQL
distribution.
@item
Added the syntax @code{BEGIN WORK} (the same as @code{BEGIN}).
@item
Fixed core dump bug when using @code{ORDER BY} on a @code{CONV()} expression.
@item
Added @code{LOAD TABLE FROM MASTER}.
@item
Added @code{FLUSH MASTER} and @code{FLUSH SLAVE}.
@item
Fixed big/little endian problem in the replication.
@end itemize


@node News-3.23.18, News-3.23.17, News-3.23.19, News-3.23.x
@appendixsubsec Changes in release 3.23.18 (11 Jun 2000)

@itemize @bullet
@item
Fixed a problem from 3.23.17 when choosing character set on the client side.
@item
Added @code{FLUSH TABLES WITH READ LOCK} to make a global lock suitable for
making a copy of MySQL data files.
@item
@code{CREATE TABLE ... SELECT ... PROCEDURE} now works.
@item
Internal temporary tables will now use compressed index when using
@code{GROUP BY} on @code{VARCHAR/CHAR} columns.
@item
Fixed a problem when locking the same table with both a @code{READ} and a
@code{WRITE} lock.
@item
Fixed problem with @command{myisamchk} and @code{RAID} tables.
@end itemize


@node News-3.23.17, News-3.23.16, News-3.23.18, News-3.23.x
@appendixsubsec Changes in release 3.23.17 (07 Jun 2000)

@itemize @bullet
@item
Fixed a bug in @code{FIND_IN_SET()} when the first argument was @code{NULL}.
@item
Added table locks to Berkeley DB.
@item
Fixed a bug with @code{LEFT JOIN} and @code{ORDER BY} where the first
table had only one matching row.
@item
Added 4 sample @file{my.cnf} example files in the @file{support-files}
directory.
@item
Fixed @code{duplicated key} problem when doing big @code{GROUP BY} operations.
(This bug was probably introduced in 3.23.15.)
@item
Changed syntax for @code{INNER JOIN} to match standard SQL.
@item
Added @code{NATURAL JOIN} syntax.
@item
A lot of fixes in the @code{BDB} interface.
@item
Added handling of @code{--no-defaults} and @code{--defaults-file} to
@command{safe_mysqld.sh} and @command{mysql_install_db.sh}.
@item
Fixed bug in reading compressed tables with many threads.
@item
Fixed that @code{USE INDEX} works with @code{PRIMARY} keys.
@item
Added @code{BEGIN} statement to start a transaction in @code{AUTOCOMMIT} mode.
@item
Added support for symbolic links for Windows.
@item
Changed protocol to let client know if the server is in @code{AUTOCOMMIT} mode
and if there is a pending transaction.  If there is a pending transaction,
the client library will give an error before reconnecting to the server to
let the client know that the server did a rollback.
The protocol is still backward-compatible with old clients.
@item
@code{KILL} now works on a thread that is locked on a 'write' to a dead client.
@item
Fixed memory leak in the replication slave thread.
@item
Added new @code{log-slave-updates} option to @command{mysqld}, to allow
daisy-chaining the slaves.
@item
Fixed compile error on FreeBSD and other systems where @code{pthread_t}
is not the same as @code{int}.
@item
Fixed master shutdown aborting the slave thread.
@item
Fixed a race condition in @code{INSERT DELAYED} code when doing
@code{ALTER TABLE}.
@item
Added deadlock detection sanity checks to @code{INSERT DELAYED}.
@end itemize


@node News-3.23.16, News-3.23.15, News-3.23.17, News-3.23.x
@appendixsubsec Changes in release 3.23.16 (16 May 2000)

@itemize @bullet
@item
Added @code{SLAVE START} and @code{SLAVE STOP} statements.
@item
Added @code{TYPE=QUICK} option to @code{CHECK TABLE} and to @code{REPAIR TABLE}.
@item
Fixed bug in @code{REPAIR TABLE} when the table was in use by other threads.
@item
Added a thread cache to make it possible to debug MySQL with
@command{gdb} when one does a lot of reconnects. This will also improve
systems where you can't use persistent connections.
@item
Lots of fixes in the Berkeley DB interface.
@item
@code{UPDATE IGNORE} will not abort if an update results in a
@code{DUPLICATE_KEY} error.
@item
Put @code{CREATE TEMPORARY TABLE} commands in the update log.
@item
Fixed bug in handling of masked IP numbers in the privilege tables.
@item
Fixed bug with @code{delay_key_write} tables and @code{CHECK TABLE}.
@item
Added @code{--replicate-do-db} and @code{--replicate-ignore-db} options to
@command{mysqld}, to restrict which databases get replicated.
@item
Added @code{SQL_LOG_BIN} option.
@end itemize


@node News-3.23.15, News-3.23.14, News-3.23.16, News-3.23.x
@appendixsubsec Changes in release 3.23.15 (08 May 2000)

@itemize @bullet
@item
To start @command{mysqld} as @code{root}, you must now use the @code{--user=root} option.
@item
Added interface to Berkeley DB. (This is not yet functional; play with it at
your own risk!)
@item
Replication between master and slaves.
@item
Fixed bug that other threads could steal a lock when a thread had
a lock on a table and did a @code{FLUSH TABLES} command.
@item
Added the @code{slow_launch_time} variable and the @code{Slow_launch_threads}
status variable to @command{mysqld}.  These can be examined with
@command{mysqladmin variables} and @command{mysqladmin extended-status}.
@item
Added functions @code{INET_NTOA()} and @code{INET_ATON()}.
@item
The default type of @code{IF()} now depends on the second and
third arguments and not only on the second argument.
@item
Fixed case when @command{myisamchk} could go into a loop when trying to
repair a crashed table.
@item
Don't write @code{INSERT DELAYED} to update log if @code{SQL_LOG_UPDATE=0}.
@item
Fixed problem with @code{REPLACE} on @code{HEAP} tables.
@item
Added possible character sets and time zone to @code{SHOW VARIABLES} output.
@item
Fixed bug in locking code that could result in locking problems with
concurrent inserts under high load.
@item
Fixed a problem with @code{DELETE} of many rows on a table with
compressed keys where MySQL scanned the index to find the rows.
@item
Fixed problem with @code{CHECK TABLE} on table with deleted keyblocks.
@item
Fixed a bug in reconnect (at the client side) where it didn't free memory
properly in some contexts.
@item
Fixed problems in update log when using @code{LAST_INSERT_ID()} to update
a table with an @code{AUTO_INCREMENT} key.
@item
Added @code{NULLIF()} function.
@item
Fixed bug when using @code{LOAD DATA INFILE} on a table with
@code{BLOB/TEXT} columns.
@item
Optimized @code{MyISAM} to be faster when inserting keys in sorted order.
@item
@code{EXPLAIN SELECT ...} now also prints out whether MySQL needs to
create a temporary table or use file sorting when resolving the @code{SELECT}.
@item
Added optimization to skip @code{ORDER BY} parts where the part is a
constant expression in the @code{WHERE} part.  Indexes can now be used
even if the @code{ORDER BY} doesn't match the index exactly, as long as
all the unused index parts and all the extra @code{ORDER BY}
columns are constants in the @code{WHERE} clause.  @xref{MySQL indexes}.
@item
@code{UPDATE} and @code{DELETE} on a whole unique key in the @code{WHERE} part
are now faster than before.
@item
Changed @code{RAID_CHUNKSIZE} to be in 1024-byte increments.
@item
Fixed core dump in @code{LOAD_FILE(NULL)}.
@end itemize


@node News-3.23.14, News-3.23.13, News-3.23.15, News-3.23.x
@appendixsubsec Changes in release 3.23.14 (09 Apr 2000)

@itemize @bullet
@item
Added @command{mysqlbinlog} program for displaying binary log files in text
format.
@item
Added @code{mysql_real_escape_string()} function to the MySQL C API.
@item
Fixed a bug in @code{CONCAT()} where one of the arguments was a function
that returned a modified argument.
@item
Fixed a critical bug in @command{myisamchk}, where it updated the header in
the index file when one only checked the table.  This confused the
@command{mysqld} daemon if it updated the same table at the same time. Now
the status in the index file is only updated if one uses
@code{--update-state}.  With older @command{myisamchk} versions you should
use @code{--read-only} when only checking tables, if there is the
slightest chance that the @command{mysqld} server is working on the table at the
same time!
@item
Fixed that @code{DROP TABLE} is logged in the update log.
@item
Fixed problem when searching on @code{DECIMAL()} key field
where the column data contained leading zeros.
@item
Fix bug in @command{myisamchk} when the @code{AUTO_INCREMENT} column isn't
the first key.
@item
Allow @code{DATETIME} in ISO8601 format: 2000-03-12T12:00:00
@item
Dynamic character sets.  A @command{mysqld} binary can now handle many different
character sets (you can choose which when starting @command{mysqld}).
@item
Added @code{REPAIR TABLE} statement.
@item
Added @code{mysql_thread_safe()} function to the MySQL C API.
@item
Added the @code{UMASK_DIR} environment variable.
@item
Added @code{CONNECTION_ID()} function to return the client connection thread
ID.
@item
When using @code{=} on @code{BLOB} or @code{VARCHAR BINARY} keys, where
only a part of the column was indexed, the whole column of the result
row wasn't compared.
@item
Fix for @code{sjis} character set and @code{ORDER BY}.
@item
When running in ANSI mode, don't allow columns to be used that aren't in
the @code{GROUP BY} part.
@end itemize


@node News-3.23.13, News-3.23.12, News-3.23.14, News-3.23.x
@appendixsubsec Changes in release 3.23.13 (14 Mar 2000)

@itemize @bullet
@item
Fixed problem when doing locks on the same table more than 2 times in
the same @code{LOCK TABLE} command; this fixed the problem one got when running
the test-ATIS test with @code{--fast} or @code{--check-only-changed}.
@item
Added @code{SQL_BUFFER_RESULT} option to @code{SELECT}.
@item
Removed endspace from double/float numbers in results from temporary
tables.
@item
Added @code{CHECK TABLE} command.
@item
Added changes for @code{MyISAM} in 3.23.12 that didn't get into the source
distribution because of CVS problems.
@item
Fixed bug so that @command{mysqladmin shutdown} will wait for the local server
to close down.
@item
Fixed a possible endless loop when calculating timestamp.
@item
Added @command{print_defaults} program to the @file{.rpm} files. Removed
@command{mysqlbug} from the client @file{.rpm} file.
@end itemize


@node News-3.23.12, News-3.23.11, News-3.23.13, News-3.23.x
@appendixsubsec Changes in release 3.23.12 (07 Mar 2000)

@itemize @bullet
@item
Fixed bug in @code{MyISAM} involving @code{REPLACE ... SELECT ...} which could
give a corrupted table.
@item
Fixed bug in @command{myisamchk} where it incorrectly reset the
@code{AUTO_INCREMENT} value.
@item
LOTS of patches for Linux Alpha. MySQL now appears to be relatively
stable on Alpha.
@item
Changed @code{DISTINCT} on @code{HEAP} temporary tables to use hashed
keys to quickly find duplicated rows. This mostly concerns queries of
type @code{SELECT DISTINCT ... GROUP BY ...}.  This fixes a problem where
not all duplicates were removed in queries of the above type.  In
addition, the new code is MUCH faster.
@item
Added patches to make MySQL compile on Mac OS X.
@item
Added @code{IF NOT EXISTS} clause to @code{CREATE DATABASE}.
@item
Added @code{--all-databases} and @code{--databases} options to @command{mysqldump}
to allow dumping of many databases at the same time.
@item
Fixed bug in compressed @code{DECIMAL()} index in @code{MyISAM} tables.
@item
Fixed bug when storing 0 into a timestamp.
@item
When doing @command{mysqladmin shutdown} on a local connection, @command{mysqladmin}
now waits until the PID file is gone before terminating.
@item
Fixed core dump with some @code{COUNT(DISTINCT ...)} queries.
@item
Fixed that @command{myisamchk} works properly with RAID tables.
@item
Fixed problem with @code{LEFT JOIN} and @code{@var{key_col} IS NULL}.
@item
Fixed bug in @code{net_clear()} which could give the error @code{Aborted
connection} in the MySQL clients.
@item
Added options @code{USE INDEX (@var{key_list})} and @code{IGNORE INDEX (@var{key_list})} as
parameters in @code{SELECT}.
@item
@code{DELETE} and @code{RENAME} should now work on @code{RAID} tables.
@end itemize


@node News-3.23.11, News-3.23.10, News-3.23.12, News-3.23.x
@appendixsubsec Changes in release 3.23.11 (16 Feb 2000)

@itemize @bullet
@item
Added @code{HIGH_PRIORITY} option to @code{INSERT}. This overrides the
effect of the @code{--low-priority-updates} server option and will not
perform concurrent inserts.
@item
Allow the @code{ALTER TABLE @var{tbl_name} ADD (field_list)} syntax.
@item
Fixed problem with optimizer that could sometimes use incorrect keys.
@item
Fixed that @code{GRANT/REVOKE ALL PRIVILEGES} doesn't affect
@code{GRANT OPTION}.
@item
Removed extra @samp{)} from the output of @code{SHOW GRANTS}.
@item
Fixed problem when storing numbers in timestamps.
@item
Fix problem with time zones that have half hour offsets.
@item
Allow the syntax @code{UNIQUE INDEX} in @code{CREATE} statements.
@item
@command{mysqlhotcopy} - fast online hot-backup utility for local
MySQL databases. By Tim Bunce.
@item
New more secure @command{mysqlaccess}. Thanks to Steve Harvey for this.
@item
Added @code{--i-am-a-dummy} and @code{--safe-updates} options to @command{mysql}.
@item
Added @code{select_limit} and @code{max_join_size} variables to @command{mysql}.
@item
Added @code{SQL_MAX_JOIN_SIZE} and @code{SQL_SAFE_UPDATES} options.
@item
Added @code{READ LOCAL} lock that doesn't lock the table for concurrent
inserts. (This is used by @command{mysqldump}.)
@item
Changed that @code{LOCK TABLES ... READ} no longer allows concurrent
inserts.
@item
Added @code{--skip-delay-key-write} option to @command{mysqld}.
@item
Fixed security problem in the protocol regarding password checking.
@item
@code{_rowid} can now be used as an alias for an integer type unique indexed
column.
@item
Added back blocking of @code{SIGPIPE} when compiling with @code{--thread-safe-clients}
to make things safe for old clients.
@end itemize


@node News-3.23.10, News-3.23.9, News-3.23.11, News-3.23.x
@appendixsubsec Changes in release 3.23.10 (30 Jan 2000)

@itemize @bullet
@item
Fixed bug in 3.23.9 where memory wasn't properly freed when using
@code{LOCK TABLES}.
@end itemize


@node News-3.23.9, News-3.23.8, News-3.23.10, News-3.23.x
@appendixsubsec Changes in release 3.23.9 (29 Jan 2000)

@itemize @bullet
@item
Fixed problem that affected queries that did arithmetic on group functions.
@item
Fixed problem with timestamps and @code{INSERT DELAYED}.
@item
Fixed that @code{date_col BETWEEN const_date AND const_date} works.
@item
Fixed problem when only changing a 0 to @code{NULL} in a table with
@code{BLOB/TEXT} columns.
@item
Fixed bug in range optimizer when using many key parts and or on the middle
key parts:  @code{WHERE K1=1 and K3=2 and (K2=2 and K4=4 or K2=3 and K4=5)}
@item
Added @code{source} command to @command{mysql} to allow reading of batch files
inside the @command{mysql} client.  Original patch by Matthew Vanecek.
@item
Fixed critical problem with the @code{WITH GRANT OPTION} option.
@item
Don't give an unnecessary @code{GRANT} error when using tables from many
databases in the same query.
@item
Added VIO wrapper (needed for SSL support; by Andrei Errapart and
T@~onu Samuel).
@item
Fixed optimizer problem on @code{SELECT} when using many overlapping indexes.
MySQL should now be able to choose keys even better when there
are many keys to choose from.
@item
Changed optimizer to prefer a range key instead of a ref key when the
range key can uses more columns than the ref key (which only can use
columns with @code{=}).  For example, the following type of queries should now
be faster: @code{SELECT * from key_part_1=const and key_part_2 > const2}
@item
Fixed bug that a change of all @code{VARCHAR} columns to @code{CHAR} columns
didn't change row type from dynamic to fixed.
@item
Disabled floating-point exceptions for FreeBSD to fix core dump when
doing @code{SELECT FLOOR(POW(2,63))}.
@item
Renamed @command{mysqld} startup option from @code{--delay-key-write} to
@code{--delay-key-write-for-all-tables}.
@item
Added @code{read-next-on-key} to @code{HEAP} tables.  This should fix all
problems with @code{HEAP} tables when using non-@code{UNIQUE} keys.
@item
Added option to print default arguments to all clients.
@item
Added @code{--log-slow-queries} option to @command{mysqld} to log all queries
that take a long time to a separate log file with a time indicating how
long the query took.
@item
Fixed core dump when doing @code{WHERE @var{key_col}=RAND(...)}.
@item
Fixed optimization bug in @code{SELECT ... LEFT JOIN ... @var{key_col} IS NULL},
when @var{key_col} could contain @code{NULL} values.
@item
Fixed problem with 8-bit characters as separators in @code{LOAD DATA INFILE}.
@end itemize


@node News-3.23.8, News-3.23.7, News-3.23.9, News-3.23.x
@appendixsubsec Changes in release 3.23.8 (02 Jan 2000)

@itemize @bullet
@item
Fixed problem when handling indexfiles larger than 8GB.
@item
Added latest patches to MIT-pthreads for NetBSD.
@item
Fixed problem with time zones that are < GMT - 11.
@item
Fixed a bug when deleting packed keys in @code{NISAM}.
@item
Fixed problem with @code{ISAM} when doing some @code{ORDER BY ... DESC} queries.
@item
Fixed bug when doing a join on a text key which didn't cover the whole key.
@item
Option @code{--delay-key-write} didn't enable delayed key writing.
@item
Fixed update of @code{TEXT} column which involved only case changes.
@item
Fixed that @code{INSERT DELAYED} doesn't update timestamps that are given.
@item
Added function @code{YEARWEEK()} and options @code{x}, @code{X}, @code{v} and
@code{V} to @code{DATE_FORMAT()}.
@item
Fixed problem with @code{MAX(indexed_column)} and @code{HEAP} tables.
@item
Fixed problem with @code{BLOB NULL} keys and @code{LIKE "prefix%"}.
@item
Fixed problem with @code{MyISAM} and fixed-length rows < 5 bytes.
@item
Fixed problem that could cause MySQL to touch freed memory when
doing very complicated @code{GROUP BY} queries.
@item
Fixed core dump if you got a crashed table where an @code{ENUM} field value
was too big.
@end itemize


@node News-3.23.7, News-3.23.6, News-3.23.8, News-3.23.x
@appendixsubsec Changes in release 3.23.7 (10 Dec 1999)

@itemize @bullet
@item
Fixed workaround under Linux to avoid problems with
@code{pthread_mutex_timedwait()},
which is used with @code{INSERT DELAYED}. @xref{Linux}.
@item
Fixed that one will get a 'disk full' error message if one gets disk full
when doing sorting (instead of waiting until we got more disk space).
@item
Fixed a bug in @code{MyISAM} with keys > 250 characters.
@item
In @code{MyISAM} one can now do an @code{INSERT} at the same time as other
threads are reading from the table.
@item
Added @code{max_write_lock_count} variable to @command{mysqld} to force a
@code{READ} lock after a certain number of @code{WRITE} locks.
@item
Inverted flag @code{delay_key_write} on @code{show variables}.
@item
Renamed @code{concurrency} variable to @code{thread_concurrency}.
@item
@c TODO: delete arguments from these functions, just list in name() form?
The following functions are now multi-byte-safe:
@code{LOCATE(@var{substr},@var{str})}, @code{POSITION(@var{substr} IN @var{str})},
@code{LOCATE(@var{substr},@var{str},@var{pos})}, @code{INSTR(@var{str},@var{substr})},
@code{LEFT(@var{str},@var{len})}, @code{RIGHT(@var{str},@var{len})},
@code{SUBSTRING(@var{str},@var{pos},@var{len})}, @code{SUBSTRING(@var{str} FROM @var{pos} FOR @var{len})},
@code{MID(@var{str},@var{pos},@var{len})}, @code{SUBSTRING(@var{str},@var{pos})}, @code{SUBSTRING(@var{str}
FROM @var{pos})}, @code{SUBSTRING_INDEX(@var{str},@var{delim},@var{count})}, @code{RTRIM(@var{str})},
@code{TRIM([[BOTH | TRAILING] [@var{remstr}] FROM] @var{str})},
@code{REPLACE(@var{str},@var{from_str},@var{to_str})}, @code{REVERSE(@var{str})},
@code{INSERT(@var{str},@var{pos},@var{len},@var{newstr})}, @code{LCASE(@var{str})}, @code{LOWER(@var{str})},
@code{UCASE(@var{str})} and @code{UPPER(@var{str})}; patch by Wei He.
@item
Fix core dump when releasing a lock from a non-existent table.
@item
Remove locks on tables before starting to remove duplicates.
@item
Added option @code{FULL} to @code{SHOW PROCESSLIST}.
@item
Added option @code{--verbose} to @command{mysqladmin}.
@item
Fixed problem when automatically converting @code{HEAP} to @code{MyISAM}.
@item
Fixed bug in @code{HEAP} tables when doing insert + delete + insert + scan the
table.
@item
Fixed bugs on Alpha with @code{REPLACE()} and @code{LOAD DATA INFILE}.
@item
Added @code{interactive_timeout} variable to @command{mysqld}.
@item
Changed the argument to @code{mysql_data_seek()} from @code{ulong} to
@code{ulonglong}.
@end itemize


@node News-3.23.6, News-3.23.5, News-3.23.7, News-3.23.x
@appendixsubsec Changes in release 3.23.6 (15 Nov 1999)

@itemize @bullet
@item
Added @code{-O lower_case_table_names=@{0|1@}} option to @command{mysqld} to allow
users to force table names to lowercase.
@item
Added @code{SELECT ... INTO DUMPFILE}.
@item
Added @code{--ansi} option to @command{mysqld} to make some functions
standard SQL compatible.
@item
Temporary table names now start with @code{#sql}.
@item
Added quoting of identifiers with @code{`} (@code{"} in @code{--ansi} mode).
@item
Changed to use @code{snprintf()} when printing floats to avoid some buffer
overflows on FreeBSD.
@item
Made @code{FLOOR()} overflow safe on FreeBSD.
@item
Added @code{--quote-names} option to @command{mysqldump}.
@item
Fixed bug that one could make a part of a @code{PRIMARY KEY NOT NULL}.
@item
Fixed @code{encrypt()} to be thread-safe and not reuse buffer.
@item
Added @code{mysql_odbc_escape_string()} function to support big5 characters in
MyODBC.
@item
Rewrote the storage engine to use classes.  This introduces a lot of new code,
but will make table handling faster and better.
@item
Added patch by Sasha for user-defined variables.
@item
Changed that @code{FLOAT} and @code{DOUBLE} (without any length modifiers)
no longer are fixed decimal point numbers.
@item
Changed the meaning of @code{FLOAT(@var{X})}: Now this is the same as @code{FLOAT} if
@var{X} <= 24 and a @code{DOUBLE} if 24 < @var{X} <= 53.
@item
@code{DECIMAL(@var{X})} is now an alias for @code{DECIMAL(@var{X},0)} and @code{DECIMAL}
is now an alias for @code{DECIMAL(10,0)}.  The same goes for @code{NUMERIC}.
@item
Added option @code{ROW_FORMAT=@{DEFAULT | DYNAMIC | FIXED | COMPRESSED@}} to
@code{CREATE_TABLE}.
@item
@code{DELETE FROM @var{tbl_name}} didn't work on temporary tables.
@item
Changed function @code{CHAR_LENGTH()} to be multi-byte character safe.
@item
Added function @code{ORD(string)}.
@end itemize


@node News-3.23.5, News-3.23.4, News-3.23.6, News-3.23.x
@appendixsubsec Changes in release 3.23.5 (20 Oct 1999)

@itemize @bullet
@item
Fixed some Y2K problems in the new date handling in 3.23.
@item
Fixed problem with @code{SELECT DISTINCT ... ORDER BY RAND()}.
@item
Added patches by Sergei A. Golubchik for text searching on the @code{MyISAM}
level.
@item
Fixed cache overflow problem when using full joins without keys.
@item
Fixed some configure issues.
@item
Some small changes to make parsing faster.
@item
Adding a column after the last field with @code{ALTER TABLE} didn't work.
@item
Fixed problem when using an @code{AUTO_INCREMENT} column in two keys
@item
With @code{MyISAM}, you now can have an @code{AUTO_INCREMENT} column as a key
sub part:
@code{CREATE TABLE foo (a INT NOT NULL AUTO_INCREMENT, b CHAR(5), PRIMARY KEY (b,a))}
@item
Fixed bug in @code{MyISAM} with packed char keys that could be @code{NULL}.
@item
@code{AS} on field name with @code{CREATE TABLE @var{tbl_name} SELECT ...} didn't
work.
@item
Allow use of @code{NATIONAL} and @code{NCHAR} when defining character columns.
This is the same as not using @code{BINARY}.
@item
Don't allow @code{NULL} columns in a @code{PRIMARY KEY} (only in @code{UNIQUE}
keys).
@item
Clear @code{LAST_INSERT_ID()} if one uses this in ODBC:
@code{WHERE auto_increment_column IS NULL}.  This seems to fix some problems
with Access.
@item
@code{SET SQL_AUTO_IS_NULL=0|1} now turns on/off the handling of
searching for the last inserted row with @code{WHERE
auto_increment_column IS NULL}.
@item
Added new variable @code{concurrency} to @command{mysqld} for Solaris.
@item
Added @code{--relative} option to @command{mysqladmin} to make
@code{extended-status} more useful to monitor changes.
@item
Fixed bug when using @code{COUNT(DISTINCT ...)} on an empty table.
@item
Added support for the Chinese character set GBK.
@item
Fixed problem with @code{LOAD DATA INFILE} and @code{BLOB} columns.
@item
Added bit operator @code{~} (negation).
@item
Fixed problem with UDF functions.
@end itemize


@node News-3.23.4, News-3.23.3, News-3.23.5, News-3.23.x
@appendixsubsec Changes in release 3.23.4 (28 Sep 1999)

@itemize @bullet
@item
Inserting a @code{DATETIME} into a @code{TIME} column no longer will
try to store 'days' in it.
@item
Fixed problem with storage of float/double on little endian machines.
(This affected @code{SUM()}.)
@item
Added connect timeout on TCP/IP connections.
@item
Fixed problem with @code{LIKE "%"} on an index that may have @code{NULL} values.
@item
@code{REVOKE ALL PRIVILEGES} didn't revoke all privileges.
@item
Allow creation of temporary tables with same name as the original table.
@item
When granting an account a @code{GRANT} option for a database, the account
couldn't grant privileges to other users.
@item
New statement: @code{SHOW GRANTS FOR user} (by Sinisa).
@item
New @code{date_add} syntax:  @code{date/datetime + INTERVAL # interval_type}.
By Joshua Chamas.
@item
Fixed privilege check for @code{LOAD DATA REPLACE}.
@item
Automatic fixing of broken include files on Solaris 2.7
@item
Some configure issues to fix problems with big filesystem detection.
@item
@code{REGEXP} is now case-insensitive if you use non-binary strings.
@end itemize


@node News-3.23.3, News-3.23.2, News-3.23.4, News-3.23.x
@appendixsubsec Changes in release 3.23.3 (13 Sep 1999)

@itemize @bullet
@item
Added patches for MIT-pthreads on NetBSD.
@item
Fixed range bug in @code{MyISAM}.
@item
@code{ASC} is now the default again for @code{ORDER BY}.
@item
Added @code{LIMIT} to @code{UPDATE}.
@item
Added @code{mysql_change_user()} function to the MySQL C API.
@item
Added character set to @code{SHOW VARIABLES}.
@item
Added support of @code{--[whitespace]} comments.
@item
Allow @code{INSERT INTO @var{tbl_name} VALUES ()}, that is, you may now specify
an empty value list to insert a row in which each column is set to its
default value.
@item
Changed @code{SUBSTRING(text FROM pos)} to conform to standard SQL. (Before this
construct returned the rightmost @code{pos} characters.)
@item
@code{SUM()} with @code{GROUP BY} returned 0 on some systems.
@item
Changed output for @code{SHOW TABLE STATUS}.
@item
Added @code{DELAY_KEY_WRITE} option to @code{CREATE TABLE}.
@item
Allow @code{AUTO_INCREMENT} on any key part.
@item
Fixed problem with @code{YEAR(NOW())} and @code{YEAR(CURDATE())}.
@item
Added @code{CASE} construct.
@item
New @code{COALESCE()} function.
@end itemize


@node News-3.23.2, News-3.23.1, News-3.23.3, News-3.23.x
@appendixsubsec Changes in release 3.23.2 (09 Aug 1999)

@itemize @bullet
@item
Fixed range optimizer bug: @code{SELECT * FROM @var{tbl_name} WHERE
@var{key_part1} >= @var{const} AND (@var{key_part2} = @var{const} OR @var{key_part2} = @var{const})}.  The
bug was that some rows could be duplicated in the result.
@item
Running @command{myisamchk} without @code{-a} updated the index
distribution incorrectly.
@item
@code{SET SQL_LOW_PRIORITY_UPDATES=1} was causing a parse error.
@item
You can now update index columns that are used in the @code{WHERE} clause.
@code{UPDATE @var{tbl_name} SET KEY=KEY+1 WHERE KEY > 100}
@item
Date handling should now be a bit faster.
@item
Added handling of fuzzy dates (dates where day or month is 0), such as
@code{'1999-01-00'}.
@item
Fixed optimization of @code{SELECT ... WHERE @var{key_part1}=@var{const1} AND
@var{key_part_2}=@var{const2} AND @var{key_part1}=@var{const4} AND
@var{key_part2}=@var{const4}}; indextype
should be @code{range} instead of @code{ref}.
@item
Fixed @command{egcs} 1.1.2 optimizer bug (when using @code{BLOB} values) on Linux Alpha.
@item
Fixed problem with @code{LOCK TABLES} combined with @code{DELETE FROM table}.
@item
@code{MyISAM} tables now allow keys on @code{NULL} and @code{BLOB/TEXT} columns.
@item
The following join is now much faster:
@code{SELECT ... FROM t1 LEFT JOIN t2 ON ... WHERE t2.@var{not_null_column} IS NULL}.
@item
@code{ORDER BY} and @code{GROUP BY} can be done on functions.
@item
Changed handling of 'const_item' to allow handling of @code{ORDER BY RAND()}.
@item
Indexes are now used for @code{WHERE @var{key_column} = @var{function}}.
@item
Indexes are now used for @code{WHERE @var{key_column} = @var{col_name}} even if
the columns are not identically packed.
@item
Indexes are now used for @code{WHERE @var{col_name} IS NULL}.
@item
Changed heap tables to be stored in low_byte_first order (to make it easy
to convert to @code{MyISAM} tables)
@item
Automatic change of @code{HEAP} temporary tables to @code{MyISAM} tables
in case of ``table is full'' errors.
@item
Added @code{--init-file=@var{file_name}} option to @command{mysqld}.
@item
Added @code{COUNT(DISTINCT @var{value}, [@var{value}, ...])}.
@item
@code{CREATE TEMPORARY TABLE} now creates a temporary table, in its own
namespace, that is automatically deleted if connection is dropped.
@item
New reserved words (required for @code{CASE}):  @code{CASE, THEN, WHEN, ELSE and END}.
@item
New functions @code{EXPORT_SET()} and @code{MD5()}.
@item
Support for the GB2312 Chinese character set.
@end itemize


@node News-3.23.1, News-3.23.0, News-3.23.2, News-3.23.x
@appendixsubsec Changes in release 3.23.1 (08 Jul 1999)

@itemize @bullet
@item
Fixed some compilation problems.
@end itemize


@node News-3.23.0,  , News-3.23.1, News-3.23.x
@appendixsubsec Changes in release 3.23.0 (05 Jul 1999: Alpha)

@itemize @bullet
@item
A new storage engine library (@code{MyISAM}) with a lot of new features.
@xref{MyISAM storage engine, , @code{MyISAM} storage engine}.
@item
You can create in-memory @code{HEAP} tables which are extremely fast for
lookups.
@item
Support for big files (63-bit) on OSs that support big files.
@item
New function @code{LOAD_FILE(filename)} to get the contents of a file as a
string value.
@item
New @code{<=>} operator that acts as @code{=} but returns TRUE
if both arguments are @code{NULL}.  This is useful for comparing changes
between tables.
@item
Added the ODBC 3.0 @code{EXTRACT(interval FROM datetime)} function.
@item
Columns defined as @code{FLOAT(@var{X})} are not rounded on storage and may be
in scientific notation (1.0 E+10) when retrieved.
@item
@code{REPLACE} is now faster than before.
@item
Changed @code{LIKE} character comparison to behave as @code{=};
This means that @code{'e' LIKE '@'e'} is now true.  (If the line doesn't
display correctly, the latter 'e' is a French 'e' with an acute accent above.)
@item
@code{SHOW TABLE STATUS} returns a lot of information about the tables.
@item
Added @code{LIKE} to the @code{SHOW STATUS} command.
@item
Added @code{Privileges} column to @code{SHOW COLUMNS}.
@item
Added @code{Packed} and @code{Comment} columns to @code{SHOW INDEX}.
@item
Added comments to tables (with @code{CREATE TABLE ... COMMENT '@var{xxx}'}).
@item
Added @code{UNIQUE}, as in
@code{CREATE TABLE @var{tbl_name} (col INT NOT NULL UNIQUE)}
@item
New create syntax: @code{CREATE TABLE @var{tbl_name} SELECT ...}
@item
New create syntax: @code{CREATE TABLE IF NOT EXISTS ...}
@item
Allow creation of @code{CHAR(0)} columns.
@item
@code{DATE_FORMAT()} now requires @samp{%} before any format character.
@item
@code{DELAYED} is now a reserved word (sorry about that :( ).
@item
An example procedure is added: @code{analyse}, file: @file{sql_analyse.c}.
This will describe the data in your query.  Try the following:
@example
SELECT ... FROM ...
WHERE ... PROCEDURE ANALYSE([max elements,[max memory]])
@end example

This procedure is extremely useful when you want to check the data in your
table!
@item
@code{BINARY} cast to force a string to be compared in case-sensitive fashion.
@item
Added @code{--skip-show-database} option to @command{mysqld}.
@item
Check whether a row has changed in an @code{UPDATE} now also works
with @code{BLOB}/@code{TEXT} columns.
@item
Added the @code{INNER} join syntax.  @strong{Note}:  This made @code{INNER}
a reserved word!
@item
Added support for netmasks to the hostname in the MySQL grant tables.
You can specify a netmask using the @code{IP/NETMASK} syntax.
@item
If you compare a @code{NOT NULL DATE/DATETIME} column with @code{IS
NULL}, this is changed to a compare against @code{0} to satisfy some ODBC
applications.  (By @email{shreeve@@uci.edu}.)
@item
@code{NULL IN (...)} now returns @code{NULL} instead of @code{0}.  This will
ensure that @code{null_column NOT IN (...)} doesn't match
@code{NULL} values.
@item
Fix storage of floating-point values in @code{TIME} columns.
@item
Changed parsing of @code{TIME} strings to be more strict.  Now the
fractional second part is detected (and currently skipped). The
following formats are supported:
@itemize @bullet
@item [[DAYS] [H]H:]MM:]SS[.fraction]
@item [[[[[H]H]H]H]MM]SS[.fraction]
@end itemize
@item
Detect (and ignore) fractional second part from @code{DATETIME}.
@item
Added the @code{LOW_PRIORITY} attribute to @code{LOAD DATA INFILE}.
@item
The default index name now uses the same case as the column name on which the
index name is based.
@item
Changed default number of connections to 100.
@item
Use bigger buffers when using @code{LOAD DATA INFILE}.
@item
@code{DECIMAL(x,y)} now works according to standard SQL.
@item
Added aggregate UDF functions. Thanks to Andreas F. Bobak
(@email{bobak@@relog.ch}) for this!
@item
@code{LAST_INSERT_ID()} is now updated for @code{INSERT INTO ... SELECT}.
@item
Some small changes to the join table optimizer to make some joins faster.
@item
@code{SELECT DISTINCT} is much faster; it uses the new @code{UNIQUE}
functionality in @code{MyISAM}. One difference compared to MySQL 3.22
is that the output of @code{DISTINCT} is no longer sorted.
@item
All C client API macros are now functions to make shared libraries more
reliable. Because of this, you can no longer call @code{mysql_num_fields()} on
a @code{MYSQL} object, you must use @code{mysql_field_count()} instead.
@item
Added use of @code{LIBWRAP}; patch by Henning P. Schmiedehausen.
@item
Don't allow @code{AUTO_INCREMENT} for other than numerical columns.
@item
Using @code{AUTO_INCREMENT} will now automatically make the column
@code{NOT NULL}.
@item
Show @code{NULL} as the default value for @code{AUTO_INCREMENT} columns.
@item
Added @code{SQL_BIG_RESULT}; @code{SQL_SMALL_RESULT} is now default.
@item
Added a shared library RPM. This enhancement was contributed by David
Fox (@email{dsfox@@cogsci.ucsd.edu}).
@item
Added  @code{--enable-large-files} and @code{--disable-large-files} options
to @command{configure}. See @file{configure.in} for some systems where this is
automatically turned off because of broken implementations.
@item
Upgraded @code{readline} to 4.0.
@item
New @code{CREATE TABLE} options: @code{PACK_KEYS} and @code{CHECKSUM}.
@item
Added @code{--default-table-type} option to @command{mysqld}.
@end itemize


@node News-3.22.x, News-3.21.x, News-3.23.x, News
@appendixsec Changes in release 3.22.x (Old; discontinued)

@cindex changes, version 3.22

The 3.22 version has faster and safer connect code than version 3.21, as well
as a lot of new nice enhancements.
As there aren't really any major changes, upgrading from 3.21 to 3.22 should
be very easy and painless.  @xref{Upgrading-from-3.21}.

@menu
* News-3.22.35::                Changes in release 3.22.35
* News-3.22.34::                Changes in release 3.22.34
* News-3.22.33::                Changes in release 3.22.33
* News-3.22.32::                Changes in release 3.22.32 (14 Feb 2000)
* News-3.22.31::                Changes in release 3.22.31
* News-3.22.30::                Changes in release 3.22.30 (11 Jan 2000)
* News-3.22.29::                Changes in release 3.22.29 (02 Jan 2000)
* News-3.22.28::                Changes in release 3.22.28 (20 Oct 1999)
* News-3.22.27::                Changes in release 3.22.27 (05 Oct 1999)
* News-3.22.26::                Changes in release 3.22.26 (16 Sep 1999)
* News-3.22.25::                Changes in release 3.22.25 (07 Jun 1999)
* News-3.22.24::                Changes in release 3.22.24 (05 Jul 1999)
* News-3.22.23::                Changes in release 3.22.23 (08 Jun 1999)
* News-3.22.22::                Changes in release 3.22.22 (30 Apr 1999)
* News-3.22.21::                Changes in release 3.22.21 (04 Apr 1999)
* News-3.22.20::                Changes in release 3.22.20 (18 Mar 1999)
* News-3.22.19::                Changes in release 3.22.19 (01 Mar 1999)
* News-3.22.18::                Changes in release 3.22.18 (26 Feb 1999)
* News-3.22.17::                Changes in release 3.22.17 (22 Feb 1999: Production)
* News-3.22.16::                Changes in release 3.22.16 (05 Feb 1999)
* News-3.22.15::                Changes in release 3.22.15 (27 Jan 1999)
* News-3.22.14::                Changes in release 3.22.14 (01 Jan 1999: Gamma)
* News-3.22.13::                Changes in release 3.22.13 (16 Dec 1998)
* News-3.22.12::                Changes in release 3.22.12 (09 Dec 1998)
* News-3.22.11::                Changes in release 3.22.11 (24 Nov 1998)
* News-3.22.10::                Changes in release 3.22.10 (04 Nov 1998)
* News-3.22.9::                 Changes in release 3.22.9 (19 Oct 1998)
* News-3.22.8::                 Changes in release 3.22.8 (06 Oct 1998)
* News-3.22.7::                 Changes in release 3.22.7 (21 Sep 1998: Beta)
* News-3.22.6::                 Changes in release 3.22.6 (31 Aug 1998)
* News-3.22.5::                 Changes in release 3.22.5 (20 Aug 1998: Alpha)
* News-3.22.4::                 Changes in release 3.22.4 (06 Jul 1998: Beta)
* News-3.22.3::                 Changes in release 3.22.3 (30 Jun 1998)
* News-3.22.2::                 Changes in release 3.22.2
* News-3.22.1::                 Changes in release 3.22.1 (Jun 1998)
* News-3.22.0::                 Changes in release 3.22.0 (18 May 1998: Alpha)
@end menu


@node News-3.22.35, News-3.22.34, News-3.22.x, News-3.22.x
@appendixsubsec Changes in release 3.22.35

@itemize @bullet
@item
Fixed problem with @code{STD()}.
@item
Merged changes from the newest @code{ISAM} library from 3.23.
@item
Fixed problem with @code{INSERT DELAYED}.
@item
Fixed a bug core dump when using a @code{LEFT JOIN}/@code{STRAIGHT_JOIN}
on a table with only one row.
@end itemize


@node News-3.22.34, News-3.22.33, News-3.22.35, News-3.22.x
@appendixsubsec Changes in release 3.22.34

@itemize @bullet
@item
Fixed problem with @code{GROUP BY} on @code{TINYBLOB} columns; this
caused bugzilla to not show rows in some queries.
@item
Had to do total recompile of the Windows binary version as VC++ didn't
compile all relevant files for 3.22.33 :(
@end itemize


@node News-3.22.33, News-3.22.32, News-3.22.34, News-3.22.x
@appendixsubsec Changes in release 3.22.33

@itemize @bullet
@item
Fixed problems in Windows when locking tables with @code{LOCK TABLE}.
@item
Quicker kill of @code{SELECT DISTINCT} queries.
@end itemize


@node News-3.22.32, News-3.22.31, News-3.22.33, News-3.22.x
@appendixsubsec Changes in release 3.22.32 (14 Feb 2000)

@itemize @bullet
@item
Fixed problem when storing numbers in timestamps.
@item
Fix problem with time zones that have half hour offsets.
@item
Added @command{mysqlhotcopy}, a fast online hot-backup utility for local MySQL
databases. By Tim Bunce.
@item
New more secure @command{mysqlaccess}. Thanks to Steve Harvey for this.
@item
Fixed security problem in the protocol regarding password checking.
@item
Fixed problem that affected queries that did arithmetic on @code{GROUP} functions.
@item
Fixed a bug in the @code{ISAM} code when deleting rows on tables with
packed indexes.
@end itemize


@node News-3.22.31, News-3.22.30, News-3.22.32, News-3.22.x
@appendixsubsec Changes in release 3.22.31

@itemize @bullet
@item
A few small fixes for the Windows version.
@end itemize


@node News-3.22.30, News-3.22.29, News-3.22.31, News-3.22.x
@appendixsubsec Changes in release 3.22.30 (11 Jan 2000)

@itemize @bullet
@item
Fixed optimizer problem on @code{SELECT} when using many overlapping indexes.
@item
Disabled floating-point exceptions for FreeBSD to fix core dump when
doing @code{SELECT FLOOR(POW(2,63))}.
@item
Added print of default arguments options to all clients.
@item
Fixed critical problem with the @code{WITH GRANT OPTION} option.
@item
Fixed non-critical Y2K problem when writing short date to log files.
@end itemize


@node News-3.22.29, News-3.22.28, News-3.22.30, News-3.22.x
@appendixsubsec Changes in release 3.22.29 (02 Jan 2000)

@itemize @bullet
@item
Upgraded the configure and include files to match the latest 3.23 version.
This should increase portability and make it easier to build shared libraries.
@item
Added latest patches to MIT-pthreads for NetBSD.
@item
Fixed problem with time zones that are < GMT -11.
@item
Fixed a bug when deleting packed keys in NISAM.
@item
Fixed problem that could cause MySQL to touch freed memory when
doing very complicated @code{GROUP BY} queries.
@item
Fixed core dump if you got a crashed table where an @code{ENUM} field value
was too big.
@item
Added @code{mysqlshutdown.exe} and @code{mysqlwatch.exe} to the Windows
distribution.
@item
Fixed problem when doing @code{ORDER BY} on a reference key.
@item
Fixed that @code{INSERT DELAYED} doesn't update timestamps that are given.
@end itemize


@node News-3.22.28, News-3.22.27, News-3.22.29, News-3.22.x
@appendixsubsec Changes in release 3.22.28 (20 Oct 1999)

@itemize @bullet
@item
Fixed problem with @code{LEFT JOIN} and @code{COUNT()} on a column which
was declared @code{NULL} + and it had a @code{DEFAULT} value.
@item
Fixed core dump problem when using @code{CONCAT()} in a @code{WHERE} clause.
@item
Fixed problem with @code{AVG()} and @code{STD()} with @code{NULL} values.
@end itemize


@node News-3.22.27, News-3.22.26, News-3.22.28, News-3.22.x
@appendixsubsec Changes in release 3.22.27 (05 Oct 1999)

@itemize @bullet
@item
Fixed prototype in @file{my_ctype.h} when using other character sets.
@item
Some configure issues to fix problems with big filesystem detection.
@item
Fixed problem when sorting on big @code{BLOB} columns.
@item
@code{ROUND()} will now work on Windows.
@end itemize


@node News-3.22.26, News-3.22.25, News-3.22.27, News-3.22.x
@appendixsubsec Changes in release 3.22.26 (16 Sep 1999)

@itemize @bullet
@item
Fixed core dump with empty @code{BLOB/TEXT} column argument to
@code{REVERSE()}.
@item
Extended @code{/*! */} with version numbers.
@item
Changed @code{SUBSTRING(text FROM pos)} to conform to standard SQL. (Before this
construct returned the rightmost 'pos' characters.)
@item
Fixed problem with @code{LOCK TABLES} combined with @code{DELETE FROM table}
@item
Fixed problem that @code{INSERT ... SELECT} didn't use @code{BIG_TABLES}.
@item
@code{SET SQL_LOW_PRIORITY_UPDATES=#} didn't work.
@item
Password wasn't updated correctly if privileges didn't change on:
@code{GRANT ... IDENTIFIED BY}
@item
Fixed range optimizer bug in
@code{SELECT * FROM @var{tbl_name} WHERE @var{key_part1} >= @var{const} AND (@var{key_part2} = @var{const}
OR @var{key_part2} = @var{const})}.
@item
Fixed bug in compression key handling in @code{ISAM}.
@end itemize


@node News-3.22.25, News-3.22.24, News-3.22.26, News-3.22.x
@appendixsubsec Changes in release 3.22.25 (07 Jun 1999)

@itemize @bullet
@item
Fixed some small problems with the installation.
@end itemize


@node News-3.22.24, News-3.22.23, News-3.22.25, News-3.22.x
@appendixsubsec Changes in release 3.22.24 (05 Jul 1999)

@itemize @bullet
@item
@code{DATA} is no longer a reserved word.
@item
Fixed optimizer bug with tables with only one row.
@item
Fixed bug when using @code{LOCK TABLES @var{tbl_name} READ; FLUSH TABLES;}
@item
Applied some patches for HP-UX.
@item
@command{isamchk} should now work on Windows.
@item
Changed @file{configure} to not use big file handling on Linux as this
crashes some Red Hat 6.0 systems
@end itemize


@node News-3.22.23, News-3.22.22, News-3.22.24, News-3.22.x
@appendixsubsec Changes in release 3.22.23 (08 Jun 1999)

@itemize @bullet
@item
Upgraded to use Autoconf 2.13, Automake 1.4 and @command{libtool} 1.3.2.
@item
Better support for SCO in @command{configure}.
@item
Added option @code{--defaults-file=file_name} to option file handling to force
use of only one specific option file.
@item
Extended @code{CREATE} syntax to ignore MySQL 3.23 keywords.
@item
Fixed deadlock problem when using @code{INSERT DELAYED} on a table locked with
@code{LOCK TABLES}.
@item
Fixed deadlock problem when using @code{DROP TABLE} on a table that was
locked by another thread.
@item
Add logging of @code{GRANT/REVOKE} commands in the update log.
@item
Fixed @command{isamchk} to detect a new error condition.
@item
Fixed bug in @code{NATURAL LEFT JOIN}.
@end itemize


@node News-3.22.22, News-3.22.21, News-3.22.23, News-3.22.x
@appendixsubsec Changes in release 3.22.22 (30 Apr 1999)

@itemize @bullet
@item
Fixed problem in the C API when you called @code{mysql_close()} directly after
@code{mysql_init()}.
@item
Better client error message when you can't open socket.
@item
Fixed @code{delayed_insert_thread} counting when you couldn't create a new
delayed_insert thread.
@item
Fixed bug in @code{CONCAT()} with many arguments.
@item
Added patches for DEC 3.2 and SCO.
@item
Fixed path-bug when installing MySQL as a service on NT.
@item
MySQL on Windows is now compiled with VC++ 6.0 instead of
with VC++ 5.0.
@item
New installation setup for MySQL on Windows.
@end itemize


@node News-3.22.21, News-3.22.20, News-3.22.22, News-3.22.x
@appendixsubsec Changes in release 3.22.21 (04 Apr 1999)

@itemize @bullet
@item
Fixed problem with @code{DELETE FROM TABLE} when table was locked by
another thread.
@item
Fixed bug in @code{LEFT JOIN} involving empty tables.
@item
Changed the @code{mysql.db} column from @code{CHAR(32)} to @code{CHAR(60)}.
@item
@code{MODIFY} and @code{DELAYED} are no longer reserved words.
@item
Fixed a bug when storing days in a @code{TIME} column.
@item
Fixed a problem with @code{Host '...' is not allowed to connect to this MySQL
server} after one had inserted a new MySQL user with a @code{GRANT}
command.
@item
Changed to use @code{TCP_NODELAY} also on Linux (should give faster TCP/IP
connections).
@end itemize


@node News-3.22.20, News-3.22.19, News-3.22.21, News-3.22.x
@appendixsubsec Changes in release 3.22.20 (18 Mar 1999)

@itemize @bullet
@item
Fixed @code{STD()} for big tables when result should be 0.
@item
The update log didn't have newlines on some operating systems.
@item
@code{INSERT DELAYED} had some garbage at end in the update log.
@end itemize


@node News-3.22.19, News-3.22.18, News-3.22.20, News-3.22.x
@appendixsubsec Changes in release 3.22.19 (01 Mar 1999)

@itemize @bullet
@item
Fixed bug in @command{mysql_install_db} (from 3.22.17).
@item
Changed default key cache size to 8MB.
@item
Fixed problem with queries that needed temporary tables with @code{BLOB}
columns.
@end itemize


@node News-3.22.18, News-3.22.17, News-3.22.19, News-3.22.x
@appendixsubsec Changes in release 3.22.18 (26 Feb 1999)

@itemize @bullet
@item
Fixes a fatal problem in 3.22.17 on Linux; after @code{shutdown}
not all threads died properly.
@item
Added option @code{-O flush_time=#} to @command{mysqld}.  This is mostly
useful on Windows and tells how often MySQL should close all
unused tables and flush all updated tables to disk.
@item
Fixed problem that a @code{VARCHAR} column compared with @code{CHAR} column
didn't use keys efficiently.
@end itemize


@node News-3.22.17, News-3.22.16, News-3.22.18, News-3.22.x
@appendixsubsec Changes in release 3.22.17 (22 Feb 1999: Production)

@itemize @bullet
@item
Fixed a core dump problem when using @code{--log-update} and connecting
without a default database.
@item
Fixed some @command{configure} and portability problems.
@item
Using @code{LEFT JOIN} on tables that had circular dependencies caused
@command{mysqld} to hang forever.
@end itemize


@node News-3.22.16, News-3.22.15, News-3.22.17, News-3.22.x
@appendixsubsec Changes in release 3.22.16 (05 Feb 1999)

@itemize @bullet
@item
@command{mysqladmin processlist} could kill the server if a new user logged in.
@item
@code{DELETE FROM @var{tbl_name} WHERE @var{key_column}=@var{col_name}} didn't find any matching
rows.  Fixed.
@item
@code{DATE_ADD(column, ...)} didn't work.
@item
@code{INSERT DELAYED} could deadlock with status @code{upgrading lock}.
@item
Extended @code{ENCRYPT()} to take longer salt strings than 2 characters.
@item
@code{longlong2str} is now much faster than before.  For @code{Intel x86}
platforms, this function is written in optimized assembler.
@item
Added the @code{MODIFY} keyword to @code{ALTER TABLE}.
@end itemize


@node News-3.22.15, News-3.22.14, News-3.22.16, News-3.22.x
@appendixsubsec Changes in release 3.22.15 (27 Jan 1999)

@itemize @bullet
@item
@code{GRANT} used with @code{IDENTIFIED BY} didn't take effect until privileges
were flushed.
@item
Name change of some variables in @code{SHOW STATUS}.
@item
Fixed problem with @code{ORDER BY} with 'only index' optimization when there
were multiple key definitions for a used column.
@item
@code{DATE} and @code{DATETIME} columns are now up to 5 times faster than
before.
@item
@code{INSERT DELAYED} can be used to let the client do other things while the
server inserts rows into a table.
@item
@code{LEFT JOIN USING (col1,col2)} didn't work if one used it with tables
from 2 different databases.
@item
@code{LOAD DATA LOCAL INFILE} didn't work in the Unix version because of
a missing file.
@item
Fixed problems with @code{VARCHAR}/@code{BLOB} on very short rows (< 4 bytes);
error 127 could occur when deleting rows.
@item
Updating @code{BLOB/TEXT} through formulas didn't work for short (< 256 char)
strings.
@item
When you did a @code{GRANT} on a new host, @command{mysqld} could die on the first
connect from this host.
@item
Fixed bug when one used @code{ORDER BY} on column name that was the same
name as an alias.
@item
Added @code{BENCHMARK(loop_count,expression)} function to time expressions.
@end itemize


@node News-3.22.14, News-3.22.13, News-3.22.15, News-3.22.x
@appendixsubsec Changes in release 3.22.14 (01 Jan 1999: Gamma)

@itemize @bullet
@item
Allow empty arguments to @command{mysqld} to make it easier to start from shell
scripts.
@item
Setting a @code{TIMESTAMP} column to @code{NULL} didn't record the timestamp
value in the update log.
@item
Fixed lock handler bug when one did
@code{INSERT INTO TABLE ... SELECT ... GROUP BY}.
@item
Added a patch for @code{localtime_r()} on Windows so that it will no lonher crash
if your date is > 2039, but instead will return a time of all zero.
@item
Names for
user-defined functions are no longer case-sensitive.
@item
Added escape of @code{^Z} (ASCII 26) to @code{\Z} as @code{^Z} doesn't
work with pipes on Windows.
@item
@command{mysql_fix_privileges} adds a new column to the @code{mysql.func} to
support aggregate UDF functions in future MySQL releases.
@end itemize


@node News-3.22.13, News-3.22.12, News-3.22.14, News-3.22.x
@appendixsubsec Changes in release 3.22.13 (16 Dec 1998)

@itemize @bullet
@item
Saving @code{NOW()}, @code{CURDATE()} or @code{CURTIME()} directly in a
column didn't work.
@item
@code{SELECT COUNT(*) ... LEFT JOIN ...} didn't work with no @code{WHERE} part.
@item
Updated @file{config.guess} to allow MySQL to configure on
UnixWare 7.1.x.
@item
Changed the implementation of @code{pthread_cond()} on the Windows version.
@code{get_lock()} now correctly times out on Windows!
@end itemize


@node News-3.22.12, News-3.22.11, News-3.22.13, News-3.22.x
@appendixsubsec Changes in release 3.22.12 (09 Dec 1998)

@itemize @bullet
@item
Fixed problem when using @code{DATE_ADD()} and @code{DATE_SUB()} in a
@code{WHERE} clause.
@item
You can now set the password for a user with the @code{GRANT ... TO user
IDENTIFIED BY 'password'} syntax.
@item
Fixed bug in @code{GRANT} checking with @code{SELECT} on many tables.
@item
Added missing file @command{mysql_fix_privilege_tables} to the RPM
distribution. This is not run by default because it relies on the client
package.
@item
Added option @code{SQL_SMALL_RESULT} to @code{SELECT} to force use of
fast temporary tables when you know that the result set will be small.
@item
Allow use of negative real numbers without a decimal point.
@item
Day number is now adjusted to maximum days in month if the resulting month
after @code{DATE_ADD}/@code{DATE_SUB()} doesn't have enough days.
@item
Fix that @code{GRANT} compares columns in case-insensitive fashion.
@item
Fixed a bug in @file{sql_list.h} that made @code{ALTER TABLE} dump core in
some contexts.
@item
The hostname in @code{user@@hostname} can now include @samp{.} and @samp{-}
without quotes in the context of the @code{GRANT}, @code{REVOKE} and
@code{SET PASSWORD FOR ...} statements.
@item
Fix for @command{isamchk} for tables which need big temporary files.
@end itemize


@node News-3.22.11, News-3.22.10, News-3.22.12, News-3.22.x
@appendixsubsec Changes in release 3.22.11 (24 Nov 1998)

@itemize @bullet
@item
@strong{Important}: You must run the @command{mysql_fix_privilege_tables} script
when you upgrade to this version!  This is needed because of the new
@code{GRANT} system. If you don't do this, you will get @code{Access
denied} when you try to use @code{ALTER TABLE}, @code{CREATE INDEX}, or
@code{DROP INDEX}.
@item
@code{GRANT} to allow/deny users table and column access.
@item
Changed @code{USER()} to return a value in @code{user@@host} format.
Formerly it returned only @code{user}.
@item
Changed the syntax for how to set @code{PASSWORD} for another user.
@item
New command @code{FLUSH STATUS} that resets most status variables to zero.
@item
New status variables: @code{aborted_threads}, @code{aborted_connects}.
@item
New option variable: @code{connection_timeout}.
@item
Added support for Thai sorting (by Pruet Boonma
@email{pruet@@ds90.intanon.nectec.or.th}).
@item
Slovak and Japanese error messages.
@item
Configuration and portability fixes.
@item
Added option @code{SET SQL_WARNINGS=1} to get a warning count also for simple
(single-row) inserts.
@item
MySQL now uses @code{SIGTERM} instead of @code{SIGQUIT} with
shutdown to work better on FreeBSD.
@item
Added option @code{\G} (print vertically) to @command{mysql}.
@item
@code{SELECT HIGH_PRIORITY ...} killed @command{mysqld}.
@item
@code{IS NULL} on a @code{AUTO_INCREMENT} column in a @code{LEFT JOIN} didn't
work as expected.
@item
New function @code{MAKE_SET()}.
@end itemize


@node News-3.22.10, News-3.22.9, News-3.22.11, News-3.22.x
@appendixsubsec Changes in release 3.22.10 (04 Nov 1998)

@itemize @bullet
@item
@command{mysql_install_db} no longer starts the MySQL server!  You
should start @command{mysqld} with @command{safe_mysqld} after installing it!  The
MySQL RPM will, however, start the server as before.
@item
Added @code{--bootstrap} option to @command{mysqld} and recoded
@command{mysql_install_db} to use it.  This will make it easier to install
MySQL with RPMs.
@item
Changed @code{+}, @code{-} (sign and minus), @code{*}, @code{/}, @code{%},
@code{ABS()} and @code{MOD()} to be @code{BIGINT} aware (64-bit safe).
@item
Fixed a bug in @code{ALTER TABLE} that caused @command{mysqld} to crash.
@item
MySQL now always reports the conflicting key values when a
duplicate key entry occurs. (Before this was only reported for @code{INSERT}.)
@item
New syntax: @code{INSERT INTO @var{tbl_name} SET @var{col_name}=@var{value}, @var{col_name}=@var{value}, ...}
@item
Most errors in the @file{.err} log are now prefixed with a time stamp.
@item
Added option @code{MYSQL_INIT_COMMAND} to @code{mysql_options()} to make
a query on connect or reconnect.
@item
Added option @code{MYSQL_READ_DEFAULT_FILE} and
@code{MYSQL_READ_DEFAULT_GROUP} to @code{mysql_options()} to read the
following parameters from the MySQL option files: @code{port},
@code{socket}, @code{compress}, @code{password}, @code{pipe}, @code{timeout},
@code{user}, @code{init-command}, @code{host} and @code{database}.
@item
Added @code{maybe_null} to the UDF structure.
@item
Added option @code{IGNORE} to @code{INSERT} statements with many rows.
@item
Fixed some problems with sorting of the @code{koi8} character sets; users of
@code{koi8} @strong{must} run @command{isamchk -rq} on each table that has an
index on a @code{CHAR} or @code{VARCHAR} column.
@item
New script @command{mysql_setpermission}, by Luuk de Boer.  It allows easy
creation of new users with permissions for specific databases.
@item
Allow use of hexadecimal strings (0x...) when specifying a constant string
(like in the column separators with @code{LOAD DATA INFILE}).
@item
Ported to OS/2 (thanks to Antony T. Curtis @email{antony.curtis@@olcs.net}).
@item
Added more variables to @code{SHOW STATUS} and changed format of output to
be like @code{SHOW VARIABLES}.
@item
Added @code{extended-status} command to @command{mysqladmin} which will show the
new status variables.
@end itemize


@node News-3.22.9, News-3.22.8, News-3.22.10, News-3.22.x
@appendixsubsec Changes in release 3.22.9 (19 Oct 1998)

@itemize @bullet
@item
@code{SET SQL_LOG_UPDATE=0} caused a lockup of the server.
@item
New SQL statement:  @code{FLUSH [ TABLES | HOSTS | LOGS | PRIVILEGES ] [, ...]}
@item
New SQL statement:  @code{KILL} @var{thread_id}.
@item
Added casts and changed include files to make MySQL easier to
compile on AIX and DEC OSF/1 4.x
@item
Fixed conversion problem when using @code{ALTER TABLE} from a @code{INT}
to a short @code{CHAR()} column.
@item
Added @code{SELECT HIGH_PRIORITY}; this will get a lock for the
@code{SELECT} even if there is a thread waiting for another
@code{SELECT} to get a @code{WRITE LOCK}.
@item
Moved @code{wild_compare()} to string class to be able to use @code{LIKE} on
@code{BLOB}/@code{TEXT} columns with @code{\0}.
@item
Added @code{ESCAPE} option to @code{LIKE}.
@item
Added a lot more output to @command{mysqladmin debug}.
@item
You can now start @command{mysqld} on Windows with the @code{--flush} option.
This will flush all tables to disk after each update.  This makes things
much safer on the Windows platforms but also @strong{much} slower.
@end itemize


@node News-3.22.8, News-3.22.7, News-3.22.9, News-3.22.x
@appendixsubsec Changes in release 3.22.8 (06 Oct 1998)

@itemize @bullet
@item
Czech character sets should now work much better.
@c You must also install
@c @uref{http://www.mysql.com/Downloads/Patches/czech-3.22.8-patch}.
@c This patch should also be installed if you are using a character set which
@c uses @code{my_strcoll()}!  The patch should always be safe to install (for any
@c system), but as this patch changes @code{ISAM} internals it's not yet in the
@c default distribution.
@item
@code{DATE_ADD()} and @code{DATE_SUB()} didn't work with group functions.
@item
@command{mysql} will now also try to reconnect on @code{USE database} commands.
@item
Fix problem with @code{ORDER BY} and @code{LEFT JOIN} and @code{const} tables.
@item
Fixed problem with @code{ORDER BY} if the first @code{ORDER BY} column
was a key and the rest of the @code{ORDER BY} columns wasn't part of the key.
@item
Fixed a big problem with @code{OPTIMIZE TABLE}.
@item
MySQL clients on NT will now by default first try to connect with
named pipes and after this with TCP/IP.
@item
Fixed a problem with @code{DROP TABLE} and @command{mysqladmin shutdown} on Windows
(a fatal bug from 3.22.6).
@item
Fixed problems with @code{TIME columns} and negative strings.
@item
Added an extra thread signal loop on shutdown to avoid some error messages
from the client.
@item
MySQL now uses the next available number as extension for the update
log file.
@item
Added patches for UNIXWARE 7.
@end itemize


@node News-3.22.7, News-3.22.6, News-3.22.8, News-3.22.x
@appendixsubsec Changes in release 3.22.7 (21 Sep 1998: Beta)

@itemize @bullet
@item
Added @code{LIMIT} clause for the @code{DELETE} statement.
@item
You can now use the @code{/*! ... */} syntax to hide MySQL-specific
keywords when you write portable code.  MySQL will parse the code
inside the comments as if the surrounding @code{/*!} and @code{*/} comment
characters didn't exist.
@item
@code{OPTIMIZE TABLE @var{tbl_name}} can now be used to reclaim disk space
after many deletes.  Currently, this uses @code{ALTER TABLE} to
regenerate the table, but in the future it will use an integrated
@command{isamchk} for more speed.
@item
Upgraded @command{libtool} to make the configuration process more portable.
@item
Fixed slow @code{UPDATE} and @code{DELETE} operations when using
@code{DATETIME} or @code{DATE} keys.
@item
Changed optimizer to make it better at deciding when to do a full join
and when using keys.
@item
You can now use @command{mysqladmin proc} to display information about your own
threads. Only users with the @code{PROCESS} privilege can get
information about all threads.
(In 4.0.2, you need the @code{SUPER} privilege for this.)
@item
Added handling of formats @code{YYMMDD}, @code{YYYYMMDD},
@code{YYMMDDHHMMSS} for numbers when using @code{DATETIME} and
@code{TIMESTAMP} types. (Formerly these formats only worked with strings.)
@item
Added connect option @code{CLIENT_IGNORE_SPACE} to allow use of spaces
after function names and before @samp{(} (Powerbuilder requires this).
This will make all function names reserved words.
@item
Added the @code{--log-long-format} option to @command{mysqld} to enable timestamps
and INSERT_IDs in the update log.
@item
Added @code{--where} option to @command{mysqldump} (patch by Jim Faucette).
@item
The lexical analyzer now uses ``perfect hashing'' for faster parsing of SQL
statements.
@end itemize


@node News-3.22.6, News-3.22.5, News-3.22.7, News-3.22.x
@appendixsubsec Changes in release 3.22.6 (31 Aug 1998)

@itemize @bullet
@item
Faster @command{mysqldump}.
@item
For the @code{LOAD DATA INFILE} statement, you can now use the new @code{LOCAL}
keyword to read the file from the client.  @command{mysqlimport} will
automatically use @code{LOCAL} when importing with the TCP/IP protocol.
@item
Fixed small optimize problem when updating keys.
@item
Changed makefiles to support shared libraries.
@item
MySQL-NT can now use named pipes, which means that you can now use
MySQL-NT without having to install TCP/IP.
@end itemize


@node News-3.22.5, News-3.22.4, News-3.22.6, News-3.22.x
@appendixsubsec Changes in release 3.22.5 (20 Aug 1998: Alpha)

@itemize @bullet
@item
All table lock handing is changed to avoid some very subtle
deadlocks when using @code{DROP TABLE}, @code{ALTER TABLE}, @code{DELETE FROM
TABLE} and @command{mysqladmin flush-tables} under heavy usage.
Changed locking code to get better handling of locks of different types.
@item
Updated @code{DBI} to 1.00 and @code{DBD} to 1.2.0.
@item
Added a check that the error message file contains error messages suitable for
the current version of @command{mysqld}. (To avoid errors if you accidentally
try to use an old error message file.)
@item
All count structures in the client (@code{affected_rows()},
@code{insert_id()}, ...) are now of type @code{BIGINT} to allow 64-bit values
to be used.
This required a minor change in the MySQL protocol which should affect
only old clients when using tables with @code{AUTO_INCREMENT} values > 16MB.
@item
The return type of @code{mysql_fetch_lengths()} has changed from @code{uint *}
to @code{ulong *}. This may give a warning for old clients but should work
on most machines.
@item
Change @code{mysys} and @code{dbug} libraries to allocate all thread variables
in one struct.  This makes it easier to make a threaded @file{libmysql.dll}
library.
@item
Use the result from @code{gethostname()} (instead of @code{uname()}) when
constructing @file{.pid} filenames.
@item
New better compressed client/server protocol.
@item
@code{COUNT()}, @code{STD()} and @code{AVG()} are extended to handle more than
4GB rows.
@item
You can now store values in the range @code{-838:59:59} <= x <=
@code{838:59:59} in a @code{TIME} column.
@item
@strong{Warning: Incompatible change!!}
If you set a @code{TIME} column to too short a value, MySQL now
assumes the value is given as: @code{[[[D ]HH:]MM:]SS} instead of
@code{HH[:MM[:SS]]}.
@item
@code{TIME_TO_SEC()} and @code{SEC_TO_TIME()} can now handle negative times
and hours up to 32767.
@item
Added new option
@code{SET SQL_LOG_UPDATE=@{0|1@}} to allow users with
the @code{PROCESS} privilege to bypass the update log.
(Modified patch from Sergey A Mukhin @email{violet@@rosnet.net}.)
@item
Fixed fatal bug in @code{LPAD()}.
@item
Initialize line buffer in @file{mysql.cc} to make @code{BLOB} reading from
pipes safer.
@item
Added @code{-O max_connect_errors=#} option to @command{mysqld}.
Connect errors are now reset for each correct connection.
@item
Increased the default value of @code{max_allowed_packet} to @code{1M} in
@command{mysqld}.
@item
Added @code{--low-priority-updates} option to @command{mysqld}, to give
table-modifying operations (@code{INSERT}, @code{REPLACE}, @code{UPDATE},
@code{DELETE}) lower priority than retrievals.  You can now use
@code{@{INSERT | REPLACE | UPDATE | DELETE@} LOW_PRIORITY ...} You can
also use @code{SET SQL_LOW_PRIORITY_UPDATES=@{0|1@}} to change
the priority for one thread.  One side effect is that @code{LOW_PRIORITY}
is now a reserved word. :(
@item
Add support for @code{INSERT INTO table ... VALUES(...),(...),(...)},
to allow inserting multiple rows with a single statement.
@item
@code{INSERT INTO @var{tbl_name}} is now also cached when used with @code{LOCK TABLES}.
(Previously only @code{INSERT ... SELECT} and @code{LOAD DATA INFILE} were
cached.)
@item
Allow @code{GROUP BY} functions with @code{HAVING}:
@example
mysql> SELECT col FROM table GROUP BY col HAVING COUNT(*)>0;
@end example
@item
@command{mysqld} will now ignore trailing @samp{;} characters in queries. This
is to make it easier to migrate from some other SQL servers that require the
trailing @samp{;}.
@item
Fix for corrupted fixed-format output generated by @code{SELECT INTO OUTFILE}.
@item
@strong{Warning: Incompatible change!}
Added Oracle @code{GREATEST()} and @code{LEAST()} functions.  You must now use
these instead of the @code{MAX()} and @code{MIN()} functions to get the
largest/smallest value from a list of values. These can now handle @code{REAL},
@code{BIGINT} and string (@code{CHAR} or @code{VARCHAR}) values.
@item
@strong{Warning: Incompatible change!}
@code{DAYOFWEEK()} had offset 0 for Sunday. Changed the offset to 1.
@item
Give an error for queries that mix @code{GROUP BY} columns and fields when
there is no @code{GROUP BY} specification.
@item
Added @code{--vertical} option to @command{mysql}, for printing results in
vertical mode.
@item
Index-only optimization; some queries are now resolved using
only indexes.  Until MySQL 4.0, this works only for numeric columns.
@xref{MySQL indexes, , MySQL indexes}.
@item
Lots of new benchmarks.
@item
A new C API chapter and lots of other improvements in the manual.
@end itemize


@node News-3.22.4, News-3.22.3, News-3.22.5, News-3.22.x
@appendixsubsec Changes in release 3.22.4 (06 Jul 1998: Beta)

@itemize @bullet
@item
Added @code{--tmpdir} option to @command{mysqld}, for specifying the location
of the temporary file directory.
@item
MySQL now automatically changes a query from an ODBC client:
@example
SELECT ... FROM table WHERE auto_increment_column IS NULL
@end example
to:
@example
SELECT ... FROM table WHERE auto_increment_column == LAST_INSERT_ID()
@end example
This allows some ODBC programs (Delphi, Access) to retrieve the newly
inserted row to fetch the @code{AUTO_INCREMENT} value.
@item
@code{DROP TABLE} now waits for all users to free a table before deleting it.
@item
Fixed small memory leak in the new connect protocol.
@item
New functions @code{BIN()}, @code{OCT()}, @code{HEX()} and @code{CONV()} for
converting between different number bases.
@item
Added function @code{SUBSTRING()} with two arguments.
@item
If you created a table with a record length smaller than 5, you couldn't
delete rows from the table.
@item
Added optimization to remove @code{const} reference tables from @code{ORDER BY} and
@code{GROUP BY}.
@item
@command{mysqld} now automatically disables system locking on Linux and Windows,
and for systems that use MIT-pthreads.  You can force the use of locking
with the @code{--enable-external-locking} option.
@item
Added @code{--console} option to @command{mysqld}, to force a console window
(for error messages) when using Windows.
@item
Fixed table locks for Windows.
@item
Allow @samp{$} in identifiers.
@item
Changed name of user-specific configuration file from @file{my.cnf} to
@file{.my.cnf} (Unix only).
@item
Added @code{DATE_ADD()} and @code{DATE_SUB()} functions.
@end itemize


@node News-3.22.3, News-3.22.2, News-3.22.4, News-3.22.x
@appendixsubsec Changes in release 3.22.3 (30 Jun 1998)

@itemize @bullet
@item
Fixed a lock problem (bug in MySQL 3.22.1) when closing temporary tables.
@item
Added missing @code{mysql_ping()} to the client library.
@item
Added @code{--compress} option to all MySQL clients.
@item
Changed @code{byte} to @code{char} in @file{mysql.h} and @file{mysql_com.h}.
@end itemize


@node News-3.22.2, News-3.22.1, News-3.22.3, News-3.22.x
@appendixsubsec Changes in release 3.22.2

@itemize @bullet
@item
Searching on multiple constant keys that matched more than 30% of the rows
didn't always use the best possible key.
@item
New functions @code{<<}, @code{>>}, @code{RPAD()} and @code{LPAD()}.
@item
You can now save default options (like passwords) in a configuration file
(@file{my.cnf}).
@item
Lots of small changes to get @code{ORDER BY} to work when no records are found
when using fields that are not in @code{GROUP BY} (MySQL extension).
@item
Added @code{--chroot} option to @command{mysqld}, to start @command{mysqld} in
a chroot environment (by Nikki Chumakov @email{nikkic@@cityline.ru}).
@item
Trailing spaces are now ignored when comparing case-sensitive strings;
this should fix some problems with ODBC and flag 512!
@item
Fixed a core dump bug in the range optimizer.
@item
Added @code{--one-thread} option to @command{mysqld}, for debugging with
LinuxThreads (or @code{glibc}).  (This replaces the @code{-T32} flag)
@item
Added @code{DROP TABLE IF EXISTS} to prevent an error from occurring if the
table doesn't exist.
@item
@code{IF} and @code{EXISTS} are now reserved words (they would have to
be sooner or later).
@item
Added lots of new options to @command{mysqldump}.
@item
Server error messages are now in @file{mysqld_error.h}.
@item
The client/server protocol now supports compression.
@item
All bugfixes from MySQL 3.21.32.
@end itemize


@node News-3.22.1, News-3.22.0, News-3.22.2, News-3.22.x
@appendixsubsec Changes in release 3.22.1 (Jun 1998)

@itemize @bullet
@item
Added new C API function @code{mysql_ping()}.
@item
Added new API functions @code{mysql_init()} and @code{mysql_options()}.
You now MUST call @code{mysql_init()} before you call
@code{mysql_real_connect()}.
You don't have to call @code{mysql_init()} if you only use
@code{mysql_connect()}.
@item
Added @code{mysql_options(...,MYSQL_OPT_CONNECT_TIMEOUT,...)} so you can set a
timeout for connecting to a server.
@item
Added @code{--timeout} option to @command{mysqladmin}, as a test of
@code{mysql_options()}.
@item
Added @code{AFTER column} and @code{FIRST} options to
@code{ALTER TABLE ... ADD columns}.
This makes it possible to add a new column at some specific location
within a row in an existing table.
@item
@code{WEEK()} now takes an optional argument to allow handling of weeks when
the week starts on Monday (some European countries).  By default,
@code{WEEK()} assumes the week starts on Sunday.
@item
@code{TIME} columns weren't stored properly (bug in MySQL 3.22.0).
@item
@code{UPDATE} now returns information about how many rows were
matched and updated, and how many ``warnings'' occurred when doing the update.
@item
Fixed incorrect result from @code{FORMAT(-100,2)}.
@item
@code{ENUM} and @code{SET} columns were compared in binary (case-sensitive)
fashion; changed to be case-insensitive.
@end itemize


@node News-3.22.0,  , News-3.22.1, News-3.22.x
@appendixsubsec Changes in release 3.22.0 (18 May 1998: Alpha)

@itemize @bullet
@item
New (backward-compatible) connect protocol that allows you to
specify the database to use when connecting, to get much faster
connections to a specific database.

The @code{mysql_real_connect()} call is changed to:

@example
mysql_real_connect(MYSQL *mysql, const char *host, const char *user,
                   const char *passwd, const char *db, uint port,
                   const char *unix_socket, uint client_flag)
@end example
@item
Each connection is handled by its own thread, rather than by the
master @code{accept()} thread.  This fixes permanently the telnet bug
that was a topic on the mail list some time ago.
@item
All TCP/IP connections are now checked with backward-resolution of
the hostname to get better security. @command{mysqld} now has a local hostname
resolver cache so connections should actually be faster than before,
even with this feature.
@item
A site automatically will be blocked from future connections if someone
repeatedly connects with an ``improper header'' (like when one uses telnet).
@item
You can now refer to tables in different databases with references of the form
@var{tbl_name@@db_name} or @var{db_name.tbl_name}.  This makes it possible to
give a user read access to some tables and write access to others simply by
keeping them in different databases!
@item
Added @code{--user} option to @command{mysqld}, to allow it to run
as another Unix user (if it is started as the Unix @code{root} user).
@item
Added caching of users and access rights (for faster access rights checking)
@item
Normal users (not anonymous ones) can change their password with
@command{mysqladmin password "@var{newpwd}"}.  This uses encrypted passwords
that are not logged in the normal MySQL log!
@item
All important string functions are now coded in assembler for x86 Linux
machines.  This gives a speedup of 10% in many cases.
@item
For tables that have many columns, the column names are now hashed for
much faster column name lookup (this will speed up some benchmark
tests a lot!)
@item
Some benchmarks are changed to get better individual timing.
(Some loops were so short that a specific test took < 2 seconds. The
loops have been changed to take about 20 seconds to make it easier
to compare different databases. A test that took 1-2 seconds before
now takes 11-24 seconds, which is much better)
@item
Re-arranged @code{SELECT} code to handle some very specific queries
involving group functions (like @code{COUNT(*)}) without a @code{GROUP BY} but
with @code{HAVING}. The following now works:
@example
mysql> SELECT COUNT(*) as C FROM table HAVING C > 1;
@end example
@item
Changed the protocol for field functions to be faster and avoid some
calls to @code{malloc()}.
@item
Added @code{-T32} option to @command{mysqld}, for running all queries under the
main thread.  This makes it possible to debug @command{mysqld} under Linux with
@command{gdb}!
@item
Added optimization of @code{not_null_column IS NULL} (needed for some Access
queries).
@item
Allow @code{STRAIGHT_JOIN} to be used between two tables to force the optimizer
to join them in a specific order.
@item
String functions now return @code{VARCHAR} rather than @code{CHAR} and
the column type is now @code{VARCHAR} for fields saved as @code{VARCHAR}.
This should make the MyODBC driver better, but may break some old
MySQL clients that don't handle @code{FIELD_TYPE_VARCHAR} the same
way as @code{FIELD_TYPE_CHAR}.
@item
@code{CREATE INDEX} and @code{DROP INDEX} are now implemented through
@code{ALTER TABLE}.
@code{CREATE TABLE} is still the recommended (fast) way to create indexes.
@item
Added @code{--set-variable} option @code{wait_timeout} to @command{mysqld}.
@item
Added time column to @command{mysqladmin processlist} to show how long a query
has taken or how long a thread has slept.
@item
Added lots of new variables to @code{show variables} and some new to
@code{show status}.
@item
Added new type @code{YEAR}. @code{YEAR} is stored in 1 byte with allowable
values of 0, and 1901 to 2155.
@item
Added new @code{DATE} type that is stored in 3 bytes rather than 4 bytes.
All new tables are created with the new date type if you don't use the
@code{--old-protocol} option to @command{mysqld}.
@item
Fixed bug in record caches; for some queries, you could get
@code{Error from table handler: #} on some operating systems.
@item
Added @code{--enable-assembler} option to @command{configure}, for x86 machines
(tested on Linux + @command{gcc}).  This will enable assembler functions for the
most important string functions for more speed!
@end itemize


@node News-3.21.x, News-3.20.x, News-3.22.x, News
@appendixsec Changes in release 3.21.x

@cindex changes, version 3.21

MySQL 3.21 is quite old now, and should be avoided if possible.  This
information is kept here for historical purposes only.

@menu
* News-3.21.33::                Changes in release 3.21.33 (08 Jul 1998)
* News-3.21.32::                Changes in release 3.21.32 (30 Jun 1998)
* News-3.21.31::                Changes in release 3.21.31 (10 Jun 1998)
* News-3.21.30::                Changes in release 3.21.30
* News-3.21.29::                Changes in release 3.21.29
* News-3.21.28::                Changes in release 3.21.28
* News-3.21.27::                Changes in release 3.21.27
* News-3.21.26::                Changes in release 3.21.26
* News-3.21.25::                Changes in release 3.21.25
* News-3.21.24::                Changes in release 3.21.24
* News-3.21.23::                Changes in release 3.21.23
* News-3.21.22::                Changes in release 3.21.22
* News-3.21.21a::               Changes in release 3.21.21a
* News-3.21.21::                Changes in release 3.21.21
* News-3.21.20::                Changes in release 3.21.20
* News-3.21.19::                Changes in release 3.21.19
* News-3.21.18::                Changes in release 3.21.18
* News-3.21.17::                Changes in release 3.21.17
* News-3.21.16::                Changes in release 3.21.16
* News-3.21.15::                Changes in release 3.21.15
* News-3.21.14b::               Changes in release 3.21.14b
* News-3.21.14a::               Changes in release 3.21.14a
* News-3.21.13::                Changes in release 3.21.13
* News-3.21.12::                Changes in release 3.21.12
* News-3.21.11::                Changes in release 3.21.11
* News-3.21.10::                Changes in release 3.21.10
* News-3.21.9::                 Changes in release 3.21.9
* News-3.21.8::                 Changes in release 3.21.8
* News-3.21.7::                 Changes in release 3.21.7
* News-3.21.6::                 Changes in release 3.21.6
* News-3.21.5::                 Changes in release 3.21.5
* News-3.21.4::                 Changes in release 3.21.4
* News-3.21.3::                 Changes in release 3.21.3
* News-3.21.2::                 Changes in release 3.21.2
* News-3.21.0::                 Changes in release 3.21.0
@end menu


@node News-3.21.33, News-3.21.32, News-3.21.x, News-3.21.x
@appendixsubsec Changes in release 3.21.33 (08 Jul 1998)

@itemize @bullet
@item
Fixed problem when sending @code{SIGHUP} to @command{mysqld};
@command{mysqld} dumped core when starting from boot on some systems.
@item
Fixed problem with losing a little memory for some connections.
@item
@code{DELETE FROM @var{tbl_name}} without a @code{WHERE} condition is now done the
long way when you use @code{LOCK TABLES} or if the table is in use, to
avoid race conditions.
@item
@code{INSERT INTO TABLE (timestamp_column) VALUES (NULL);} didn't set timestamp.
@end itemize


@node News-3.21.32, News-3.21.31, News-3.21.33, News-3.21.x
@appendixsubsec Changes in release 3.21.32 (30 Jun 1998)

@itemize @bullet
@item
Fixed some possible race conditions when doing many reopen/close on the same
tables under heavy load!  This can happen if you execute @command{mysqladmin
refresh} often. This could in some very rare cases corrupt the header of the
index file and cause error 126 or 138.

@item
Fixed fatal bug in @code{refresh()} when running with the
@code{--skip-external-locking} option.  There was a ``very small'' time gap after
a @command{mysqladmin refresh} when a table could be corrupted if one
thread updated a table while another thread did @command{mysqladmin
refresh} and another thread started a new update ont the same table
before the first thread had finished.  A refresh (or
@code{--flush-tables}) will now not return until all used tables are
closed!
@item
@code{SELECT DISTINCT} with a @code{WHERE} clause that didn't match any rows
returned a row in some contexts (bug only in 3.21.31).
@item
@code{GROUP BY} + @code{ORDER BY} returned one empty row when no rows where
found.
@item
Fixed a bug in the range optimizer that wrote
@code{Use_count: Wrong count for ...} in the error log file.
@end itemize


@node News-3.21.31, News-3.21.30, News-3.21.32, News-3.21.x
@appendixsubsec Changes in release 3.21.31 (10 Jun 1998)

@itemize @bullet
@item
Fixed a sign extension problem for the @code{TINYINT} type on Irix.
@item
Fixed problem with @code{LEFT("constant_string",function)}.
@item
Fixed problem with @code{FIND_IN_SET()}.
@item
@code{LEFT JOIN} dumped core if the second table is used with a constant
@code{WHERE/ON} expression that uniquely identifies one record.
@item
Fixed problems with @code{DATE_FORMAT()} and incorrect dates.
@code{DATE_FORMAT()} now ignores @code{'%'} to make it possible to extend
it more easily in the future.
@end itemize


@node News-3.21.30, News-3.21.29, News-3.21.31, News-3.21.x
@appendixsubsec Changes in release 3.21.30

@itemize @bullet
@item
@command{mysql} now returns an exit code > 0 if the query returned an error.
@item
Saving of command-line history to file in @command{mysql} client.
By Tommy Larsen @email{tommy@@mix.hive.no}.
@item
Fixed problem with empty lines that were ignored in @file{mysql.cc}.
@item
Save the pid of the signal handler thread in the pid file instead
of the pid of the main thread.
@item
Added patch by @email{tommy@@valley.ne.jp} to support Japanese characters
SJIS and UJIS.
@item
Changed @command{safe_mysqld} to redirect startup messages to
@code{@var{host_name}.err} instead
of @code{@var{host_name}.log} to reclaim file space on @command{mysqladmin refresh}.
@item
@code{ENUM} always had the first entry as default value.
@item
@code{ALTER TABLE} wrote two entries to the update log.
@item
@code{sql_acc()} now closes the @code{mysql} grant tables after a reload to
save table space and memory.
@item
Changed @code{LOAD DATA} to use less memory with tables and @code{BLOB}
columns.
@item
Sorting on a function which made a division / 0 produced a wrong set
in some cases.
@item
Fixed @code{SELECT} problem with @code{LEFT()} when using the @code{czech}
character set.
@item
Fixed problem in @command{isamchk}; it couldn't repair a packed table in a very
unusual case.
@item
@code{SELECT} statements with @code{&} or @code{|} (bit functions) failed on
columns with @code{NULL} values.
@item
When comparing a field = field, where one of the fields was a part key,
only the length of the part key was compared.
@end itemize


@node News-3.21.29, News-3.21.28, News-3.21.30, News-3.21.x
@appendixsubsec Changes in release 3.21.29

@itemize @bullet
@item
@code{LOCK TABLES} + @code{DELETE from @var{tbl_name}} never removed locks properly.
@item
Fixed problem when grouping on an @code{OR} function.
@item
Fixed permission problem with @code{umask()} and creating new databases.
@item
Fixed permission problem on result file with @code{SELECT ... INTO OUTFILE ...}
@item
Fixed problem in range optimizer (core dump) for a very complex query.
@item
Fixed problem when using @code{MIN(integer)} or @code{MAX(integer)} in
@code{GROUP BY}.
@item
Fixed bug on Alpha when using integer keys. (Other keys worked on Alpha.)
@item
Fixed bug in @code{WEEK("XXXX-xx-01")}.
@end itemize


@node News-3.21.28, News-3.21.27, News-3.21.29, News-3.21.x
@appendixsubsec Changes in release 3.21.28

@itemize @bullet
@item
Fixed socket permission (clients couldn't connect to Unix socket on Linux).
@item
Fixed bug in record caches; for some queries, you could get
@code{Error from table handler: #} on some operating systems.
@end itemize


@node News-3.21.27, News-3.21.26, News-3.21.28, News-3.21.x
@appendixsubsec Changes in release 3.21.27

@itemize @bullet
@item
Added user level lock functions @code{GET_LOCK(string,timeout)},
@code{RELEASE_LOCK(string)}.
@item
Added @code{Opened_tables} to @code{show status}.
@item
Changed connect timeout to 3 seconds to make it somewhat harder
for crackers to kill @command{mysqld} through telnet + TCP/IP.
@item
Fixed bug in range optimizer when using
@code{WHERE @var{key_part_1} >= @var{something} AND @var{key_part_2} <= @var{something_else}}.
@item
Changed @command{configure} for detection of FreeBSD 3.0 9803xx and above
@item
@code{WHERE} with @code{@var{string_col_key} = @var{constant_string}} didn't always
find all rows if the column had many values differing only with
characters of the same sort value (like e and e with an accent).
@item
Strings keys looked up with 'ref' were not compared in case-sensitive fashion.
@item
Added @code{umask()} to make log files non-readable for normal users.
@item
Ignore users with old (8-byte) password on startup if not using
@code{--old-protocol} option to @command{mysqld}.
@item
@code{SELECT} which matched all key fields returned the values in the
case of the matched values, not of the found values. (Minor problem.)
@end itemize


@node News-3.21.26, News-3.21.25, News-3.21.27, News-3.21.x
@appendixsubsec Changes in release 3.21.26

@itemize @bullet
@item
@code{FROM_DAYS(0)} now returns "0000-00-00".
@item
In @code{DATE_FORMAT()}, PM and AM were swapped for hours 00 and 12.
@item
Extended the default maximum key size to 256.
@item
Fixed bug when using @code{BLOB}/@code{TEXT} in @code{GROUP BY} with many
tables.
@item
An @code{ENUM} field that is not declared @code{NOT NULL} has @code{NULL} as
the default value.
(Previously, the default value was the first enumeration value.)
@item
Fixed bug in the join optimizer code when using many part keys
on the same key:  @code{INDEX (Organization,Surname(35),Initials(35))}.
@item
Added some tests to the table order optimizer to get some cases with
@code{SELECT ... FROM many_tables} much faster.
@item
Added a retry loop around @code{accept()} to possibly fix some problems on some
Linux machines.
@end itemize


@node News-3.21.25, News-3.21.24, News-3.21.26, News-3.21.x
@appendixsubsec Changes in release 3.21.25

@itemize @bullet
@item
Changed @code{typedef 'string'} to @code{typedef 'my_string'} for better
portability.
@item
You can now kill threads that are waiting on a disk-full condition.
@item
Fixed some problems with UDF functions.
@item
Added long options to @command{isamchk}. Try @command{isamchk --help}.
@item
Fixed a bug when using 8 bytes long (alpha); @code{filesort()} didn't work.
Affects @code{DISTINCT}, @code{ORDER BY} and @code{GROUP BY} on 64-bit
processors.
@end itemize


@node News-3.21.24, News-3.21.23, News-3.21.25, News-3.21.x
@appendixsubsec Changes in release 3.21.24

@itemize @bullet
@item
Dynamic loadable functions. Based on source from Alexis Mikhailov.
@item
You couldn't delete from a table if no one had done a @code{SELECT} on the
table.
@item
Fixed problem with range optimizer with many @code{OR} operators on key parts
inside each other.
@item
Recoded @code{MIN()} and @code{MAX()} to work properly with strings and
@code{HAVING}.
@item
Changed default umask value for new files from @code{0664} to @code{0660}.
@item
Fixed problem with @code{LEFT JOIN} and constant expressions in the @code{ON}
part.
@item
Added Italian error messages from @email{brenno@@dewinter.com}.
@item
@command{configure} now works better on OSF/1 (tested on 4.0D).
@item
Added hooks to allow @code{LIKE} optimization with international character
support.
@item
Upgraded @code{DBI} to 0.93.
@end itemize


@node News-3.21.23, News-3.21.22, News-3.21.24, News-3.21.x
@appendixsubsec Changes in release 3.21.23

@itemize @bullet
@item
The following symbols are now reserved words:
@code{TIME}, @code{DATE}, @code{TIMESTAMP}, @code{TEXT}, @code{BIT},
@code{ENUM}, @code{NO}, @code{ACTION}, @code{CHECK}, @code{YEAR},
@code{MONTH}, @code{DAY}, @code{HOUR}, @code{MINUTE}, @code{SECOND},
@code{STATUS}, @code{VARIABLES}.
@item
Setting a @code{TIMESTAMP} to @code{NULL} in @code{LOAD DATA INFILE ...} didn't
set the current time for the @code{TIMESTAMP}.
@item
Fix @code{BETWEEN} to recognize binary strings. Now @code{BETWEEN} is
case-sensitive.
@item
Added @code{--skip-thread-priority} option to @command{mysqld}, for systems
where @command{mysqld} thread scheduling doesn't work properly (BSDI 3.1).
@item
Added ODBC functions @code{DAYNAME()} and @code{MONTHNAME()}.
@item
Added function @code{TIME_FORMAT()}.  This works like @code{DATE_FORMAT()},
but takes a time string (@code{'HH:MM:SS'}) as argument.
@item
Fixed unlikely(?) key optimizer bug when using @code{OR} operators of key parts
inside @code{AND} expressions.
@item
Added @code{variables} command to @command{mysqladmin}.
@item
A lot of small changes to the binary releases.
@item
Fixed a bug in the new protocol from MySQL 3.21.20.
@item
Changed @code{ALTER TABLE} to work with Windows (Windows can't rename
open files).  Also fixed a couple of small bugs in the Windows version.
@item
All standard MySQL clients are now ported to MySQL for Windows.
@item
MySQL can now be started as a service on NT.
@end itemize


@node News-3.21.22, News-3.21.21a, News-3.21.23, News-3.21.x
@appendixsubsec Changes in release 3.21.22

@itemize @bullet
@item
Starting with this version, all MySQL distributions will be
configured, compiled and tested with @code{crash-me} and the benchmarks on
the following platforms: SunOS 5.6 sun4u, SunOS 5.5.1 sun4u, SunOS 4.14 sun4c,
SunOS 5.6 i86pc, Irix 6.3 mips5k, HP-UX 10.20 hppa, AIX 4.2.1 ppc,
OSF/1 V4.0 alpha, FreeBSD 2.2.2 i86pc and BSDI 3.1 i386.
@item
Fix @code{COUNT(*)} problems when the @code{WHERE} clause didn't match any
records.  (Bug from 3.21.17.)
@item
Removed that @code{NULL = NULL} is true.  Now you must use @code{IS NULL}
or @code{IS NOT NULL} to test whether a value is @code{NULL}.
(This is according to standard SQL but may break
old applications that are ported from @code{mSQL}.)
You can get the old behavior by compiling with @code{-DmSQL_COMPLIANT}.
@item
Fixed bug that caused core-dump when using many @code{LEFT OUTER JOIN} clauses.
@item
Fixed bug in @code{ORDER BY} on string formula with possible @code{NULL} values.
@item
Fixed problem in range optimizer when using @code{<=} on sub index.
@item
Added functions @code{DAYOFYEAR()}, @code{DAYOFMONTH()}, @code{MONTH()},
@code{YEAR()}, @code{WEEK()}, @code{QUARTER()}, @code{HOUR()}, @code{MINUTE()},
@code{SECOND()} and @code{FIND_IN_SET()}.
@item
Added @code{SHOW VARIABLES} command.
@item
Added support of ``long constant strings'' from standard SQL:
@example
mysql> SELECT 'first ' 'second';       -> 'first second'
@end example
@item
Upgraded Msql-Mysql-modules to 1.1825.
@item
Upgraded @command{mysqlaccess} to 2.02.
@item
Fixed problem with Russian character set and @code{LIKE}.
@item
Ported to OpenBSD 2.1.
@item
New Dutch error messages.
@end itemize


@node News-3.21.21a, News-3.21.21, News-3.21.22, News-3.21.x
@appendixsubsec Changes in release 3.21.21a

@itemize @bullet
@item
Configure changes for some operating systems.
@end itemize


@node News-3.21.21, News-3.21.20, News-3.21.21a, News-3.21.x
@appendixsubsec Changes in release 3.21.21

@itemize @bullet
@item
Fixed optimizer bug when using
@code{WHERE data_field = date_field2 AND date_field2 = constant}.
@item
Added @code{SHOW STATUS} command.
@item
Removed @file{manual.ps} from the source distribution to make it smaller.
@end itemize


@node News-3.21.20, News-3.21.19, News-3.21.21, News-3.21.x
@appendixsubsec Changes in release 3.21.20

@itemize @bullet
@item
Changed the maximum table name and column name lengths from 32 to 64.
@item
Aliases can now be of ``any'' length.
@item
Fixed @command{mysqladmin stat} to return the right number of queries.
@item
Changed protocol (downward compatible) to mark if a column has the
@code{AUTO_INCREMENT} attribute or is a @code{TIMESTAMP}. This is needed for
the new Java driver.
@item
Added Hebrew sorting order by Zeev Suraski.
@item
Solaris 2.6: Fixed @command{configure} bugs and increased maximum table size
from 2GB to 4GB.
@end itemize


@node News-3.21.19, News-3.21.18, News-3.21.20, News-3.21.x
@appendixsubsec Changes in release 3.21.19

@itemize @bullet
@item
Upgraded @code{DBD} to 1.1823. This version implements @code{mysql_use_result}
in @code{DBD-Mysql}.
@item
Benchmarks updated for empress (by Luuk).
@item
Fixed a case of slow range searching.
@item
Configure fixes (@file{Docs} directory).
@item
Added function @code{REVERSE()} (by Zeev Suraski).
@end itemize


@node News-3.21.18, News-3.21.17, News-3.21.19, News-3.21.x
@appendixsubsec Changes in release 3.21.18

@itemize @bullet
@item
Issue error message if client C functions are called in wrong order.
@item
Added automatic reconnect to the @file{libmysql.c} library. If a write command
fails, an automatic reconnect is done.
@item
Small sort sets no longer use temporary files.
@item
Upgraded @code{DBI} to 0.91.
@item
Fixed a couple of problems with @code{LEFT OUTER JOIN}.
@item
Added @code{CROSS JOIN} syntax. @code{CROSS} is now a reserved word.
@item
Recoded @command{yacc}/@command{bison} stack allocation to be even safer and to allow
MySQL to handle even bigger expressions.
@item
Fixed a couple of problems with the update log.
@item
@code{ORDER BY} was slow when used with key ranges.
@end itemize


@node News-3.21.17, News-3.21.16, News-3.21.18, News-3.21.x
@appendixsubsec Changes in release 3.21.17

@itemize @bullet
@item
Changed documentation string of @code{--with-unix-socket-path} to avoid
confusion.
@item
Added ODBC and standard SQL style @code{LEFT OUTER JOIN}.
@item
The following are new reserved words: @code{LEFT}, @code{NATURAL},
@code{USING}.
@item
The client library now uses the value of the environment variable
@code{MYSQL_HOST} as the default host if it's defined.
@item
@code{SELECT @var{col_name}, SUM(@var{expr})} now returns @code{NULL} for @var{col_name}
when there are matching rows.
@item
Fixed problem with comparing binary strings and @code{BLOB} values with ASCII
characters over 127.
@item
Fixed lock problem: when freeing a read lock on a table with multiple
read locks, a thread waiting for a write lock would have been given the lock.
This shouldn't affect data integrity, but could possibly make @command{mysqld}
restart if one thread was reading data that another thread modified.
@item
@code{LIMIT offset,count} didn't work in @code{INSERT ... SELECT}.
@item
Optimized key block caching. This will be quicker than the old algorithm when
using bigger key caches.
@end itemize


@node News-3.21.16, News-3.21.15, News-3.21.17, News-3.21.x
@appendixsubsec Changes in release 3.21.16

@itemize @bullet
@item
Added ODBC 2.0 & 3.0 functions @code{POWER()}, @code{SPACE()},
@code{COT()}, @code{DEGREES()}, @code{RADIANS()}, @code{ROUND(2 arg)}
and @code{TRUNCATE()}.
@item
@strong{Warning: Incompatible change!} @code{LOCATE()} parameters were
swapped according to ODBC standard. Fixed.
@item
Added function @code{TIME_TO_SEC()}.
@item
In some cases, default values were not used for @code{NOT NULL} fields.
@item
Timestamp wasn't always updated properly in @code{UPDATE SET ...} statements.
@item
Allow empty strings as default values for @code{BLOB} and @code{TEXT}, to
be compatible with @command{mysqldump}.
@end itemize


@node News-3.21.15, News-3.21.14b, News-3.21.16, News-3.21.x
@appendixsubsec Changes in release 3.21.15

@itemize @bullet
@item
@strong{Warning: Incompatible change!} @code{mysqlperl} is now from
Msql-Mysql-modules. This means that @code{connect()} now takes
@code{host}, @code{database}, @code{user}, @code{password} arguments! The old
version took @code{host}, @code{database}, @code{password}, @code{user}.
@item
Allow @code{DATE '1997-01-01'}, @code{TIME '12:10:10'} and
@code{TIMESTAMP '1997-01-01 12:10:10'} formats required by standard SQL.
@strong{Warning: Incompatible change!} This has the unfortunate
side effect that you no longer can have columns named @code{DATE}, @code{TIME}
or @code{TIMESTAMP}. :( Old columns can still be accessed through
@var{tbl_name.col_name}!)
@item
Changed Makefiles to hopefully work better with BSD systems. Also,
@file{manual.dvi} is now included in the distribution to avoid having stupid
@command{make} programs trying to rebuild it.
@item
@code{readline} library upgraded to version 2.1.
@item
A new sortorder german-1. That is a normal ISO-Latin1 with a german sort
order.
@item
Perl @code{DBI}/@code{DBD} is now included in the distribution. @code{DBI}
is now the recommended way to connect to MySQL from Perl.
@item
New portable benchmark suite with @code{DBD}, with test results from
@code{mSQL} 2.0.3, MySQL, PostgreSQL 6.2.1 and Solid server 2.2.
@item
@code{crash-me} is now included with the benchmarks; this is a Perl program
designed to find as many limits as possible in an SQL server. Tested with
@code{mSQL}, PostgreSQL, Solid and MySQL.
@item
Fixed bug in range-optimizer that crashed MySQL on some queries.
@item
Table and column name completion for @command{mysql} command-line tool, by Zeev
Suraski and Andi Gutmans.
@item
Added new command @code{REPLACE} that works like @code{INSERT} but
replaces conflicting records with the new record. @code{REPLACE INTO
TABLE ... SELECT ...} works also.
@item
Added new commands @code{CREATE DATABASE @var{db_name}} and @code{DROP
DATABASE @var{db_name}}.
@item
Added @code{RENAME} option to @code{ALTER TABLE}: @code{ALTER TABLE name
RENAME TO new_name}.
@item
@command{make_binary_distribution} now includes @file{libgcc.a} in
@file{libmysqlclient.a}. This should make linking work for people who don't
have @command{gcc}.
@item
Changed @code{net_write()} to @code{my_net_write()} because of a name
conflict with Sybase.
@item
@cindex ODBC compatibility
@cindex compatibility, with ODBC
New function @code{DAYOFWEEK()} compatible with ODBC.
@item
Stack checking and @command{bison} memory overrun checking to make MySQL
safer with weird queries.
@end itemize


@node News-3.21.14b, News-3.21.14a, News-3.21.15, News-3.21.x
@appendixsubsec Changes in release 3.21.14b

@itemize @bullet
@item
Fixed a couple of small @command{configure} problems on some platforms.
@end itemize


@node News-3.21.14a, News-3.21.13, News-3.21.14b, News-3.21.x
@appendixsubsec Changes in release 3.21.14a

@itemize @bullet
@item
Ported to SCO Openserver 5.0.4  with FSU Pthreads.
@item
HP-UX 10.20 should work.
@item
Added new function @code{DATE_FORMAT()}.
@item
Added @code{NOT IN}.
@item
Added automatic removal of 'ODBC function conversions': @code{@{fn now() @}}
@item
Handle ODBC 2.50.3 option flags.
@item
Fixed comparison of @code{DATE} and @code{TIME} values with @code{NULL}.
@item
Changed language name from germany to german to be consistent with
the other language names.
@item
Fixed sorting problem on functions returning a @code{FLOAT}. Previously, the
values were converted to @code{INT} values before sorting.
@item
Fixed slow sorting when sorting on key field when using
@code{@var{key_col}=@var{constant}}.
@item
Sorting on calculated @code{DOUBLE} values sorted on integer results instead.
@item
@command{mysql} no longer requires a database argument.
@item
Changed the place where @code{HAVING} should be. According to the SQL standards, it should
be after @code{GROUP BY} but before @code{ORDER BY}. MySQL 3.20
incorrectly had it last.
@item
Added Sybase command @code{USE database} to start using another database.
@item
Added automatic adjusting of number of connections and table cache size
if the maximum number of files that can be opened is less than needed.
This should fix that @command{mysqld} doesn't crash even if you haven't done a
@command{ulimit -n 256} before starting @command{mysqld}.
@item
Added lots of limit checks to make it safer when running with too little
memory or when doing weird queries.
@end itemize


@node News-3.21.13, News-3.21.12, News-3.21.14a, News-3.21.x
@appendixsubsec Changes in release 3.21.13

@itemize @bullet
@item
Added retry of interrupted reads and clearing of @code{errno}.
This makes Linux systems much safer!
@item
Fixed locking bug when using many aliases on the same table in the same
@code{SELECT}.
@item
Fixed bug with @code{LIKE} on number key.
@item
New error message so you can check whether the connection was lost while
the command was running or whether the connection was down from the start.
@item
Added @code{--table} option to @command{mysql} to print in table format.
Moved time and row information after query result.
Added automatic reconnect of lost connections.
@item
Added @code{!=} as a synonym for @code{<>}.
@item
Added function @code{VERSION()} to make easier logs.
@item
New multi-user test @file{tests/fork_test.pl} to put some strain on the
thread library.
@end itemize


@node News-3.21.12, News-3.21.11, News-3.21.13, News-3.21.x
@appendixsubsec Changes in release 3.21.12

@itemize @bullet
@item
Fixed @code{ftruncate()} call in MIT-pthreads. This made @command{isamchk}
destroy the @file{.ISM} files on (Free)BSD 2.x systems.
@item
Fixed broken @code{__P_} patch in MIT-pthreads.
@item
Many memory overrun checks. All string functions now return @code{NULL}
if the returned string should be longer than @code{max_allowed_packet} bytes.
@item
Changed the name of the @code{INTERVAL} type to @code{ENUM}, because
@code{INTERVAL} is used in standard SQL.
@item
In some cases, doing a @code{JOIN} + @code{GROUP} + @code{INTO OUTFILE},
the result wasn't grouped.
@item
@code{LIKE} with @code{'_'} as last character didn't work. Fixed.
@item
Added extended standard SQL @code{TRIM()} function.
@item
Added @code{CURTIME()}.
@item
Added @code{ENCRYPT()} function by Zeev Suraski.
@item
Fixed better @code{FOREIGN KEY} syntax skipping. New reserved words:
@code{MATCH}, @code{FULL}, @code{PARTIAL}.
@item
@command{mysqld} now allows IP number and hostname for the @code{--bind-address}
option.
@item
Added @code{SET CHARACTER SET cp1251_koi8} to enable conversions of
data to and from the @code{cp1251_koi8} character set.
@item
Lots of changes for Windows 95 port. In theory, this version should now be
easily portable to Windows 95.
@item
Changed the @code{CREATE COLUMN} syntax of @code{NOT NULL} columns to be after
the @code{DEFAULT} value, as specified in the standard SQL standard. This will
make @command{mysqldump} with @code{NOT NULL} and default values incompatible with
MySQL 3.20.
@item
Added many function name aliases so the functions can be used with
ODBC or standard SQL syntax.
@item
Fixed syntax of @code{ALTER TABLE @var{tbl_name} ALTER COLUMN @var{col_name} SET DEFAULT
NULL}.
@item
Added @code{CHAR} and @code{BIT} as synonyms for @code{CHAR(1)}.
@item
Fixed core dump when updating as a user who has only @code{SELECT} privilege.
@item
@code{INSERT ... SELECT ... GROUP BY} didn't work in some cases. An
@code{Invalid use of group function} error occurred.
@item
When using @code{LIMIT}, @code{SELECT} now always uses keys instead of record
scan.  This will give better performance on @code{SELECT} and a @code{WHERE}
that matches many rows.
@item
Added Russian error messages.
@end itemize


@node News-3.21.11, News-3.21.10, News-3.21.12, News-3.21.x
@appendixsubsec Changes in release 3.21.11

@itemize @bullet
@item
Configure changes.
@item
MySQL now works with the new thread library on BSD/OS 3.0.
@item
Added new group functions @code{BIT_OR()} and @code{BIT_AND()}.
@item
Added compatibility functions @code{CHECK} and @code{REFERENCES}.
@code{CHECK} is now a reserved word.
@item
Added @code{ALL} option to @code{GRANT} for better compatibility. (@code{GRANT}
is still a dummy function.)
@item
Added partly translated Dutch error messages.
@item
Fixed bug in @code{ORDER BY} and @code{GROUP BY} with @code{NULL} columns.
@item
Added function @code{LAST_INSERT_ID()} SQL function to retrieve last
@code{AUTO_INCREMENT}
value.  This is intended for clients to ODBC that can't use the
@code{mysql_insert_id()} API function, but can be used by any client.
@item
Added @code{--flush-logs} option to @command{mysqladmin}.
@item
Added command @code{STATUS} to @command{mysql}.
@item
Fixed problem with @code{ORDER BY}/@code{GROUP BY} because of bug in @command{gcc}.
@item
Fixed problem with @code{INSERT ... SELECT ... GROUP BY}.
@end itemize


@node News-3.21.10, News-3.21.9, News-3.21.11, News-3.21.x
@appendixsubsec Changes in release 3.21.10

@itemize @bullet
@item
New program @command{mysqlaccess}.
@item
@code{CREATE} now supports all ODBC types and the @code{mSQL} @code{TEXT} type.
All ODBC 2.5 functions are also supported (added @code{REPEAT}). This provides
better portability.
@item
Added text types @code{TINYTEXT}, @code{TEXT}, @code{MEDIUMTEXT} and
@code{LONGTEXT}.  These are actually @code{BLOB} types, but all searching is
done in case-insensitive fashion.
@item
All old @code{BLOB} fields are now @code{TEXT} fields.  This only
changes that all searching on strings is done in case-sensitive fashion.
You must do an @code{ALTER TABLE} and change the data type to @code{BLOB}
if you want to have tests done in case-sensitive fashion.
@item
Fixed some @command{configure} issues.
@item
Made the locking code a bit safer. Fixed very unlikely
deadlock situation.
@item
Fixed a couple of bugs in the range optimizer. Now the new range benchmark
@code{test-select} works.
@end itemize


@node News-3.21.9, News-3.21.8, News-3.21.10, News-3.21.x
@appendixsubsec Changes in release 3.21.9

@itemize @bullet
@item
Added @code{--enable-unix-socket=@var{pathname}} option to @command{configure}.
@item
Fixed a couple of portability problems with include files.
@item
Fixed bug in range calculation that could return empty
set when searching on multiple key with only one entry (very rare).
@item
Most things ported to FSU Pthreads, which should allow MySQL to
run on SCO. @xref{SCO}.
@end itemize


@node News-3.21.8, News-3.21.7, News-3.21.9, News-3.21.x
@appendixsubsec Changes in release 3.21.8

@itemize @bullet
@item
Works now in Solaris 2.6.
@item
Added handling of calculation of @code{SUM()} functions.
For example, you can now use @code{SUM(column)/COUNT(column)}.
@item
Added handling of trigometric functions:
@code{PI()}, @code{ACOS()}, @code{ASIN()}, @code{ATAN()}, @code{COS()},
@code{SIN()} and @code{TAN()}.
@item
New languages: Norwegian, Norwegian-ny and Portuguese.
@item
Fixed parameter bug in @code{net_print()} in @file{procedure.cc}.
@item
Fixed a couple of memory leaks.
@item
Now allow also the old @code{SELECT ... INTO OUTFILE} syntax.
@item
Fixed bug with @code{GROUP BY} and @code{SELECT} on key with many values.
@item
@code{mysql_fetch_lengths()} sometimes returned incorrect lengths when you used
@code{mysql_use_result()}. This affected at least some cases of
@command{mysqldump --quick}.
@item
Fixed bug in optimization of @code{WHERE const op field}.
@item
Fixed problem when sorting on @code{NULL} fields.
@item
Fixed a couple of 64-bit (Alpha) problems.
@item
Added @code{--pid-file=#} option to @command{mysqld}.
@item
Added date formatting to @code{FROM_UNIXTIME()}, originally by Zeev Suraski.
@item
Fixed bug in @code{BETWEEN} in range optimizer (did only test = of the first
argument).
@item
Added machine-dependent files for MIT-pthreads i386-SCO. There is probably
more to do to get this to work on SCO 3.5.
@end itemize


@node News-3.21.7, News-3.21.6, News-3.21.8, News-3.21.x
@appendixsubsec Changes in release 3.21.7

@itemize @bullet
@item
Changed @file{Makefile.am} to take advantage of Automake 1.2.
@item
Added the beginnings of a benchmark suite.
@item
Added more secure password handling.
@item
Added new client function @code{mysql_errno()}, to get the error number of
the error message. This makes error checking in the client much easier.
This makes the new server incompatible with the 3.20.x server when running
without @code{--old-protocol}.  The client code is backward-compatible.
More information can be found in the @file{README} file!
@item
Fixed some problems when using very long, illegal names.
@end itemize


@node News-3.21.6, News-3.21.5, News-3.21.7, News-3.21.x
@appendixsubsec Changes in release 3.21.6

@itemize @bullet
@item
Fixed more portability issues (incorrect @code{sigwait} and @code{sigset}
defines).
@item
@command{configure} should now be able to detect the last argument to
@code{accept()}.
@end itemize


@node News-3.21.5, News-3.21.4, News-3.21.6, News-3.21.x
@appendixsubsec Changes in release 3.21.5

@itemize @bullet
@item
Should now work with FreeBSD 3.0 if used with
@file{FreeBSD-3.0-libc_r-1.0.diff},
which can be found at @uref{http://dev.mysql.com/downloads/os-freebsd.html}.
@item
Added new @code{-O tmp_table_size=#} option to @command{mysqld}.
@item
New function @code{FROM_UNIXTIME(timestamp)} which returns a date string in
@code{'YYYY-MM-DD HH:MM:SS'} format.
@item
New function @code{SEC_TO_TIME(seconds)} which returns a string in
@code{'HH:MM:SS'} format.
@item
New function @code{SUBSTRING_INDEX()}, originally by Zeev Suraski.
@end itemize


@node News-3.21.4, News-3.21.3, News-3.21.5, News-3.21.x
@appendixsubsec Changes in release 3.21.4

@itemize @bullet
@item
Should now configure and compile on OSF/1 4.0 with the DEC compiler.
@item
Configuration and compilation on BSD/OS 3.0 works, but due to some bugs in
BSD/OS 3.0, @command{mysqld} doesn't work on it yet.
@item
Configuration and compilation on FreeBSD 3.0 works, but I couldn't get
@code{pthread_create} to work.
@end itemize


@node News-3.21.3, News-3.21.2, News-3.21.4, News-3.21.x
@appendixsubsec Changes in release 3.21.3

@itemize @bullet
@item
Added reverse check lookup of hostnames to get better security.
@item
Fixed some possible buffer overflows if filenames that are too long are used.
@item
@command{mysqld} doesn't accept hostnames that start with digits followed by a
@code{'.'}, because the hostname may look like an IP number.
@item
Added @code{--skip-networking} option to @command{mysqld}, to allow only socket
connections.  (This will not work with MIT-pthreads!)
@item
Added check of too long table names for alias.
@item
Added check whether database name is okay.
@item
Added check whether too long table names.
@item
Removed incorrect @code{free()} that killed the server on
@code{CREATE DATABASE} or @code{DROP DATABASE}.
@item
Changed some @command{mysqld} @code{-O} options to better names.
@item
Added @code{-O join_cache_size=#} option to @command{mysqld}.
@item
Added @code{-O max_join_size=#} option to @command{mysqld}, to be able to set a
limit how big queries (in this case big = slow) one should be able to handle
without specifying @code{SET SQL_BIG_SELECTS=1}.  A # = is about 10
examined records. The default is ``unlimited.''
@item
When comparing a @code{TIME}, @code{DATE}, @code{DATETIME} or @code{TIMESTAMP}
column to a constant, the constant is converted to a time value before
performing the comparison.
This will make it easier to get ODBC (particularly Access97) to work with
these types. It should also make dates easier to use and the comparisons
should be quicker than before.
@item
Applied patch from Jochen Wiedmann that allows @code{query()} in
@code{mysqlperl} to take a query with @code{\0} in it.
@item
Storing a timestamp with a two-digit year (@code{YYMMDD}) didn't work.
@item
Fix that timestamp wasn't automatically updated if set in an @code{UPDATE}
clause.
@item
Now the automatic timestamp field is the FIRST timestamp field.
@item
@code{SELECT * INTO OUTFILE}, which didn't correctly if the outfile already
existed.
@item
@command{mysql} now shows the thread ID when starting or doing a reconnect.
@item
Changed the default sort buffer size from 2MB to 1MB.
@end itemize


@node News-3.21.2, News-3.21.0, News-3.21.3, News-3.21.x
@appendixsubsec Changes in release 3.21.2

@itemize @bullet
@item
The range optimizer is coded, but only 85% tested. It can be enabled with
@code{--new}, but it crashes core a lot yet...
@item
More portable. Should compile on AIX and alpha-digital.
At least the @code{isam} library should be relatively 64-bit clean.
@item
New @command{isamchk} which can detect and fix more problems.
@item
New options for @code{isamlog}.
@item
Using new version of Automake.
@item
Many small portability changes (from the AIX and alpha-digital port)
Better checking of pthread(s) library.
@item
czech error messages by @email{snajdr@@pvt.net}.
@item
Decreased size of some buffers to get fewer problems on systems with little
memory.  Also added more checks to handle ``out of memory'' problems.
@item
@command{mysqladmin}: you can now do @command{mysqladmin kill 5,6,7,8} to kill
multiple threads.
@item
When the maximum connection limit is reached, one extra connection by a user
with the @strong{process_acl} privilege is granted.
@item
Added @code{-O backlog=#} option to @command{mysqld}.
@item
Increased maximum packet size from 512KB to 1024KB for client.
@item
Almost all of the function code is now tested in the internal test suite.
@item
@code{ALTER TABLE} now returns warnings from field conversions.
@item
Port changed to 3306 (got it reserved from ISI).
@item
Added a fix for Visual FoxBase so that any schema name from a table
specification is automatically removed.
@item
New function @code{ASCII()}.
@item
Removed function @code{BETWEEN(a,b,c)}. Use the standard SQL
syntax instead: @code{expr BETWEEN @var{expr} AND @var{expr}}.
@item
MySQL no longer has to use an extra temporary table when sorting
on functions or @code{SUM()} functions.
@item
Fixed bug that you couldn't use @var{tbl_name.field_name} in @code{UPDATE}.
@item
Fixed @code{SELECT DISTINCT} when using 'hidden group'. For example:
@example
mysql> SELECT DISTINCT MOD(some_field,10) FROM test
    ->        GROUP BY some_field;
@end example
Note: @code{some_field} is normally in the @code{SELECT} part. Standard SQL should
require it.
@end itemize


@node News-3.21.0,  , News-3.21.2, News-3.21.x
@appendixsubsec Changes in release 3.21.0

@itemize @bullet
@item
New reserved words used: @code{INTERVAL}, @code{EXPLAIN}, @code{READ},
@code{WRITE}, @code{BINARY}.
@item
Added ODBC function @code{CHAR(num,...)}.
@item
New operator @code{IN}. This uses a binary search to find a match.
@item
New command @code{LOCK TABLES @var{tbl_name} [AS @var{alias}] @{READ|WRITE@} ...}
@item
Added @code{--log-update} option to @command{mysqld}, to get a log suitable for
incremental updates.
@item
New command @code{EXPLAIN SELECT ...} to get information about how the
optimizer will do the join.
@item
For easier client code, the client should no longer use
@code{FIELD_TYPE_TINY_BLOB}, @code{FIELD_TYPE_MEDIUM_BLOB},
@code{FIELD_TYPE_LONG_BLOB} or @code{FIELD_TYPE_VAR_STRING} (as
previously returned by @code{mysql_list_fields}).  You should instead use only
@code{FIELD_TYPE_BLOB} or @code{FIELD_TYPE_STRING}.  If you want exact
types, you should use the command @code{SHOW FIELDS}.
@item
Added varbinary syntax: @code{0x######} which can be used as a string
(default) or a number.
@item
@code{FIELD_TYPE_CHAR} is renamed to @code{FIELD_TYPE_TINY}.
@item
Changed all fields to C++ classes.
@item
Removed FORM struct.
@item
Fields with @code{DEFAULT} values no longer need to be @code{NOT NULL}.
@item
New field types:
@table @code
@item ENUM
A string which can take only a couple of defined values. The value is
stored as a 1-3 byte number that is mapped automatically to a string.
This is sorted according to string positions!
@item SET
A string which may have one or many string values separated by ','.
The string is stored as a 1-, 2-, 3-, 4- or 8-byte number where each bit stands
for a specific set member.  This is sorted according to the unsigned value
of the stored packed number.
@end table
@item
Now all function calculation is done with @code{double} or @code{long long}.
This will provide the full 64-bit range with bit functions and fix some
conversions that previously could result in precision losses.  One should
avoid using @code{unsigned long long} columns with full 64-bit range
(numbers bigger than 9223372036854775807) because calculations are done
with @code{signed long long}.
@item
@code{ORDER BY} will now put @code{NULL} field values first. @code{GROUP BY}
will also work with @code{NULL} values.
@item
Full @code{WHERE} with expressions.
@item
New range optimizer that can resolve ranges when some keypart prefix is
constant. Example:
@example
mysql> SELECT * FROM @var{tbl_name}
    ->          WHERE @var{key_part_1}='@var{customer}'
    ->          AND @var{key_part_2}>=10 AND @var{key_part_2}<=10;
@end example
@end itemize


@node News-3.20.x, News-3.19.x, News-3.21.x, News
@appendixsec Changes in release 3.20.x

@cindex changes, version 3.20

MySQL 3.20 is quite old now, and should be avoided if possible.  This
information is kept here for historical purposes only.

Changes from 3.20.18 to 3.20.32b are not documented here because the
3.21 release branched here. And the relevant changes are also
documented as changes to the 3.21 version.

@menu
* News-3.20.18::                Changes in release 3.20.18
* News-3.20.17::                Changes in release 3.20.17
* News-3.20.16::                Changes in release 3.20.16
* News-3.20.15::                Changes in release 3.20.15
* News-3.20.14::                Changes in release 3.20.14
* News-3.20.13::                Changes in release 3.20.13
* News-3.20.11::                Changes in release 3.20.11
* News-3.20.10::                Changes in release 3.20.10
* News-3.20.9::                 Changes in release 3.20.9
* News-3.20.8::                 Changes in release 3.20.8
* News-3.20.7::                 Changes in release 3.20.7
* News-3.20.6::                 Changes in release 3.20.6
* News-3.20.3::                 Changes in release 3.20.3
* News-3.20.0::                 Changes in release 3.20.0
@end menu


@node News-3.20.18, News-3.20.17, News-3.20.x, News-3.20.x
@appendixsubsec Changes in release 3.20.18

@itemize @bullet
@item
Added @code{-p#} (remove @code{#} directories from path) to @code{isamlog}.
All files are written with a relative path from the database directory
Now @command{mysqld} shouldn't crash on shutdown when using the
@code{--log-isam} option.
@item
New @code{mysqlperl} version. It is now compatible with @code{msqlperl-0.63}.
@item
New @code{DBD} module available.
@item
Added group function @code{STD()} (standard deviation).
@item
The @command{mysqld} server is now compiled by default without debugging
information.  This will make the daemon smaller and faster.
@item
Now one usually only has to specify the @code{--basedir} option to
@command{mysqld}. All other paths are relative in a normal installation.
@item
@code{BLOB} columns sometimes contained garbage when used with a @code{SELECT}
on more than one table and @code{ORDER BY}.
@item
Fixed that calculations that are not in @code{GROUP BY} work as expected
(standard SQL extension).
Example:
@example
mysql> SELECT id,id+1 FROM table GROUP BY id;
@end example
@item
The test of using @code{MYSQL_PWD} was reversed. Now @code{MYSQL_PWD} is
enabled as default in the default release.
@item
Fixed conversion bug which caused @command{mysqld} to core dump with
Arithmetic error on SPARC-386.
@item
Added @code{--unbuffered} option to @command{mysql}, for new @command{mysqlaccess}.
@item
When using overlapping (unnecessary) keys and join over many tables,
the optimizer could get confused and return 0 records.
@end itemize


@node News-3.20.17, News-3.20.16, News-3.20.18, News-3.20.x
@appendixsubsec Changes in release 3.20.17

@itemize @bullet
@item
You can now use @code{BLOB} columns and the functions @code{IS NULL} and
@code{IS NOT NULL} in the @code{WHERE} clause.
@item
All communication packets and row buffers are now allocated dynamically
on demand. The default value of @code{max_allowed_packet} is now 64KB for
the server and 512KB for the client. This is mainly used to catch
incorrect packets that could trash all memory. The server limit may be
changed when it is started.
@item
Changed stack usage to use less memory.
@item
Changed @command{safe_mysqld} to check for running daemon.
@item
The @code{ELT()} function is renamed to @code{FIELD()}.  The new
@code{ELT()} function returns a value based on an index: @code{FIELD()}
is the inverse of @code{ELT()} Example: @code{ELT(2,"A","B","C")} returns
@code{"B"}. @code{FIELD("B","A","B","C")} returns @code{2}.
@item
@code{COUNT(field)}, where @code{field} could have a @code{NULL} value, now
works.
@item
A couple of bugs fixed in @code{SELECT ... GROUP BY}.
@item
Fixed memory overrun bug in @code{WHERE} with many unoptimizable brace levels.
@item
Fixed some small bugs in the grant code.
@item
If hostname isn't found by @code{get_hostname}, only the IP is checked.
Previously, you got @code{Access denied}.
@item
Inserts of timestamps with values didn't always work.
@item
@code{INSERT INTO ... SELECT ... WHERE} could give the error
@code{Duplicated field}.
@item
Added some tests to @command{safe_mysqld} to make it ``safer.''
@item
@code{LIKE} was case-sensitive in some places and case-insensitive in others.
Now @code{LIKE} is always case-insensitive.
@item
@file{mysql.cc}: Allow @code{'#'} anywhere on the line.
@item
New command @code{SET SQL_SELECT_LIMIT=#}. See the FAQ for more details.
@item
New version of the @command{mysqlaccess} script.
@item
Change @code{FROM_DAYS()} and @code{WEEKDAY()} to also take a full
@code{TIMESTAMP} or @code{DATETIME} as argument. Before they only took a
number of type @code{YYYYMMDD} or @code{YYMMDD}.
@item
Added new function @code{UNIX_TIMESTAMP(timestamp_column)}.
@end itemize


@node News-3.20.16, News-3.20.15, News-3.20.17, News-3.20.x
@appendixsubsec Changes in release 3.20.16

@itemize @bullet
@item
More changes in MIT-pthreads to get them safer. Fixed also some link
bugs at least in SunOS.
@item
Changed @command{mysqld} to work around a bug in MIT-pthreads. This makes multiple
small @code{SELECT} operations 20 times faster. Now @code{lock_test.pl} should
work.
@item
Added @code{mysql_FetchHash(handle)} to @code{mysqlperl}.
@item
The @command{mysqlbug} script is now distributed built to allow for reporting
bugs that appear during the build with it.
@item
Changed @file{libmysql.c} to prefer @code{getpwuid()} instead of
@code{cuserid()}.
@item
Fixed bug in @code{SELECT} optimizer when using many tables with the same
column used as key to different tables.
@item
Added new @code{latin2} and Russian @code{KOI8} character tables.
@item
Added support for a dummy @code{GRANT} command to satisfy Powerbuilder.
@end itemize


@node News-3.20.15, News-3.20.14, News-3.20.16, News-3.20.x
@appendixsubsec Changes in release 3.20.15

@itemize @bullet
@item
Fixed fatal bug @code{packets out of order} when using MIT-pthreads.
@item
Removed possible loop when a thread waits for command from client
and @code{fcntl()} fails. Thanks to Mike Bretz for finding this bug.
@item
Changed alarm loop in @file{mysqld.cc} because shutdown didn't always
succeed in Linux.
@item
Removed use of @code{termbits} from @file{mysql.cc}.  This conflicted with
@code{glibc} 2.0.
@item
Fixed some syntax errors for at least BSD and Linux.
@item
Fixed bug when doing a @code{SELECT} as superuser without a database.
@item
Fixed bug when doing @code{SELECT} with group calculation to outfile.
@end itemize


@node News-3.20.14, News-3.20.13, News-3.20.15, News-3.20.x
@appendixsubsec Changes in release 3.20.14

@itemize @bullet
@item
If one gives @code{-p} or @code{--password} option to @command{mysql} without
an argument, the user is solicited for the password from the tty.
@item
Added default password from @code{MYSQL_PWD} (by Elmar Haneke).
@item
Added command @code{kill} to @command{mysqladmin} to kill a specific
MySQL thread.
@item
Sometimes when doing a reconnect on a down connection this succeeded
first on second try.
@item
Fixed adding an @code{AUTO_INCREMENT} key with @code{ALTER_TABLE}.
@item
@code{AVG()} gave too small value on some @code{SELECT} statements with
@code{GROUP BY} and @code{ORDER BY}.
@item
Added new @code{DATETIME} type (by Giovanni Maruzzelli
@email{maruzz@@matrice.it}).
@item
Fixed that defining @code{DONT_USE_DEFAULT_FIELDS} works.
@item
Changed to use a thread to handle alarms instead of signals on Solaris to
avoid race conditions.
@item
Fixed default length of signed numbers. (George Harvey
@email{georgeh@@pinacl.co.uk}.)
@item
Allow anything for @code{CREATE INDEX}.
@item
Add prezeros when packing numbers to @code{DATE}, @code{TIME} and
@code{TIMESTAMP}.
@item
Fixed a bug in @code{OR} of multiple tables (gave empty set).
@item
Added many patches to MIT-pthreads. This fixes at least one lookup bug.
@end itemize


@node News-3.20.13, News-3.20.11, News-3.20.14, News-3.20.x
@appendixsubsec Changes in release 3.20.13

@itemize @bullet
@item
Added standard SQL @code{DATE} and @code{TIME} types.
@item
Fixed bug in @code{SELECT} with @code{AND}-@code{OR} levels.
@item
Added support for Slovenian characters. The @file{Contrib} directory contains
source and instructions for adding other character sets.
@item
Fixed bug with @code{LIMIT} and @code{ORDER BY}.
@item
Allow @code{ORDER BY} and @code{GROUP BY} on items that aren't in the
@code{SELECT} list.
(Thanks to Wim Bonis @email{bonis@@kiss.de}, for pointing this out.)
@item
Allow setting of timestamp values in @code{INSERT}.
@item
Fixed bug with @code{SELECT ... WHERE ... = NULL}.
@item
Added changes for @code{glibc} 2.0. To get @code{glibc} to work, you should
add the @file{gibc-2.0-sigwait-patch} before compiling @code{glibc}.
@item
Fixed bug in @code{ALTER TABLE} when changing a @code{NOT NULL} field to
allow @code{NULL} values.
@item
Added some standard SQL synonyms as field types to @code{CREATE TABLE}.
@code{CREATE TABLE} now allows @code{FLOAT(4)} and @code{FLOAT(8)} to mean
@code{FLOAT} and @code{DOUBLE}.
@item
New utility program @command{mysqlaccess} by @email{Yves.Carlier@@rug.ac.be}.
This program shows the access rights for a specific user and the grant
rows that determine this grant.
@item
Added @code{WHERE const op field} (by @email{bonis@@kiss.de}).
@end itemize


@node News-3.20.11, News-3.20.10, News-3.20.13, News-3.20.x
@appendixsubsec Changes in release 3.20.11

@itemize @bullet
@item
When using @code{SELECT ... INTO OUTFILE}, all temporary tables are @code{ISAM}
instead of @code{HEAP} to allow big dumps.
@item
Changed date functions to be string functions. This fixed some ``funny''
side effects when sorting on dates.
@item
Extended @code{ALTER TABLE} for standard SQL compliance.
@item
Some minor compatibility changes.
@item
Added @code{--port} and @code{--socket} options to all utility programs and
@command{mysqld}.
@item
Fixed MIT-pthreads @code{readdir_r()}. Now @command{mysqladmin create database}
and @command{mysqladmin drop database} should work.
@item
Changed MIT-pthreads to use our @code{tempnam()}. This should fix the ``sort
aborted'' bug.
@item
Added sync of records count in @code{sql_update}. This fixed slow updates
on first connection. (Thanks to Vaclav Bittner for the test.)
@end itemize


@node News-3.20.10, News-3.20.9, News-3.20.11, News-3.20.x
@appendixsubsec Changes in release 3.20.10

@itemize @bullet
@item
New insert type: @code{INSERT INTO ... SELECT ...}
@item
@code{MEDIUMBLOB} fixed.
@item
Fixed bug in @code{ALTER TABLE} and @code{BLOB} values.
@item
@code{SELECT ... INTO OUTFILE} now creates the file in the current
database directory.
@item
@code{DROP TABLE} now can take a list of tables.
@item
Oracle synonym @code{DESCRIBE} (@code{DESC}).
@item
Changes to @command{make_binary_distribution}.
@item
Added some comments to installation instructions about @command{configure}
C++ link test.
@item
Added @code{--without-perl} option to @command{configure}.
@item
Lots of small portability changes.
@end itemize


@node News-3.20.9, News-3.20.8, News-3.20.10, News-3.20.x
@appendixsubsec Changes in release 3.20.9

@itemize @bullet
@item
@code{ALTER TABLE} didn't copy null bit. As a result, fields that were allowed
to have @code{NULL} values were always @code{NULL}.
@item
@code{CREATE} didn't take numbers as @code{DEFAULT}.
@item
Some compatibility changes for SunOS.
@item
Removed @file{config.cache} from old distribution.
@end itemize


@node News-3.20.8, News-3.20.7, News-3.20.9, News-3.20.x
@appendixsubsec Changes in release 3.20.8

@itemize @bullet
@item
Fixed bug with @code{ALTER TABLE} and multiple-part keys.
@end itemize


@node News-3.20.7, News-3.20.6, News-3.20.8, News-3.20.x
@appendixsubsec Changes in release 3.20.7

@itemize @bullet
@item
New commands: @code{ALTER TABLE}, @code{SELECT ... INTO OUTFILE} and
@code{LOAD DATA INFILE}.
@item
New function: @code{NOW()}.
@item
Added new field @code{File_priv} to @code{mysql/user} table.
@item
New script @code{add_file_priv} which adds the new field @code{File_priv}
to the @code{user} table. This script must be executed if you want to
use the new @code{SELECT ... INTO} and @code{LOAD DATA INFILE ...} commands
with a version of MySQL earlier than 3.20.7.
@item
Fixed bug in locking code, which made @code{lock_test.pl} test fail.
@item
New files @file{NEW} and @file{BUGS}.
@item
Changed @file{select_test.c} and @file{insert_test.c} to include
@file{config.h}.
@item
Added @code{status} command to @command{mysqladmin} for short logging.
@item
Increased maximum number of keys to 16 and maximum number of key parts to 15.
@item
Use of sub keys. A key may now be a prefix of a string field.
@item
Added @code{-k} option to @command{mysqlshow}, to get key information for a table.
@item
Added long options to @command{mysqldump}.
@end itemize


@node News-3.20.6, News-3.20.3, News-3.20.7, News-3.20.x
@appendixsubsec Changes in release 3.20.6

@itemize @bullet
@item
Portable to more systems because of MIT-pthreads, which will
be used automatically if @command{configure} cannot find a @code{-lpthreads}
library.
@item
Added GNU-style long options to almost all programs. Test with
@code{@var{program} --help}.
@item
Some shared library support for Linux.
@item
The FAQ is now in @file{.texi} format and is available in @file{.html},
@file{.txt} and @file{.ps} formats.
@item
Added new SQL function @code{RAND([init])}.
@item
Changed @code{sql_lex} to handle @code{\0} unquoted, but the client can't send
the query through the C API, because it takes a str pointer.
You must use @code{mysql_real_query()} to send the query.
@item
Added API function @code{mysql_get_client_info()}.
@item
@command{mysqld} now uses the @code{N_MAX_KEY_LENGTH} from @file{nisam.h} as
the maximum allowable key length.
@item
The following now works:
@example
mysql> SELECT filter_nr,filter_nr FROM filter ORDER BY filter_nr;
@end example
Previously, this resulted in the error:
@code{Column: 'filter_nr' in order clause is ambiguous}.
@item
@command{mysql} now outputs @code{'\0'}, @code{'\t'}, @code{'\n'} and @code{'\\'}
when encountering ASCII 0, tab, newline, or @code{'\'} while writing
tab-separated output.
This is to allow printing of binary data in a portable format.
To get the old behavior, use @code{-r} (or @code{--raw}).
@item
Added german error messages (60 of 80 error messages translated).
@item
Added new API function @code{mysql_fetch_lengths(MYSQL_RES *)}, which
returns an array of column lengths (of type @code{uint}).
@item
Fixed bug with @code{IS NULL} in @code{WHERE} clause.
@item
Changed the optimizer a little to get better results when searching on a key
part.
@item
Added @code{SELECT} option @code{STRAIGHT_JOIN} to tell the optimizer that
it should join tables in the given order.
@item
Added support for comments starting with @code{'--'} in @file{mysql.cc}
(Postgres syntax).
@item
You can have @code{SELECT} expressions and table columns in a @code{SELECT}
which are not used in the group part. This makes it efficient to implement
lookups.  The column that is used should be a constant for each group because
the value is calculated only once for the first row that is found for a group.
@example
mysql> SELECT id,lookup.text,SUM(*) FROM test,lookup
    ->        WHERE test.id=lookup.id GROUP BY id;
@end example
@item
Fixed bug in @code{SUM(function)} (could cause a core dump).
@item
Changed @code{AUTO_INCREMENT} placement in the SQL query:
@example
INSERT INTO table (auto_field) VALUES (0);
@end example
inserted 0, but it should insert an @code{AUTO_INCREMENT} value.
@item
@file{mysqlshow.c}: Added number of records in table. Had to change the
client code a little to fix this.
@item
@command{mysql} now allows doubled @code{''} or @code{""} within strings for
embedded @code{'} or @code{"}.
@item
New math functions:
@code{EXP()}, @code{LOG()}, @code{SQRT()}, @code{ROUND()}, @code{CEILING()}.
@end itemize


@node News-3.20.3, News-3.20.0, News-3.20.6, News-3.20.x
@appendixsubsec Changes in release 3.20.3

@itemize @bullet
@item
The @command{configure} source now compiles a thread-free client library
@code{-lmysqlclient}. This is the only library that needs to be linked
with client applications.  When using the binary releases, you must
link with @code{-lmysql -lmysys -ldbug -lmystrings} as before.
@item
New @code{readline} library from @code{bash-2.0}.
@item
LOTS of small changes to @command{configure} and makefiles (and related source).
@item
It should now be possible to compile in another directory using
@code{VPATH}. Tested with GNU Make 3.75.
@item
@command{safe_mysqld} and @command{mysql.server} changed to be more compatible
between the source and the binary releases.
@item
@code{LIMIT} now takes one or two numeric arguments.
If one argument is given, it indicates the maximum number of rows in
a result. If two arguments are given, the first argument indicates the offset
of the first row to return, the second is the maximum number of rows.
With this it's easy to do a poor man's next page/previous page WWW
application.
@item
Changed name of SQL function @code{FIELDS()} to @code{ELT()}.
Changed SQL function @code{INTERVALL()} to @code{INTERVAL()}.
@item
Made @code{SHOW COLUMNS} a synonym for @code{SHOW FIELDS}.
Added compatibility syntax @code{FRIEND KEY} to @code{CREATE TABLE}. In
MySQL, this creates a non-unique key on the given columns.
@item
Added @code{CREATE INDEX} and @code{DROP INDEX} as compatibility functions.
In MySQL, @code{CREATE INDEX} only checks whether the index exists and
issues an error if it doesn't exist. @code{DROP INDEX} always succeeds.
@item
@file{mysqladmin.c}: added client version to version information.
@item
Fixed core dump bug in @code{sql_acl} (core on new connection).
@item
Removed @code{host}, @code{user} and @code{db} tables from database @code{test}
in the distribution.
@item
@code{FIELD_TYPE_CHAR} can now be signed (-128 to 127) or unsigned (0 to 255)
Previously, it was always unsigned.
@item
Bug fixes in @code{CONCAT()} and @code{WEEKDAY()}.
@item
Changed a lot of source to get @command{mysqld} to be compiled with SunPro
compiler.
@item
SQL functions must now have a @code{'('} immediately after the function name
(no intervening space).
For example, @code{'USER('} is regarded as beginning a function call, and
@code{'USER ('} is regarded as an identifier @code{USER} followed by a
@code{'('}, not as a function call.
@end itemize


@node News-3.20.0,  , News-3.20.3, News-3.20.x
@appendixsubsec Changes in release 3.20.0

@itemize @bullet
@item
The source distribution is done with @command{configure} and Automake.
It will make porting much easier.  The @code{readline} library is included
in the distribution.
@item
Separate client compilation:
the client code should be very easy to compile on systems which
don't have threads.
@item
The old Perl interface code is automatically compiled and installed.
Automatic compiling of @code{DBD} will follow when the new @code{DBD} code
is ported.
@item
Dynamic language support: @command{mysqld} can now be started with Swedish
or English (default) error messages.
@item
New functions: @code{INSERT()}, @code{RTRIM()}, @code{LTRIM()} and
@code{FORMAT()}.
@item
@command{mysqldump} now works correctly for all field types (even
@code{AUTO_INCREMENT}). The format for @code{SHOW FIELDS FROM @var{tbl_name}}
is changed so the @code{Type} column contains information suitable for
@code{CREATE TABLE}.  In previous releases, some @code{CREATE TABLE}
information had to be patched when re-creating tables.
@item
Some parser bugs from 3.19.5 (@code{BLOB} and @code{TIMESTAMP}) are corrected.
@code{TIMESTAMP} now returns different date information depending on its
create length.
@item
Changed parser to allow a database, table or field name to
start with a number or @code{'_'}.
@item
All old C code from Unireg changed to C++ and cleaned up. This makes
the daemon a little smaller and easier to understand.
@item
A lot of small bugfixes done.
@item
New @file{INSTALL} files (not final version) and some information regarding porting.
@end itemize


@node News-3.19.x, InnoDB change history, News-3.20.x, News
@appendixsec Changes in release 3.19.x

@cindex changes, version 3.19

MySQL 3.19 is quite old now, and should be avoided if possible.  This
information is kept here for historical purposes only.

@menu
* News-3.19.5::                 Changes in release 3.19.5
* News-3.19.4::                 Changes in release 3.19.4
* News-3.19.3::                 Changes in release 3.19.3
@end menu


@node News-3.19.5, News-3.19.4, News-3.19.x, News-3.19.x
@appendixsubsec Changes in release 3.19.5

@itemize @bullet
@item
Some new functions, some more optimization on joins.
@item
Should now compile clean on Linux (2.0.x).
@item
Added functions @code{DATABASE()}, @code{USER()}, @code{POW()},
@code{LOG10()} (needed for ODBC).
@item
In a @code{WHERE} with an @code{ORDER BY} on fields from only one table,
the table is now preferred as first table in a multi-join.
@item
@code{HAVING} and @code{IS NULL} or @code{IS NOT NULL} now works.
@item
A group on one column and a sort on a group function (@code{SUM()},
@code{AVG()}...) didn't work together. Fixed.
@item
@command{mysqldump}: Didn't send password to server.
@end itemize


@node News-3.19.4, News-3.19.3, News-3.19.5, News-3.19.x
@appendixsubsec Changes in release 3.19.4

@itemize @bullet
@item
Fixed horrible locking bug when inserting in one thread and reading
in another thread.
@item
Fixed one-off decimal bug.  1.00 was output as 1.0.
@item
Added attribute @code{'Locked'} to process list as information if a query is
locked by another query.
@item
Fixed full magic timestamp. Timestamp length may now be 14, 12, 10, 8, 6, 4
or 2 bytes.
@item
Sort on some numeric functions could sort incorrectly on last number.
@item
@code{IF(arg,syntax_error,syntax_error)} crashed.
@item
Added functions @code{CEILING()}, @code{ROUND()}, @code{EXP()}, @code{LOG()} and @code{SQRT()}.
@item
Enhanced @code{BETWEEN} to handle strings.
@end itemize


@node News-3.19.3,  , News-3.19.4, News-3.19.x
@appendixsubsec Changes in release 3.19.3

@itemize @bullet
@item
Fixed @code{SELECT} with grouping on @code{BLOB} columns not to return
incorrect @code{BLOB} info. Grouping, sorting and distinct on @code{BLOB}
columns will not yet work as
expected (probably it will group/sort by the first 7 characters in the
@code{BLOB}). Grouping on formulas with a fixed string size (use @code{MID()}
on a @code{BLOB}) should work.
@item
When doing a full join (no direct keys) on multiple tables with @code{BLOB}
fields, the @code{BLOB} was garbage on output.
@item
Fixed @code{DISTINCT} with calculated columns.
@end itemize


@node InnoDB change history, MySQL Cluster change history, News-3.19.x, News
@appendixsec @code{InnoDB} Change History

@strong{Starting from 4.0.22 and 4.1.5, all InnoDB changes are included in
the MySQL Change History, and this manual section is no longer separately
maintained.}

@menu
* InnoDB news-4.0.21::          MySQL/InnoDB-4.0.21, September 10, 2004
* InnoDB news-4.1.4::           MySQL/InnoDB-4.1.4, August 31, 2004
* InnoDB news-4.1.3::           MySQL/InnoDB-4.1.3, June 28, 2004
* InnoDB news-4.1.2::           MySQL/InnoDB-4.1.2, May 30, 2004
* InnoDB news-4.0.20::          MySQL/InnoDB-4.0.20, May 18, 2004
* InnoDB news-4.0.19::          MySQL/InnoDB-4.0.19, May 4, 2004
* InnoDB news-4.0.18::          MySQL/InnoDB-4.0.18, February 13, 2004
* InnoDB news-5.0.0::           MySQL/InnoDB-5.0.0, December 24, 2003
* InnoDB news-4.0.17::          MySQL/InnoDB-4.0.17, December 17, 2003
* InnoDB news-4.1.1::           MySQL/InnoDB-4.1.1, December 4, 2003
* InnoDB news-4.0.16::          MySQL/InnoDB-4.0.16, October 22, 2003
* InnoDB news-3.23.58::         MySQL/InnoDB-3.23.58, September 15, 2003
* InnoDB news-4.0.15::          MySQL/InnoDB-4.0.15, September 10, 2003
* InnoDB news-4.0.14::          MySQL/InnoDB-4.0.14, July 22, 2003
* InnoDB news-3.23.57::         MySQL/InnoDB-3.23.57, June 20, 2003 
* InnoDB news-4.0.13::          MySQL/InnoDB-4.0.13, May 20, 2003 
* InnoDB news-4.1.0::           MySQL/InnoDB-4.1.0, April 3, 2003 
* InnoDB news-3.23.56::         MySQL/InnoDB-3.23.56, March 17, 2003 
* InnoDB news-4.0.12::          MySQL/InnoDB-4.0.12, March 18, 2003 
* InnoDB news-4.0.11::          MySQL/InnoDB-4.0.11, February 25, 2003 
* InnoDB news-4.0.10::          MySQL/InnoDB-4.0.10, February 4, 2003 
* InnoDB news-3.23.55::         MySQL/InnoDB-3.23.55, January 24, 2003
* InnoDB news-4.0.9::           MySQL/InnoDB-4.0.9, January 14, 2003
* InnoDB news-4.0.8::           MySQL/InnoDB-4.0.8, January 7, 2003
* InnoDB news-4.0.7::           MySQL/InnoDB-4.0.7, December 26, 2002
* InnoDB news-4.0.6::           MySQL/InnoDB-4.0.6, December 19, 2002
* InnoDB news-3.23.54::         MySQL/InnoDB-3.23.54, December 12, 2002
* InnoDB news-4.0.5::           MySQL/InnoDB-4.0.5, November 18, 2002
* InnoDB news-3.23.53::         MySQL/InnoDB-3.23.53, October 9, 2002
* InnoDB news-4.0.4::           MySQL/InnoDB-4.0.4, October 2, 2002
* InnoDB news-4.0.3::           MySQL/InnoDB-4.0.3, August 28, 2002
* InnoDB news-3.23.52::         MySQL/InnoDB-3.23.52, August 16, 2002
* InnoDB news-4.0.2::           MySQL/InnoDB-4.0.2, July 10, 2002
* InnoDB news-3.23.51::         MySQL/InnoDB-3.23.51, June 12, 2002
* InnoDB news-3.23.50::         MySQL/InnoDB-3.23.50, April 23, 2002
* InnoDB news-3.23.49::         MySQL/InnoDB-3.23.49, February 17, 2002
* InnoDB news-3.23.48::         MySQL/InnoDB-3.23.48, February 9, 2002
* InnoDB news-3.23.47::         MySQL/InnoDB-3.23.47, December 28, 2001
* InnoDB news-4.0.1::           MySQL/InnoDB-4.0.1, December 23, 2001
* InnoDB news-3.23.46::         MySQL/InnoDB-3.23.46, November 30, 2001
* InnoDB news-3.23.45::         MySQL/InnoDB-3.23.45, November 23, 2001
* InnoDB news-3.23.44::         MySQL/InnoDB-3.23.44, November 2, 2001
* InnoDB news-3.23.43::         MySQL/InnoDB-3.23.43, October 4, 2001
* InnoDB news-3.23.42::         MySQL/InnoDB-3.23.42, September 9, 2001
* InnoDB news-3.23.41::         MySQL/InnoDB-3.23.41, August 13, 2001
* InnoDB news-3.23.40::         MySQL/InnoDB-3.23.40, July 16, 2001
* InnoDB news-3.23.39::         MySQL/InnoDB-3.23.39, June 13, 2001
* InnoDB news-3.23.38::         MySQL/InnoDB-3.23.38, May 12, 2001
@end menu



@node InnoDB news-4.0.21, InnoDB news-4.1.4, InnoDB change history, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.21, September 10, 2004

Functionality added or changed:

@itemize @bullet

@item
Renamed the @file{innodb.status.@var{<pid>}} files (created in the data
directory) to @file{innodb_status.@var{<pid>}}. This avoids
problems on filesystems that do not allow multiple periods in filenames.

@item
Added @code{innodb_status_file} system variable to @command{mysqld}
to control whether output from @code{SHOW INNODB STATUS} is written
to a @file{innodb_status.@var{<pid>}} file in the data directory.
By default, the file is not created.  To create it, start @command{mysqld}
with the @code{--innodb_status_file=1} option.

@item
Changes for NetWare to exit InnoDB gracefully on NetWare even in a case of
an assertion failure, instead of intentionally crashing the @code{`mysqld'}
server process. 

@end itemize

Bugs fixed:

@itemize @bullet

@item
Fixed a bug in @code{ON DELETE CASCADE} and @code{ON UPDATE CASCADE}
foreign key constraints: long chains of cascaded operations would cause
a stack overflow and crash the server.  Cascaded operations are now limited
to 15 levels.  (Bug #4446)

@item
Fixed a possible bug in @code{LOCK TABLES} introduced in
MySQL/InnoDB-4.0.19: The count of tables explicitly locked by a
transaction was incremented only after the locks were granted, but
decremented when the lock structures were destroyed.

@item
Fixed a bug in @code{UNLOCK TABLES} in @code{AUTOCOMMIT=0} mode,
introduced in MySQL/InnoDB-4.0.19: The memory allocated for some locks
acquired by the transaction could be deallocated before those locks were
released.  The bug can lead to crashes and memory corruption of the
buffer pool when the transaction acquires a large number of locks (table
locks or row-level locks).

@item
Increment the InnoDB watchdog timeout during @code{CHECK TABLE}. A
long-running @code{CHECK TABLE} would cause InnoDB to
complain about a 'long semaphore wait', and crash the server,
if a query had to wait more than 600 seconds behind that
@code{CHECK TABLE} operation.
(Bug #2694)

@item
If you configure @code{innodb_additional_mem_pool_size} so small that InnoDB
memory allocation spills over from it, then every 4 billionth spill may
cause memory corruption. A symptom is a printout like below in the
@file{.err} log.
The workaround is to make
@code{innodb_additional_mem_pool_size} big enough to hold all memory
allocation.
Use @code{SHOW INNODB STATUS} to determine that there is plenty of free space
available in the additional mem pool, and the total allocated memory stays
rather constant.
@example
InnoDB: Error: Mem area size is 0. Possibly a memory overrun of the
InnoDB: previous allocated area!
InnoDB: Apparent memory corruption: mem dump  len 500; hex
@end example

@item
The special meaning of the table names @code{innodb_monitor},
@code{innodb_lock_monitor}, @code{innodb_tablespace_monitor},
@code{innodb_table_monitor}, and @code{innodb_validate} in
@code{CREATE TABLE} and @code{DROP TABLE} statements was accidentally
removed in MySQL/InnoDB-4.0.19.  The diagnostic functions attached
to these special table names (@pxref{InnoDB Monitor}) are accessible
again in MySQL/InnoDB-4.0.21.

@item
When the private SQL parser of InnoDB was modified in
MySQL/InnoDB-4.0.19 in order to allow the use of the apostrophe (@samp{'})
in table and column names, the fix relied on a previously unused function
@code{mem_realloc()}, whose implementation was incorrect.  As a
result, InnoDB can incorrectly parse column and table names as the
empty string.  The InnoDB @code{realloc()} implementation has been
corrected in MySQL/InnoDB-4.0.21.

@item
Fixed a glitch introduced in 4.0.18 and 4.1.2: in @code{SHOW TABLE STATUS}
InnoDB systematically overestimated the row count by 1 if the
table fit on a single 16 kB data page.

@item
InnoDB created temporary files with the C library function @code{tmpfile()}.
On Windows, the files would be created in the root directory of the current
file system.  To correct this behavior, the invocations of @code{tmpfile()}
were replaced with code that uses the function @code{create_temp_file()} in
the MySQL portability layer.  (Bug #3998)

@item
If @code{ALTER TABLE ... DROP FOREIGN KEY ...} fails because of a wrong
constraint name, return a table handler error number 150 instead of 152.

@item
If there was little file I/O in InnoDB, but the insert buffer was
used, it could happen that 'Pending normal aio reads' was bigger than 0,
but the I/O handler thread did not get waken up in 600 seconds.
This resulted in a hang, and crashing of InnoDB.

@item
If we @code{RENAME}d a table, InnoDB forgot to load the @code{FOREIGN KEY}
constraints that reference the new table name, and forgot to check that
they are compatible with the table.

@end itemize



@node InnoDB news-4.1.4, InnoDB news-4.1.3, InnoDB news-4.0.21, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.1.4, August 31, 2004

Functionality added or changed:

@itemize @bullet
@item
@strong{Important:}
Made internal representation of @code{TIMESTAMP} values in @code{InnoDB} in
4.1 to be the same as in 4.0. This difference resulted in incorrect datetime
values in @code{TIMESTAMP} columns in @code{InnoDB} tables after an upgrade
from 4.0 to 4.1. (Bug #4492)
@strong{Warning: extra steps during upgrade required!}
This means that if you are upgrading from 4.1.x,
where x <= 3, to 4.1.4
you should use @code{mysqldump} for saving and then restoring your
@code{InnoDB} tables with @code{TIMESTAMP} columns. No conversion
is needed if you upgrade from 3.23 or 4.0 to 4.1.4 or later.

@item
Added a new startup option @code{innodb_locks_unsafe_for_binlog}. This
option forces @code{InnoDB} not to use next-key locking in searches and
index scans.

@item
Added @code{innodb_status_file} system variable to @command{mysqld}
to control whether output from @code{SHOW INNODB STATUS} is written
to a @file{innodb_status.@var{<pid>}} file in the data directory.
By default, the file is not created.  To create it, start @command{mysqld}
with the @code{--innodb_status_file=1} option.

@item
Changes for NetWare to exit InnoDB gracefully on NetWare
even in a case of an assertion failure, instead of intentionally crashing the
@command{mysqld} server process.

@item
'Gap' type row locks without
the @code{LOCK_INSERT_INTENTION} flag do not need to wait for
anything. This is because different users can have conflicting lock types
on gaps. This change reduces unnecessary deadlocks.

@end itemize

Bugs fixed:

@itemize @bullet
@item
Fixed a bug in @code{ON DELETE CASCADE} and @code{ON UPDATE CASCADE}
foreign key constraints: long chains of cascaded operations would cause
a stack overflow and crash the server.  Cascaded operations are now limited
to 15 levels.  (Bug #4446)

@item
Increment the InnoDB watchdog timeout during @code{CHECK TABLE}.  (Bug #2694)

@item
If you configure @code{innodb_additional_mem_pool_size} so small that InnoDB
memory allocation spills over from it, then every 4 billionth spill may
cause memory corruption. A symptom is a printout like below in the
@file{.err} log.
@example
InnoDB: Error: Mem area size is 0. Possibly a memory overrun of the
InnoDB: previous allocated area!
InnoDB: Apparent memory corruption: mem dump  len 500; hex
@end example

@item
Fixed a glitch introduced in 4.0.18 and 4.1.2: in @code{SHOW TABLE STATUS}
InnoDB systematically overestimated the row count by 1 if the
table fit on a single 16 kB data page.

@item
InnoDB created temporary files with the C library function @code{tmpfile()}.
On Windows, the files would be created in the root directory of the current
file system.  To correct this behavior, the invocations of @code{tmpfile()}
were replaced with code that uses the function @code{create_temp_file()} in
the MySQL portability layer.  (Bug #3998)

@item
If we @code{RENAME}d a table, InnoDB forgot to load the foreign key
constraints that reference the new table name, and forgot to check
that they are compatible with the table.

@item
If there was little file I/O in InnoDB, but the insert buffer was
used, it could happen that 'Pending normal aio reads' was bigger than 0,
but the I/O handler thread did not get waken up in 600 seconds.
This resulted in a hang, and an intentional crashing of @command{mysqld}.
@end itemize

@node InnoDB news-4.1.3, InnoDB news-4.1.2, InnoDB news-4.1.4, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.1.3, June 28, 2004

Functionality added or changed:
@itemize @bullet

@item
@strong{Important:}
Starting from MySQL 4.1.3, @code{InnoDB} uses the same character
set comparison functions as MySQL for non-@code{latin1_swedish_ci}
character strings that are not @code{BINARY}.  This changes the sorting
order of space and characters < ASCII(32) in those character sets.
For @code{latin1_swedish_ci} character strings and @code{BINARY} strings,
@code{InnoDB} uses its own pad-spaces-at-end comparison method, which stays
unchanged.  If you have an @code{InnoDB} table created with MySQL 4.1.2 or
earlier, with an index on a non-@code{latin1} character set (in the case
of 4.1.0 and 4.1.1 with any character set) @code{CHAR}/@code{VARCHAR}/or
@code{TEXT} column that is not @code{BINARY} but may contain characters <
ASCII(32), then you should do @code{ALTER TABLE} or @code{OPTIMIZE} table on
it to @strong{regenerate the index, after upgrading to MySQL 4.1.3 or later}.

@item
@code{OPTIMIZE TABLE} for @code{InnoDB} tables is now mapped to @code{ALTER
TABLE} rather than to @code{ANALYZE TABLE}.

@item
Added an interface for storing the binlog offset in the InnoDB log and
flushing the log.
@end itemize

Bugs fixed:

@itemize @bullet

@item
The @strong{critical bug in 4.1.2} (crash recovery skipping all @file{.ibd}
files if you specify @code{innodb_file_per_table} on Unix) has been fixed.
The bug was a combination of two bugs.  Crash recovery ignored the files,
because the attempt to lock them in the wrong mode failed.  From now on,
locks will only be obtained for regular files opened in read/write mode,
and crash recovery will stop if an @file{.ibd} file for a table exists
in a database directory but is unaccessible.

@item
Do not remember the original @code{select_lock_type} inside @code{LOCK TABLES}.
(Bug #4047)

@item
The special meaning of the table names @code{innodb_monitor},
@code{innodb_lock_monitor}, @code{innodb_tablespace_monitor},
@code{innodb_table_monitor}, and @code{innodb_validate} in
@code{CREATE TABLE} and @code{DROP TABLE} statements was accidentally
removed in MySQL/InnoDB-4.1.2.  The diagnostic functions attached
to these special table names (@pxref{InnoDB Monitor}) are accessible
again in MySQL/InnoDB-4.1.3.

@item
When the private SQL parser of InnoDB was modified in
MySQL/InnoDB-4.0.19 in order to allow the use of the apostrophe (@samp{'})
in table and column names, the fix relied on a previously unused function
@code{mem_realloc()}, whose implementation was incorrect.  As a
result, InnoDB can incorrectly parse column and table names as the
empty string.  The InnoDB @code{realloc()} implementation has been
corrected in MySQL/InnoDB-4.1.3.

@item
In a clean-up of MySQL/InnoDB-4.1.2, the code for invalidating the
query cache was broken.  Now the query cache should be correctly
invalidated for tables affected by @code{ON UPDATE CASCADE} or
@code{ON DELETE CASCADE} constraints.

@item
Fixed a bug: in @code{LIKE 'abc%'}, the @code{'%'} did not match
the empty string if the character set was not
@code{latin1_swedish_ci}. This bug was fixed by changing the sorting
order in these character sets. See the above note about data conversion
in 4.1.3.

@end itemize

@node InnoDB news-4.1.2, InnoDB news-4.0.20, InnoDB news-4.1.3, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.1.2, May 30, 2004

@strong{NOTE: CRITICAL BUG in 4.1.2 if you specify innodb_file_per_table in
@file{my.cnf} on Unix.} In crash recovery InnoDB will skip the crash recovery
for all @file{.ibd} files and those tables become CORRUPT! The symptom is
a message
@code{Unable to lock ...ibd with lock 1, error: 9: fcntl: Bad file descriptor}
in the @file{.err} log in crash recovery.

Functionality added or changed:

@itemize @bullet
@item
Support multiple character sets.  Note that tables created in other
collations than @code{latin1_swedish_ci} cannot be accessed in
MySQL/InnoDB 4.0.

@item
Automatically create a suitable index on a @code{FOREIGN KEY}, if the user does
not create one. Removes most of the cases of @code{Error 1005 (errno 150)}
in table creation.

@item
Do not assert in @file{log0log.c}, line 856 if @code{ib_logfiles} are
too small for @code{innodb_thread_concurrency}.  Instead, print
instructions how to adjust @file{my.cnf} and call @code{exit(1)}.

@item
If MySQL tries to @code{SELECT} from an InnoDB table without setting
any table locks, print a descriptive error message and assert; some
subquery bugs were of this type.

@item
Allow a key part length in InnoDB to be up to 3,500 bytes; this is
needed so that you can create an index on a column with 255 UTF-8
characters.

@item
All new features from InnoDB-4.0.17, InnoDB-4.0.18, InnoDB-4.0.19 and InnoDB-4.0.20.
@end itemize

Bugs fixed:

@itemize @bullet
@item
If you configure @code{innodb_additional_mem_pool_size} so small that InnoDB
memory allocation spills over from it, then every 4 billionth spill may
cause memory corruption. A symptom is a printout like below in the
@file{.err} log.
@example
InnoDB: Error: Mem area size is 0. Possibly a memory overrun of the
InnoDB: previous allocated area!
InnoDB: Apparent memory corruption: mem dump  len 500; hex
@end example

@item
Improved portability to 64-bit platforms, especially Win64.

@item
Fixed an assertion failure when a purge of a table was not possible
because of missing @file{.ibd} file.

@item
Fixed a bug: do not retrieve all columns in a table if we only need
the 'ref' of the row (usually, the @code{PRIMARY KEY}) to calculate an
@code{ORDER BY}. (Bug #1942)

@item
On Unix-like systems, obtain an exclusive advisory lock on InnoDB
files, to prevent corruption when multiple instances of MySQL are
running on the same set of data files.  The Windows version of InnoDB
already took a mandatory lock on the files. (Bug #3608)

@item
Added a missing space to the output format of @code{SHOW INNODB STATUS};
reported by Jocelyn Fournier.

@item
All bugfixes from InnoDB-4.0.17, InnoDB-4.0.18, InnoDB-4.0.19 and InnoDB-4.0.20.
@end itemize


@node InnoDB news-4.0.20, InnoDB news-4.0.19, InnoDB news-4.1.2, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.20, May 18, 2004

Bugs fixed:

@itemize @bullet
@item
Apostrophe characters now are recognized by the internal @code{InnoDB}
parser and can be used within quoted table and column identifiers in
@code{FOREIGN KEY} clauses.

@item
Make @code{LOCK TABLE} aware of @code{InnoDB} row-level locks and
@code{InnoDB} aware of locks set with @code{LOCK TABLE}. (Bug #3299)

@item
Fixed race conditions in @code{SHOW INNODB STATUS}. (Bug #3596)
@end itemize


@node InnoDB news-4.0.19, InnoDB news-4.0.18, InnoDB news-4.0.20, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.19, May 4, 2004

Functionality added or changed:

@itemize @bullet
@item
Better error message when the server has to crash because the buffer
pool is exhausted by the lock table or the adaptive hash index.

@item
Print always the count of pending @code{pread()} and @code{pwrite()}
calls if there is a long semaphore wait.

@item
Improve space utilization when rows of 1,500 to 8,000 bytes are
inserted in the order of the primary key.

@item
Remove potential buffer overflow errors by sending diagnostic output to
stderr or files instead of stdout or fixed-size memory buffers.  As a
side effect, the output of @code{SHOW INNODB STATUS} will be written
to a file @file{@var{<datadir>}/innodb.status.@var{<pid>}} every 15
seconds.
@end itemize

Bugs fixed:

@itemize @bullet
@item
Fixed a bug: @code{DROP DATABASE} did not work if @code{FOREIGN KEY}
references were defined within the database. (Bug #3058)

@item
Remove unnecessary files, functions and variables.  Many of these were
needed in the standalone version of InnoDB.  Remove debug functions
and variables from non-debug build.

@item
Add diagnostic code to analyze an assertion failure in ha_innodb.cc on line
2020 reported by a user. (Bug #2903)

@item
Fixed a bug: in a @code{FOREIGN KEY}, @code{ON UPDATE CASCADE}
was not triggered if the update changed a string to another value
identical in alphabetical ordering, for example, @samp{abc} -> @samp{aBc}.

@item
Protect the reading of the latest foreign key error explanation buffer
with a mutex; in theory, a race condition could cause @code{SHOW
INNODB STATUS} print garbage characters after the error info.

@item
Fixed a bug: The row count and key cardinality estimate was grossly
too small if each clustered index page only contained one record.

@item
Parse @code{CONSTRAINT FOREIGN KEY} correctly. (Bug #3332)

@item
Fixed a memory corruption bug on Windows.  The bug is present in all
InnoDB versions in Windows, but it depends on how the linker places a
static array in @code{srv0srv.c}, whether the bug shows itself. 4
bytes were overwritten with a pointer to a statically allocated
string @samp{get windows aio return value}.

@item
Fix a glitch reported by Philippe Lewicki on the general mailing list:
do not print a warning to the @file{.err} log if @code{read_key} fails
with a lock wait timeout error 146.

@item
Allow quotes to be embedded in strings in the private SQL parser of
InnoDB, so that @samp{'} can be used in InnoDB table and column names.
Display quotes within identifiers properly.

@item
Debugging: Allow @code{UNIV_SYNC_DEBUG} to be disabled while
@code{UNIV_DEBUG} is enabled.

@item
Debugging: Handle magic numbers in a more consistent way.
@end itemize


@node InnoDB news-4.0.18, InnoDB news-5.0.0, InnoDB news-4.0.19, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.18, February 13, 2004

@itemize @bullet
@item
Do not allow dropping a table referenced by a @code{FOREIGN KEY}
constraint, unless the user does @code{SET FOREIGN_KEY_CHECKS=0}.
The error message here is somewhat misleading
``Cannot delete or update a parent row...'', and must be changed in a
future version 4.1.x.
@item
Make @code{InnoDB} to remember the @code{CONSTRAINT} name given by a user for
a @code{FOREIGN KEY}.
@item
Change the print format of @code{FOREIGN KEY} constraints spanning
multiple databases to @code{`@var{db_name}`.`@var{tbl_name}`}. But when
parsing them, we must also accept @code{`@var{db_name}.@var{tbl_name}`},
because that was the output format in < 4.0.18.
@item
An optimization in locking: If @code{AUTOCOMMIT=1}, then we do not
need to make a plain @code{SELECT} set shared locks even on the
@code{SERIALIZABLE} isolation level, because we know that the
transaction is read-only. A read-only transaction can always be
performed on the @code{REPEATABLE READ} level, and that does not
endanger the serializability.
@item
Implement an automatic downgrade from >= 4.1.1 -> 4.0.18 if the user
has not created tables in @file{.ibd} files or used other 4.1.x
features. @strong{Consult} the manual section on
@strong{multiple tablespaces} carefully if you want to downgrade!
@item
Fixed a bug: MySQL should not allow @code{REPLACE} to internally
perform an @code{UPDATE} if the table is referenced by a
@code{FOREIGN KEY}. The MySQL manual states that @code{REPLACE} must
resolve a duplicate-key error semantically with
@code{DELETE}(s) + @code{INSERT}, and not by an @code{UPDATE}.
In versions < 4.0.18 and < 4.1.2, MySQL could resolve a duplicate key
conflict in @code{REPLACE} by doing an @code{UPDATE} on the existing
row, and @code{FOREIGN KEY} checks could behave in a semantically
wrong way. (Bug #2418)
@item
Fixed a bug: generate @code{FOREIGN KEY} constraint identifiers
locally for each table, in the form
@var{db_name/tbl_name_ibfk_number}. If the user gives the
constraint name explicitly, then remember it. These changes should
ensure that foreign key id's in a slave are the same as in the master,
and @code{DROP FOREIGN KEY} does not break replication. (Bug #2167)
@item
Fixed a bug: allow quoting of identifiers in InnoDB's
@code{FOREIGN KEY} definitions with a backtick (`) and a double quote
("). You can now use also spaces in table and column names, if you
quote the identifiers. (Bug #1725, Bug #2424)
@item
Fixed a bug: @code{FOREIGN KEY ... ON UPDATE/DELETE NO ACTION} must
check the foreign key constraint, not ignore it. Since we do not have
deferred constraints in @code{InnoDB}, this bugfix makes @code{InnoDB} to check
@code{NO ACTION} constraints immediately, like it checks
@code{RESTRICT} constraints.
@item
Fixed a bug: @code{InnoDB} crashed in @code{RENAME TABLE} if 
@var{db_name.tbl_name} is shorter than 5 characters.
(Bug #2689)
@item
Fixed a bug: in @code{SHOW TABLE STATUS}, @code{InnoDB} row count and index
cardinality estimates wrapped around at 512 million in 32-bit
computers. Note that unless MySQL is compiled with the
@code{BIG_TABLES} option, they will still wrap around at 4 billion.
@item
Fixed a bug: If there was a @code{UNIQUE} secondary index, and
@code{NULL} values in that unique index, then with the
@code{IS NULL} predicate, @code{InnoDB} returned only the first matching row,
though there can be many.
This bug was introduced in 4.0.16. (Bug #2483)
@end itemize


@node InnoDB news-5.0.0, InnoDB news-4.0.17, InnoDB news-4.0.18, InnoDB change history
@appendixsubsec MySQL/InnoDB-5.0.0, December 24, 2003

@itemize @bullet
@item
@strong{Important note:} If you upgrade to MySQL 4.1.1 or higher, it is
difficult to downgrade back to 4.0 or 4.1.0! That is because, for earlier
versions, @code{InnoDB} is not aware of multiple tablespaces.
@item
@code{InnoDB} in 5.0.0 is essentially the same as InnoDB-4.1.1 with the
bugfixes of InnoDB-4.0.17 included.
@end itemize


@node InnoDB news-4.0.17, InnoDB news-4.1.1, InnoDB news-5.0.0, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.17, December 17, 2003

@itemize @bullet
@item
Fixed a bug: If you created a column prefix secondary index and updated it
so that the last characters in the column prefix were spaces, @code{InnoDB} would
assert in @file{row0upd.c}, line 713. The same assertion failed if you
updated a column in an ordinary secondary index so that the new value was
alphabetically equivalent, but had a different length. This could happen,
for example, in the UTF8 character set if you updated a letter to its
accented or umlaut form. 
@item
Fixed a bug: @code{InnoDB} could think that a secondary index record was not
locked though it had been updated to an alphabetically equivalent value,
for example, 'abc' -> 'aBc'. 
@item
Fixed a bug: If you updated a secondary index column to an alphabetically
equivalent value, and rolled back your update, @code{InnoDB} failed to restore
the field in the secondary index to its original value. 
@item
There are still several outstanding non-critical bugs reported in the MySQL
bugs database. Their fixing has been delayed, because resources were
allocated to the 4.1.1 release.
@end itemize

@node InnoDB news-4.1.1, InnoDB news-4.0.16, InnoDB news-4.0.17, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.1.1, December 4, 2003

@itemize @bullet
@item
@strong{Important note:} If you upgrade to MySQL 4.1.1 or higher, you
cannot downgrade to a version lower than 4.1.1 any more! That is because,
for earlier versions, @code{InnoDB} is not aware of multiple tablespaces.
@item
Multiple tablespaces now available for @code{InnoDB}. You can store each
@code{InnoDB}
type table and its indexes into a separate @file{.ibd} file into a
MySQL database directory, into the same directory where the
@file{.frm} file is stored.
@item
The MySQL query cache now works for @code{InnoDB} tables also if
@code{AUTOCOMMIT=0}, or the statements are enclosed inside
@code{BEGIN ... COMMIT}. 
@item
Reduced @code{InnoDB} memory consumption by a few megabytes if one sets the buffer
pool size < 8MB. 
@item
You can use raw disk partitions also in Windows. 
@end itemize

@node InnoDB news-4.0.16, InnoDB news-3.23.58, InnoDB news-4.1.1, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.16, October 22, 2003

@itemize @bullet
@item
Fixed a bug: in contrary to what was said in the manual, in a locking
read @code{InnoDB} set two record locks if a unique exact match search
condition was used on a multi-column unique key. For a single column
unique key it worked right. 
@item
Fixed a bug: If you used the rename trick
@code{#sql... -> rsql...} to recover a temporary table, @code{InnoDB} asserted in
@code{row_mysql_lock_data_dictionary()}.
@item 
There are several outstanding non-critical bugs reported in the MySQL bugs
database. Their fixing has been delayed, because resources are allocated
to the upcoming 4.1.1 release. 
@end itemize

@node InnoDB news-3.23.58, InnoDB news-4.0.15, InnoDB news-4.0.16, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.58, September 15, 2003

@itemize @bullet
@item
Fixed a bug: @code{InnoDB} could make the index page directory corrupt in the
first B-tree page splits after @command{mysqld} startup. A symptom would be
an assertion failure in @file{page0page.c}, in function
@code{page_dir_find_slot()}.
@item
Fixed a bug: @code{InnoDB} could in rare cases return an extraneous row if a
rollback, purge, and a @code{SELECT} coincided.
@item 
Fixed a possible hang over the @file{btr0sea.c} latch if
@code{SELECT} was used inside @code{LOCK TABLES}.
@item 
Fixed a bug: If a single @code{DELETE} statement first managed to delete
some rows and then failed in a @code{FOREIGN KEY} error or a
@code{Table is full} error, MySQL did not roll back the whole SQL statement
as it should. 
@end itemize

@node InnoDB news-4.0.15, InnoDB news-4.0.14, InnoDB news-3.23.58, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.15, September 10, 2003

@itemize @bullet
@item
Fixed a bug: If you updated a row so that the 8000 byte maximum length
(without @code{BLOB} and @code{TEXT}) was exceeded, @code{InnoDB} simply removed
the record from the clustered index. In a similar insert, @code{InnoDB} would
leak reserved file space extents, which would only be freed at the next
@command{mysqld} startup. 
@item
Fixed a bug: If you used big @code{BLOB} values, and your log files were
relatively small, @code{InnoDB} could in a big @code{BLOB} operation temporarily
write over the log produced after the latest checkpoint. If @code{InnoDB}
would crash at that moment, then the crash recovery would fail,
because @code{InnoDB} would not be able to scan the log even up to the
latest checkpoint. Starting from this version, @code{InnoDB} tries to ensure
the latest checkpoint is young enough. If that is not possible,
@code{InnoDB} prints a warning to the @file{.err} log of MySQL and advises
you to make the log files bigger. 
@item
Fixed a bug: setting @code{innodb_fast_shutdown=0} had no effect. 
@item
Fixed a bug introduced in 4.0.13: If a @code{CREATE TABLE} ended in a
comment, that could cause a memory overrun. 
@item
Fixed a bug: If @code{InnoDB} printed @code{Operating system error number .. in
a file operation} to the @file{.err} log in Windows, the error number
explanation was wrong. Workaround: look at section 13.2 of
http://www.innodb.com/ibman.php about Windows
error numbers.
@item
Fixed a bug: If you created a column prefix
@code{PRIMARY KEY} like in @code{t(a CHAR(200), PRIMARY KEY (a(10)))}
on a fixed-length @code{CHAR} column, @code{InnoDB} would crash even in a
simple @code{SELECT}. A @code{CHECK TABLE} would report the table as
corrupt, also in the case where the created key was not @code{PRIMARY}. 
@end itemize

@node InnoDB news-4.0.14, InnoDB news-3.23.57, InnoDB news-4.0.15, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.14, July 22, 2003

@itemize bullet
@item
@code{InnoDB} now supports the @code{SAVEPOINT} and @code{ROLLBACK TO SAVEPOINT}
SQL statements. See http://www.innodb.com/ibman.php#Savepoints for
the syntax.
@item
You can now create column prefix keys like in
@code{CREATE TABLE t (a BLOB, INDEX (a(10)))}.
@item
You can also use @code{O_DIRECT} as the @code{innodb_flush_method} on the
latest versions of Linux and FreeBSD. Beware of possible bugs in those
operating systems, though. 
@item
Fixed the checksum calculation of data pages. Previously most OS file
system corruption went unnoticed. Note that if you downgrade from
version >= 4.0.14 to an earlier version < 4.0.14 then in the first
startup(s) @code{InnoDB} will print warnings: 
@example
InnoDB: Warning: An inconsistent page in the doublewrite buffer
InnoDB: space id 2552202359 page number 8245, 127'th page in dblwr buf.
@end example
but that is not dangerous and can be ignored. 
@item
Modified the buffer pool replacement algorithm so that it tries to
flush modified pages if there are no replaceable pages in the last
10 % of the LRU list. This can reduce disk I/O if the workload is
a mixture of reads and writes. 
@item
The buffer pool checkpoint flush algorithm now tries to flush also
close neighbors of the page at the end of the flush list. This can
speed up database shutdown, and can also speed up disk writes if
@code{InnoDB} log files are very small compared to the buffer pool size. 
@item
In 4.0.13 we made @code{SHOW INNODB STATUS} to print detailed info
on the latest @code{UNIQUE KEY} error, but storing that information could
slow down @code{REPLACE} significantly. We no longer store or print
the info. 
@item
Fixed a bug: @code{SET FOREIGN_KEY_CHECKS=0} was not replicated properly
in the MySQL replication. The fix will not be backported to 3.23. 
@item
Fixed a bug: the parameter @code{innodb_max_dirty_pages_pct} forgot to
take into account the free pages in the buffer pool. This could lead
to excessive flushing even though there were lots of free pages in
the buffer pool. Workaround: @code{SET GLOBAL
innodb_max_dirty_pages_pct = 100}.
@item
Fixed a bug: If there were big index scans then a file read request
could starve and @code{InnoDB} could assert because of a very long semaphore wait. 
@item
Fixed a bug: If @code{AUTOCOMMIT=1} then inside @code{LOCK TABLES} MySQL
failed to do the commit after an updating SQL statement if binary logging was
not on, and for @code{SELECT} statements did not commit regardless of binary logging state. 
@item
Fixed a bug: @code{InnoDB} could make the index page directory corrupt in the
first B-tree page splits after a @command{mysqld} startup. A symptom would be an
assertion in page0page.c, in function page_dir_find_slot(). 
@item
Fixed a bug: If in a @code{FOREIGN KEY} with an @code{UPDATE CASCADE}
clause the parent column was of a different internal storage length
than the child column, then a cascaded update would make the column
length wrong in the child table and corrupt the child table. Because
of MySQL's 'silent column specification changes' a fixed-length
@code{CHAR} column can change internally to a @code{VARCHAR} and cause
this error. 
@item
Fixed a bug: If a non-@code{latin1} character set was used and if in a
@code{FOREIGN KEY} the parent column was of a different internal storage
length than the child column, then all inserts to the child table would
fail in a foreign key error. 
@item
Fixed a bug: @code{InnoDB} could complain that it cannot find the clustered
index record, or in rare cases return an extraneous row if a rollback,
purge, and a @code{SELECT} coincided. 
@item
Fixed a possible hang over the btr0sea.c latch if @code{SELECT} was used
inside @code{LOCK TABLES}. 
@item
Fixed a bug: contrary to what the release note of 4.0.13 said, the
group commit still did not work if the MySQL binary logging was on. 
@item
Fixed a bug: os_event_wait() did not work properly in Unix, which
might have caused starvation in various log operations. 
@item
Fixed a bug: If a single @code{DELETE} statement first managed to delete
some rows and then failed in a @code{FOREIGN KEY} error or a
'Table is full error', MySQL did not roll back the whole SQL statement
as it should, and also wrote the failed statement to the binary log, reporting
there a non-zero error_code. 
@item
Fixed a bug: the maximum allowed number of columns in a table is 1000, but
@code{InnoDB} did not check that limit in @code{CREATE TABLE}, and a subsequent
@code{INSERT} or @code{SELECT} from that table could cause an assertion. 
@end itemize

@node InnoDB news-3.23.57, InnoDB news-4.0.13, InnoDB news-4.0.14, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.57, June 20, 2003 

@itemize bullet
@item
Changed the default value of @code{innodb_flush_log_at_trx_commit} from 0
to 1. If you have not specified it explicitly in your @file{my.cnf}, and
your application runs much slower with this new release, it is because the
value 1 causes a log flush to disk at each transaction commit. 
@item
Fixed a bug: @code{InnoDB} forgot to call pthread_mutex_destroy() when a table was
dropped. That could cause memory leakage on FreeBSD and other non-Linux
Unixes. 
@item
Fixed a bug: MySQL could erroneously return 'Empty set' if @code{InnoDB} estimated
an index range size to 0 records though the range was not empty; MySQL also
failed to do the next-key locking in the case of an empty index range. 
@item
Fixed a bug: @code{GROUP BY} and @code{DISTINCT} could treat NULL values
inequal. 
@end itemize

@node InnoDB news-4.0.13, InnoDB news-4.1.0, InnoDB news-3.23.57, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.13, May 20, 2003 

@itemize bullet
@item
@code{InnoDB} now supports @code{ALTER TABLE DROP FOREIGN KEY}. You have to use
@code{SHOW CREATE TABLE} to find the internally generated foreign key ID
when you want to drop a foreign key. 
@item
@code{SHOW INNODB STATUS} now prints detailed information of the latest
detected @code{FOREIGN KEY} and @code{UNIQUE KEY} errors. If you do not understand
why @code{InnoDB} gives the error 150 from a @code{CREATE TABLE}, you can use
this statement to study the reason. 
@item
@code{ANALYZE TABLE} now works also for @code{InnoDB} type tables. It makes 10
random dives to each of the index trees and updates index cardinality
estimates accordingly. Note that because these are only estimates,
repeated runs of @code{ANALYZE TABLE} may produce different numbers. MySQL
uses index cardinality estimates only in join optimization. If some
join is not optimized in the right way, you may try using @code{ANALYZE TABLE}. 
@item
@code{InnoDB} group commit capability now works also when MySQL
binary logging is switched on. There have to be > 2 client threads
for the group commit to become active. 
@item
Changed the default value of @code{innodb_flush_log_at_trx_commit} from
0 to 1. If you have not specified it explicitly in your @file{my.cnf},
and your application runs much slower with this new release, it
is because the value 1 causes a log flush to disk at each transaction
commit. 
@item
Added a new global settable MySQL system variable
@code{innodb_max_dirty_pages_pct}. It is an integer in the range 0 - 100.
The default is 90. The main thread in @code{InnoDB} tries to flush pages
from the buffer pool so that at most this many percents are not yet
flushed at any time. 
@item
If @code{innodb_force_recovery=6}, do not let @code{InnoDB} do repair of corrupt
pages based on the doublewrite buffer. 
@item
@code{InnoDB} startup now happens faster because it does not set the
memory in the buffer pool to zero. 
@item
Fixed a bug: The @code{InnoDB} parser for @code{FOREIGN KEY} definitions was
confused by the keywords 'foreign key' inside MySQL comments. 
@item
Fixed a bug: If you dropped a table to which there was a @code{FOREIGN
KEY} reference, and later created the same table with non-matching
column types, @code{InnoDB} could assert in @file{dict0load.c}, in function
@code{dict_load_table()}. 
@item
Fixed a bug: @code{GROUP BY} and @code{DISTINCT} could treat @code{NULL}
values as not equal.
MySQL also failed to do the next-key locking in the case of an
empty index range. 
@item
Fixed a bug: Do not commit the current transaction when a @code{MyISAM}
table is updated; this also makes @code{CREATE TABLE} not to commit an
@code{InnoDB} transaction, even when binary logging is enabled. 
@item
Fixed a bug: We did not allow @code{ON DELETE SET NULL} to modify the same
table where the delete was made; we can allow it because that cannot
produce infinite loops in cascaded operations. 
@item
Fixed a bug: Allow @code{HANDLER PREV} and @code{NEXT} also after positioning
the cursor with a unique search on the primary key.
@item
Fixed a bug: If @code{MIN()} or @code{MAX()} resulted in a deadlock or a lock
wait timeout, MySQL did not return an error, but returned @code{NULL} as the
function value.
@item
Fixed a bug: @code{InnoDB} forgot to call @code{pthread_mutex_destroy()} when
a table was dropped. That could cause memory leakage on FreeBSD
and other non-Linux Unix systems. 
@end itemize


@node InnoDB news-4.1.0, InnoDB news-3.23.56, InnoDB news-4.0.13, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.1.0, April 3, 2003 

@itemize @bullet
@item
@code{InnoDB} now supports up to 64GB of buffer pool memory in a
Windows 32-bit Intel computer. This is possible because @code{InnoDB}
can use the AWE extension of Windows to address memory over
the 4GB limit of a 32-bit process. A new startup variable
@code{innodb_buffer_pool_awe_mem_mb} enables AWE and sets the size
of the buffer pool in megabytes. 
@item
Reduced the size of buffer headers and the lock table. @code{InnoDB} uses
2 % less memory. 
@end itemize


@node InnoDB news-3.23.56, InnoDB news-4.0.12, InnoDB news-4.1.0, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.56, March 17, 2003 

@itemize @bullet
@item
Fixed a major bug in @code{InnoDB} query optimization: queries of type
SELECT ... WHERE indexcolumn < x and SELECT ... WHERE
indexcolumn > x could cause a table scan even if the selectivity
would have been very good.
@item 
Fixed a potential bug if MySQL calls store_lock with TL_IGNORE
in the middle of a query. 
@end itemize


@node InnoDB news-4.0.12, InnoDB news-4.0.11, InnoDB news-3.23.56, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.12, March 18, 2003 

@itemize @bullet
@item
In crash recovery @code{InnoDB} now prints the progress in percents of a
transaction rollback.
@item
Fixed a bug/feature: If your application program used
mysql_use_result(), and used >= 2 connections to send
SQL queries, it could deadlock on the adaptive hash S-latch
in btr0sea.c. Now @command{mysqld} releases the S-latch whenever it
passes data from a SELECT to the client. 
@item
Fixed a bug: MySQL could erroneously return 'Empty set'
if @code{InnoDB} estimated an index range size to 0 records though
the range was not empty; MySQL also failed to do the next-key
locking in the case of an empty index range. 
@end itemize


@node InnoDB news-4.0.11, InnoDB news-4.0.10, InnoDB news-4.0.12, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.11, February 25, 2003 

@itemize @bullet
@item
Fixed a bug introduced in 4.0.10: SELECT ... FROM ... ORDER BY ... DESC
could hang in an infinite loop. 
@item
An outstanding bug: SET FOREIGN_KEY_CHECKS=0 is not replicated properly
in the MySQL replication.
@end itemize


@node InnoDB news-4.0.10, InnoDB news-3.23.55, InnoDB news-4.0.11, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.10, February 4, 2003 

@itemize @bullet
@item
In INSERT INTO t1 SELECT ... FROM t2 WHERE ... MySQL previously
set a table level read lock on t2. This lock is now removed. 
@item
Increased SHOW INNODB STATUS maximum printed length to 200KB.
@item
Fixed a major bug in @code{InnoDB} query optimization: queries of type
SELECT ... WHERE indexcolumn < x and SELECT ... WHERE
indexcolumn > x could cause a table scan even if the
selectivity would have been very good. 
@item
Fixed a bug: purge could cause a hang in a BLOB table where the
primary key index tree was of height 1. Symptom: semaphore waits
caused by an X-latch set in btr_free_externally_stored_field(). 
@item
Fixed a bug: using @code{InnoDB} HANDLER commands on a fresh handle
crashed @command{mysqld} in @code{ha_innobase::change_active_index()}. 
@item
Fixed a bug: If MySQL estimated a query in the middle of a SELECT
statement, @code{InnoDB} could hang on the adaptive hash index latch in btr0sea.c. 
@item
Fixed a bug: @code{InnoDB} could report table corruption and assert
in page_dir_find_owner_slot() if an adaptive hash index search
coincided with purge or an insert. 
@item
Fixed a bug: some filesystem snapshot tool in Windows 2000 could
cause an @code{InnoDB} file write to fail with error 33 ERROR_LOCK_VIOLATION.
In synchronous writes @code{InnoDB} now retries the write 100 times at 1
second intervals. 
@item
Fixed a bug: REPLACE INTO t1 SELECT ... did not work if t1 has an
auto-inc column. 
@item
An outstanding bug: SET FOREIGN_KEY_CHECKS=0 is not replicated properly
in the MySQL replication.
@end itemize


@node InnoDB news-3.23.55, InnoDB news-4.0.9, InnoDB news-4.0.10, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.55, January 24, 2003

@itemize @bullet
@item
In INSERT INTO t1 SELECT ... FROM t2 WHERE ... MySQL previously set
a table level read lock on t2. This lock is now removed.
@item
Fixed a bug: If the combined size of @code{InnoDB} log files was >= 2GB 
in a 32-bit computer, @code{InnoDB} would write log in a wrong
position. That could make crash recovery and @code{InnoDB Hot Backup}
to fail in log scan. 
@item
Fixed a bug: index cursor restoration could theoretically fail. 
@item
Fixed a bug: an assertion in btr0sea.c, in function
btr_search_info_update_slow could theoretically fail in a race of 3 threads. 
@item
Fixed a bug: purge could cause a hang in a BLOB table where the
primary key index tree was of height 1. Symptom: semaphore waits
caused by an X-latch set in btr_free_externally_stored_field(). 
@item
Fixed a bug: If MySQL estimated a query in the middle of a SELECT statement,
@code{InnoDB} could hang on the adaptive hash index latch in btr0sea.c. 
@item
Fixed a bug: @code{InnoDB} could report table corruption and assert in
page_dir_find_owner_slot() if an adaptive hash index search
coincided with purge or an insert. 
@item
Fixed a bug: some filesystem snapshot tool in Windows 2000 could
cause an @code{InnoDB} file write to fail with error 33 ERROR_LOCK_VIOLATION.
In synchronous writes @code{InnoDB} now retries the write 100 times
at 1 second intervals. 
@item
An outstanding bug: SET FOREIGN_KEY_CHECKS=0 is not replicated properly
in the MySQL replication. The fix will appear in 4.0.11 and will probably
not be backported to 3.23.
@item
Fixed bug in @code{InnoDB} @file{page0cur.c} file in function page_cur_search_with_match
which caused @code{InnoDB} to remain on the same page forever.
This bug is evident only in tables with more than one page.
@end itemize


@node InnoDB news-4.0.9, InnoDB news-4.0.8, InnoDB news-3.23.55, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.9, January 14, 2003

@itemize @bullet
@item
Removed the warning message: 'InnoDB: Out of memory in additional memory pool.'
@item
Fixed a bug: If the combined size of @code{InnoDB} log files was >= 2GB in a
32-bit computer, @code{InnoDB} would write log in a wrong position. That could
make crash recovery and @code{InnoDB Hot Backup} to fail. 
@item
Fixed a bug: index cursor restoration could theoretically fail. 
@end itemize


@node InnoDB news-4.0.8, InnoDB news-4.0.7, InnoDB news-4.0.9, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.8, January 7, 2003

@itemize @bullet
@item
@code{InnoDB} now supports also FOREIGN KEY (...) REFERENCES ...(...)
[ON UPDATE CASCADE | ON UPDATE SET NULL | ON UPDATE RESTRICT
| ON UPDATE NO ACTION]. 
@item
Tables and indexes now reserve 4 % less space in the tablespace.
Also existing tables reserve less space. By upgrading to 4.0.8
you will see more free space in "InnoDB free" in SHOW TABLE STATUS. 
@item
Fixed bugs: updating the PRIMARY KEY of a row would generate a
foreign key error on all FOREIGN KEYs which referenced secondary
keys of the row to be updated. Also, if a referencing
FOREIGN KEY constraint only referenced the first columns in an
index, and there were more columns in that index, updating the
additional columns generated a foreign key error. 
@item
Fixed a bug: If an index contains some column twice, and that
column is updated, the table will become corrupt. From now on
@code{InnoDB} prevents creation of such indexes. 
@item
Fixed a bug: removed superfluous error 149 and 150 printouts
from the .err log when a locking SELECT caused a deadlock or a
lock wait timeout.
@item
Fixed a bug: an assertion in btr0sea.c, in function
btr_search_info_update_slow could theoretically fail in a race of 3 threads. 
@item
Fixed a bug: one could not switch a session transaction isolation
level back to REPEATABLE READ after setting it to something else.
@end itemize


@node InnoDB news-4.0.7, InnoDB news-4.0.6, InnoDB news-4.0.8, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.7, December 26, 2002

@itemize @bullet
@item
@code{InnoDB} in 4.0.7 is essentially the same as in 4.0.6.
@end itemize


@node InnoDB news-4.0.6, InnoDB news-3.23.54, InnoDB news-4.0.7, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.6, December 19, 2002

@itemize @bullet
@item
Since innodb_log_arch_dir has no relevance under MySQL,
there is no need to specify it any more in my.cnf. 
@item
LOAD DATA INFILE in AUTOCOMMIT=1 mode no longer does
implicit commits for each 1MB of written binary log. 
@item
Fixed a bug introduced in 4.0.4: LOCK TABLES ... READ LOCAL
should not set row locks on the rows read. This caused
deadlocks and lock wait timeouts in mysqldump. 
@item
Fixed two bugs introduced in 4.0.4: in AUTO_INCREMENT,
REPLACE could cause the counter to be left 1 too low.
A deadlock or a lock wait timeout could cause the same problem. 
@item
Fixed a bug: TRUNCATE on a TEMPORARY table crashed @code{InnoDB}. 
@item
Fixed a bug introduced in 4.0.5: If binary logging was not switched on,
INSERT INTO ... SELECT ... or CREATE TABLE ... SELECT ... could
cause @code{InnoDB} to hang on a semaphore created in btr0sea.c, line 128.
Workaround: switch binary logging on. 
@item
Fixed a bug: in replication issuing SLAVE STOP in the middle of
a multiple-statement transaction could cause that SLAVE START would
only perform a part of the transaction. A similar error could occur
if the slave crashed and was restarted.
@end itemize


@node InnoDB news-3.23.54, InnoDB news-4.0.5, InnoDB news-4.0.6, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.54, December 12, 2002

@itemize @bullet
@item
Fixed a bug: the @code{InnoDB} range estimator greatly exaggerated
the size of a short index range if the paths to the endpoints of
the range in the index tree happened to branch already in the root.
This could cause unnecessary table scans in SQL queries. 
@item
Fixed a bug: ORDER BY could fail if you had not created a
primary key to a table, but had defined several indexes
of which at least one was a UNIQUE index with all its
columns declared as NOT NULL. 
@item
Fixed a bug: a lock wait timeout in connection with
ON DELETE CASCADE could cause corruption in indexes. 
@item
Fixed a bug: If a SELECT was done with a unique key
from a primary index, and the search matched to a
delete-marked record, @code{InnoDB} could erroneously return the NEXT record. 
@item
Fixed a bug introduced in 3.23.53: LOCK TABLES ... READ LOCAL
should not set row locks on the rows read. This caused deadlocks
and lock wait timeouts in mysqldump. 
@item
Fixed a bug: If an index contains some column twice, and that
column is updated, the table will become corrupt. From now on
@code{InnoDB} prevents creation of such indexes. 
@end itemize


@node InnoDB news-4.0.5, InnoDB news-3.23.53, InnoDB news-3.23.54, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.5, November 18, 2002

@itemize @bullet
@item
@code{InnoDB} now supports also transaction isolation levels READ COMMITTED
and READ UNCOMMITTED. READ COMMITTED more closely emulates Oracle
and makes porting of applications from Oracle to MySQL easier. 
@item
Deadlock resolution is now selective: we try to pick as victims
transactions with less modified or inserted rows. 
@item
FOREIGN KEY definitions are now aware of the
lower_case_table_names setting in my.cnf. 
@item
SHOW CREATE TABLE does not output the database name
to a FOREIGN KEY definition if the referred table is
in the same database as the table. 
@item
@code{InnoDB} does a consistency check to most index pages
before writing them to a data file. 
@item
If you set @code{innodb_force_recovery} > 0, @code{InnoDB} tries to
jump over corrupt index records and pages when doing
SELECT * FROM table. This helps in dumping. 
@item
@code{InnoDB} now again uses asynchronous unbuffered I/O in
Windows 2000 and XP; only unbuffered simulated async
I/O in NT, 95/98/ME. 
@item
Fixed a bug: the @code{InnoDB} range estimator greatly exaggerated
the size of a short index range if the paths to the
endpoints of the range in the index tree happened
to branch already in the root. This could cause
unnecessary table scans in SQL queries.
The fix will also be backported to 3.23.54. 
@item
Fixed a bug present in 3.23.52, 4.0.3, 4.0.4:
@code{InnoDB} startup could take very long or even
crash on some Windows 95/98/ME computers. 
@item
Fixed a bug: the AUTO-INC lock was held to the end
of the transaction if it was granted after a
lock wait. This could cause unnecessary deadlocks. 
@item
Fixed a bug: If SHOW INNODB STATUS, innodb_monitor,
or innodb_lock_monitor had to print several hundred
transactions in one report, and the output became
truncated, @code{InnoDB} would hang, printing to the error
log many waits for a mutex created at srv0srv.c, line 1621. 
@item
Fixed a bug: SHOW INNODB STATUS on Unix always
reported average file read size as 0 bytes. 
@item
Fixed a potential bug in 4.0.4: @code{InnoDB} now
does ORDER BY ... DESC like @code{MyISAM}. 
@item
Fixed a bug: DROP TABLE could cause crash or a
hang if there was a rollback concurrently running
on the table. The fix will be backported to 3.23
only if this appears a real problem for users. 
@item
Fixed a bug: ORDER BY could fail if you had not
created a primary key to a table, but had defined
several indexes of which at least one was a UNIQUE
index with all its columns declared as NOT NULL. 
@item
Fixed a bug: a lock wait timeout in connection
with ON DELETE CASCADE could cause corruption in indexes. 
@item
Fixed a bug: If a SELECT was done with a unique
key from a primary index, and the search matched
to a delete-marked record, @code{InnoDB} could return the NEXT record. 
@item
Outstanding bugs: in 4.0.4 two bugs were introduced
to AUTO_INCREMENT. REPLACE can cause the counter to
be left 1 too low. A deadlock or a lock wait timeout
can cause the same problem. These will be fixed in 4.0.6.
@end itemize


@node InnoDB news-3.23.53, InnoDB news-4.0.4, InnoDB news-4.0.5, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.53, October 9, 2002

@itemize @bullet
@item
We again use unbuffered disk I/O to data files in Windows.
Windows XP and Windows 2000 read performance seems to be
very poor with normal I/O. 
@item
Tuned range estimator so that index range scans are
preferred over full index scans. 
@item
Allow dropping and creating a table even if
innodb_force_recovery is set. One can use this to
drop a table which would cause a crash in rollback
or purge, or if a failed table import causes a runaway rollback in recovery. 
@item
Fixed a bug present in 3.23.52, 4.0.3, 4.0.4: @code{InnoDB} startup
could take very long or even crash on some Windows 95/98/ME computers. 
@item
Fixed a bug: fast shutdown (which is the default)
sometimes was slowed down by purge and insert buffer merge. 
@item
Fixed a bug: doing a big SELECT from a table where no
rows were visible in a consistent read could cause a
very long (> 600 seconds) semaphore wait in btr0cur.c line 310. 
@item
Fixed a bug: the AUTO-INC lock was held to the end of
the transaction if it was granted after a lock wait.
This could cause unnecessary deadlocks. 
@item
Fixed a bug: If you created a temporary table
inside LOCK TABLES, and used that temporary table,
that caused an assertion failure in ha_innobase.cc. 
@item
Fixed a bug: If SHOW INNODB STATUS, innodb_monitor,
or innodb_lock_monitor had to print several hundred
transactions in one report, and the output became
truncated, @code{InnoDB} would hang, printing to the error
log many waits for a mutex created at srv0srv.c, line 1621. 
@item
Fixed a bug: SHOW INNODB STATUS on Unix always
reported average file read size as 0 bytes.
@end itemize


@node InnoDB news-4.0.4, InnoDB news-4.0.3, InnoDB news-3.23.53, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.4, October 2, 2002

@itemize @bullet
@item
We again use unbuffered disk I/O in Windows. Windows XP and Windows 2000
read performance seems to be very poor with normal I/O.
@item
Increased the maximum key length of @code{InnoDB} tables from 500 to 1024 bytes.
@item
Increased the table comment field in SHOW TABLE STATUS so that
up to 16000 characters of foreign key definitions can be printed there.
@item
The auto-increment counter is no longer incremented if
an insert of a row immediately fails in an error.
@item
Allow dropping and creating a table even if
innodb_force_recovery is set. One can use this to drop
a table which would cause a crash in rollback or purge,
or if a failed table import causes a runaway rollback in recovery.
@item
Fixed a bug: Using ORDER BY primarykey DESC in 4.0.3 causes
an assertion failure in btr0pcur.c, line 203.
@item
Fixed a bug: fast shutdown (which is the default) sometimes
was slowed down by purge and insert buffer merge.
@item
Fixed a bug: doing a big SELECT from a table where
no rows were visible in a consistent read could cause
a very long (> 600 seconds) semaphore wait in btr0cur.c line 310.
@item
Fixed a bug: If the MySQL query cache was used, it did not get
invalidated by a modification done by ON DELETE CASCADE or ...SET NULL.
@item
Fixed a bug: If you created a temporary table inside LOCK TABLES,
and used that temporary table, that caused an assertion failure
in ha_innodb.cc.
@item
Fixed a bug: If you set innodb_flush_log_at_trx_commit to 1, SHOW
VARIABLES would show its value as 16 million.
@end itemize


@node InnoDB news-4.0.3, InnoDB news-3.23.52, InnoDB news-4.0.4, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.3, August 28, 2002

@itemize @bullet
@item
Removed unnecessary deadlocks when inserts have to wait for
a locking read, update, or delete to release its next-key lock.
@item
The MySQL @code{HANDLER} SQL commands now work also for @code{InnoDB}
type tables. @code{InnoDB} does the @code{HANDLER} reads always as
consistent reads. @code{HANDLER} is a direct access path to read
individual indexes of tables. In some cases, @code{HANDLER} can be
used as a substitute of server-side cursors.
@item
Fixed a bug in 4.0.2: even a simple insert could crash the
AIX version.
@item
Fixed a bug: If you used in a table name characters whose code is > 127,
in DROP TABLE @code{InnoDB} could assert on line 155 of pars0sym.c.
@item
Compilation from source now provides a working version both on
HP-UX-11 and HP-UX-10.20. The source of 4.0.2 worked only on 11,
and the source of 3.23.52 only on 10.20.
@item
Fixed a bug: If compiled on 64-bit Solaris, @code{InnoDB} produced a bus error
at startup.
@end itemize


@node InnoDB news-3.23.52, InnoDB news-4.0.2, InnoDB news-4.0.3, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.52, August 16, 2002

@itemize @bullet
@item
The feature set of 3.23 will be frozen from this version on. New features
will go the 4.0 branch, and only bugfixes will be made to the 3.23
branch.
@item
Many CPU-bound join queries now run faster. On Windows also many
other CPU-bound queries run faster.
@item
A new SQL command SHOW INNODB STATUS returns the output of the
@code{InnoDB} Monitor to the client. The @code{InnoDB} Monitor now prints detailed
information on
the latest detected deadlock.
@item
@code{InnoDB} made the SQL query optimizer to avoid too much index-only
range scans and choose full table scans instead. This is now fixed.
@item
@code{BEGIN} and @code{COMMIT} are now added in the binary log around transactions.
The MySQL replication now respects transaction borders:
a user will no longer see half transactions in replication slaves.
@item
A replication slave now prints in crash recovery the last
master binary log position it was able to recover to.
@item
A new setting @code{innodb_flush_log_at_trx_commit=2} makes @code{InnoDB} to write
the log to the operating system file cache at each commit. This is
almost as fast as the setting innodb_flush_log_at_trx_commit=0, and
the setting 2 also has the nice feature that in a crash where the
operating system does not crash, no committed transaction is lost.
If the operating system crashes or there is a power outage, then
the setting 2 is no safer than the setting 0.
@item
Added checksum fields to log blocks.
@item
SET FOREIGN_KEY_CHECKS=0 helps in importing tables
in an arbitrary order which does not respect the foreign key rules.
@item
SET UNIQUE_CHECKS=0 speeds up table imports into @code{InnoDB}
if you have UNIQUE constraints on secondary indexes.
This flag should be used only if you are certain that the input records
contain no UNIQUE constraint violations.
@item
SHOW TABLE STATUS now lists also possible ON DELETE CASCADE or
ON DELETE SET NULL in the comment field of the table.
@item
When CHECK TABLE is run on any @code{InnoDB} type table, it now
checks also the adaptive hash index for all tables.
@item
If you defined ON DELETE CASCADE or SET NULL and updated the
referenced key in the parent row, @code{InnoDB} deleted or updated
the child row. This is now changed to conform to standard SQL: you get
the error 'Cannot delete parent row'.
@item
Improved the auto-increment algorithm: now the first insert or
SHOW TABLE STATUS initializes the auto-increment counter for the table.
This removes almost all surprising deadlocks caused by
SHOW TABLE STATUS.
@item
Aligned some buffers used in reading and writing to data files.
This allows using unbuffered raw devices as data files in Linux.
@item
Fixed a bug: If you updated the primary key of a table so that only the
case of characters changed, that could cause assertion
failures, mostly in page0page.ic line 515.
@item
Fixed a bug: If you delete or update a row referenced in a foreign key
constraint and the foreign key check has to wait for a lock,
then the check may report an erroneous result. This
affects also the ON DELETE... operation.
@item
Fixed a bug: A deadlock or a lock wait timeout error in @code{InnoDB}
causes @code{InnoDB} to roll back the whole transaction, but MySQL could still
write the earlier SQL statements to the binary log, even though
@code{InnoDB} rolled them back. This could, for example, cause replicated
databases to get out-of-sync.
@item
Fixed a bug: If the database happened to crash in the middle of a
commit, then the recovery might leak tablespace pages.
@item
Fixed a bug: If you specified a non-latin1 character set in my.cnf,
then, in contrary to what is stated in the manual, in a foreign key
constraint a string type column had to have the same length specification
in the referencing table and the referenced table.
@item
Fixed a bug: DROP TABLE or DROP DATABASE could fail if there
simultaneously was a CREATE TABLE running.
@item
Fixed a bug: If you configured the buffer pool bigger than 2GB in
a 32-bit computer, @code{InnoDB} would assert in buf0buf.ic line 214.
@item
Fixed a bug: on 64-bit computers updating rows which contained the
SQL NULL in some column could cause the undo log and the ordinary
log to become corrupt.
@item
Fixed a bug: innodb_log_monitor caused a hang if it suppressed
lock prints for a page.
@item
Fixed a bug: in the HP-UX-10.20 version mutexes would leak and cause
race conditions and crashes in any part of @code{InnoDB} code.
@item
Fixed a bug: If you ran in the AUTOCOMMIT mode, executed a SELECT,
and immediately after that a RENAME TABLE, then RENAME would fail and
MySQL would complain about error 1192.
@item
Fixed a bug: If compiled on 64-bit Solaris, @code{InnoDB} produced a bus error
at startup.
@end itemize


@node InnoDB news-4.0.2, InnoDB news-3.23.51, InnoDB news-3.23.52, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.2, July 10, 2002

@itemize @bullet
@item
@code{InnoDB} is essentially the same as InnoDB-3.23.51.
@item
If no innodb_data_file_path is specified, @code{InnoDB} at the database creation
now creates a 10MB auto-extending data file ibdata1 to the datadir
of MySQL. In 4.0.1 the file was 64MB and not auto-extending.
@end itemize


@node InnoDB news-3.23.51, InnoDB news-3.23.50, InnoDB news-4.0.2, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.51, June 12, 2002

@itemize @bullet
@item
Fixed a bug: a join could result in a seg fault in copying of a BLOB or
TEXT column if some of the BLOB or TEXT columns in the table contained
SQL NULL values.
@item
Fixed a bug: If you added self-referential foreign key constraints with
ON DELETE CASCADE to tables and a row deletion caused @code{InnoDB}
to attempt the deletion of the same row twice because of
a cascading delete, then you got an assertion failure.
@item
Fixed a bug: If you use MySQL 'user level locks' and close
a connection, then @code{InnoDB} may assert in ha_innobase.cc, line 302.
@end itemize


@node InnoDB news-3.23.50, InnoDB news-3.23.49, InnoDB news-3.23.51, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.50, April 23, 2002

@itemize @bullet
@item
@code{InnoDB} now supports an auto-extending last data file. You do not need
to preallocate the whole data file at the database startup.
@item
Made several changes to facilitate the use of the @code{InnoDB Hot Backup}
tool. It is a separate non-free tool you can use to take online backups
of your database without shutting down the server or setting
any locks.
@item
If you want to run the @code{InnoDB Hot Backup} tool on an auto-extending
data file you have to upgrade it to version ibbackup-0.35.
@item
The log scan phase in crash recovery will now run much faster.
@item
Starting from this server version, the hot backup tool
truncates unused ends in the backup @code{InnoDB} data files.
@item
To allow the hot backup tool to work, on Windows we no longer use
unbuffered I/O or native async I/O; instead we use the same simulated
async I/O as on Unix.
@item
You can now define the ON DELETE CASCADE or ON DELETE SET NULL
clause on foreign keys.
@item
FOREIGN KEY constraints now survive ALTER TABLE and CREATE
INDEX.
@item
We suppress the FOREIGN KEY check if any of the column values in the
foreign key or referenced key to be checked is the SQL NULL. This
is compatible with Oracle, for example.
@item
SHOW CREATE TABLE now lists also foreign key constraints. Also
mysqldump no longer forgets about foreign keys in table definitions.
@item
You can now add a new foreign key constraint with
ALTER TABLE ... ADD CONSTRAINT FOREIGN KEY (...) REFERENCES ... (...).
@item
FOREIGN KEY definitions now allow backticks around table and
column names.
@item
MySQL command
SET TRANSACTION ISOLATION LEVEL ...
has now the following effect on
@code{InnoDB} tables: If a transaction is defined as SERIALIZABLE
then @code{InnoDB} conceptually adds LOCK IN SHARE MODE
to all consistent reads. If a transaction is defined to have any other
isolation level, then @code{InnoDB} obeys its default locking strategy
which is REPEATABLE READ.
@item
SHOW TABLE STATUS no longer sets an x-lock at the end of an
auto-increment index if the auto-increment counter has already
been initialized. This removes in almost all cases the surprising deadlocks
caused by SHOW TABLE STATUS.
@item
Fixed a bug: in a CREATE TABLE statement the string 'foreign'
followed by a non-space character confused the FOREIGN KEY parser
and caused table creation to fail with errno 150.
@end itemize


@node InnoDB news-3.23.49, InnoDB news-3.23.48, InnoDB news-3.23.50, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.49, February 17, 2002

@itemize @bullet
@item
Fixed a bug: If you called DROP DATABASE for a database on which
there simultaneously were running queries, the MySQL server could crash
or hang. Crashes fixed, but a full fix has to wait some changes
in the MySQL layer of code.
@item
Fixed a bug: on Windows one had to put the database name
in lowercase for @code{DROP
DATABASE} to work. Fixed in 3.23.49: case no longer matters
on Windows. On Unix, the database name remains case sensitive.
@item
Fixed a bug: If one defined a non-latin1 character set as
the default character set,
then definition of foreign key constraints could fail
in an assertion failure
in dict0crea.c, reporting an internal error 17.
@end itemize


@node InnoDB news-3.23.48, InnoDB news-3.23.47, InnoDB news-3.23.49, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.48, February 9, 2002

@itemize @bullet
@item
Tuned the SQL optimizer to favor more often index searches
over table scans.
@item
Fixed a performance problem when several large SELECT
queries are run concurrently on a multiprocessor Linux computer.
Large CPU-bound SELECT queries will now also generally run faster on
all platforms.
@item
If MySQL binary logging is used,
@code{InnoDB} now prints after crash recovery the latest MySQL binary log
file name and the position in that file (= byte offset)
@code{InnoDB} was able to recover to. This is useful, for example,
when resynchronizing a master and a slave database in replication.
@item
Added better error messages to help in installation problems.
@item
One can now recover also MySQL temporary tables which have become
orphaned inside the @code{InnoDB} tablespace.
@item
@code{InnoDB} now prevents a FOREIGN KEY declaration where the signedness
is not the same in the referencing and referenced integer columns.
@item
Fixed a bug: calling SHOW CREATE TABLE or SHOW TABLE STATUS
could cause memory corruption and make @command{mysqld} to crash.
Especially at risk was mysqldump, because it calls frequently
SHOW CREATE TABLE.
@item
Fixed a bug: If on Unix you did an ALTER TABLE to an @code{InnoDB} table and
simultaneously did queries to it, @command{mysqld} could crash with an assertion
failure in row0row.c, line 474.
@item
Fixed a bug: If inserts to several tables containing an auto-inc column
were wrapped inside one LOCK TABLES, @code{InnoDB} asserted in lock0lock.c.
@item
In 3.23.47 we allowed several NULLS in a UNIQUE secondary index.
But CHECK TABLE was not relaxed: it reports the table as corrupt.
CHECK TABLE no longer complains in this situation.
@item
Fixed a bug: on Sparc and other high-endian processors SHOW VARIABLES
showed innodb_flush_log_at_trx_commit and other boolean-valued
startup parameters always OFF even if they were switched on. 
@item
Fixed a bug: If you ran mysqld-max-nt as a service on Windows NT/2000,
the service shutdown did not always wait long enough for the @code{InnoDB} shutdown
to finish.
@end itemize


@node InnoDB news-3.23.47, InnoDB news-4.0.1, InnoDB news-3.23.48, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.47, December 28, 2001

@itemize @bullet
@item
Recovery happens now faster, especially in a lightly loaded system,
because background checkpointing has been made more frequent.
@item
@code{InnoDB} allows now several similar key values in a UNIQUE secondary index
if those values contain SQL NULLs. Thus the convention is now the same as in
@code{MyISAM} tables.
@item
@code{InnoDB} gives a better row count estimate for a table which contains BLOBs.
@item
In a FOREIGN KEY constraint @code{InnoDB} is now case-insensitive to column
names, and in Windows also to table names.
@item
@code{InnoDB} allows a FOREIGN KEY column of CHAR type to refer to a column of
VARCHAR type, and vice versa. MySQL silently changes the type of some
columns between CHAR and VARCHAR, and these silent changes do not hinder
FOREIGN KEY declaration any more.
@item
Recovery has been made more resilient to corruption of log files.
@item
Unnecessary statistics calculation has been removed from queries which
generate a temporary table. Some ORDER BY and DISTINCT queries will now run
much faster.
@item
MySQL now knows that the table scan of an @code{InnoDB} table is done through the
primary key. This will save a sort in some ORDER BY queries.
@item
The maximum key length of @code{InnoDB} tables is again restricted to 500 bytes.
The MySQL interpreter is not able to handle longer keys.
@item
The default value of innodb_lock_wait_timeout was changed from infinite to
50 seconds, the default value of innodb_file_io_threads from 9
to 4.
@end itemize


@node InnoDB news-4.0.1, InnoDB news-3.23.46, InnoDB news-3.23.47, InnoDB change history
@appendixsubsec MySQL/InnoDB-4.0.1, December 23, 2001

@itemize @bullet
@item
@code{InnoDB} is the same as in 3.23.47.
@item
In 4.0.0 the MySQL interpreter did not know the syntax LOCK IN
SHARE MODE. This has been fixed.
@item
In 4.0.0 multiple-table delete did not work for transactional tables.
This has been fixed.
@end itemize


@node InnoDB news-3.23.46, InnoDB news-3.23.45, InnoDB news-4.0.1, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.46, November 30, 2001

@itemize @bullet
@item
This is the same as 3.23.45.
@end itemize


@node InnoDB news-3.23.45, InnoDB news-3.23.44, InnoDB news-3.23.46, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.45, November 23, 2001

@itemize @bullet
@item
This is a bugfix release.
@item
In versions 3.23.42-.44 when creating a table on Windows, you
have to use lowercase letters in the database name to be able to
access the table. Fixed in 3.23.45.
@item
@code{InnoDB} now flushes stdout and stderr every 10 seconds: If these
are redirected to files, the file contents can be better viewed with
an editor.
@item
Fixed an assertion failure in .44, in trx0trx.c, line 178
when you drop a table which has
the .frm file but does not exist inside @code{InnoDB}.
@item
Fixed a bug in the insert buffer.
The insert buffer tree could get into an inconsistent state, causing a crash,
and also crashing the recovery. This bug could appear especially in
large table imports or alterations.
@item
Fixed a bug in recovery: @code{InnoDB} could go into an infinite loop
constantly printing
a warning message that it cannot find free blocks from the buffer pool.
@item
Fixed a bug: when you created a temporary table of the @code{InnoDB} type, and then
used ALTER TABLE to it, the MySQL server could crash.
@item
Prevented creation of MySQL system tables 'mysql.user',
'mysql.host', or 'mysql.db', in the
@code{InnoDB} type.
@item
Fixed a bug which can cause an assertion failure in 3.23.44 in
srv0srv.c, line 1728.
@end itemize


@node InnoDB news-3.23.44, InnoDB news-3.23.43, InnoDB news-3.23.45, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.44, November 2, 2001

@itemize @bullet
@item
You can define foreign key constraints on @code{InnoDB}
tables. An example: FOREIGN KEY (col1) REFERENCES table2(col2).
@item
You can create data files larger than 4GB in those
filesystems that allow it.
@item
Improved @code{InnoDB} monitors, including a new innodb_table_monitor
which allows you to print the contents of the @code{InnoDB} internal data
dictionary.
@item
DROP DATABASE will now work also for @code{InnoDB} tables.
@item
Accent characters in the default character set
latin1 will be ordered according to the MySQL ordering.<br>
NOTE: If you are using latin1 and have inserted characters
whose code is > 127 to an indexed CHAR column, you should run
CHECK TABLE on your table when you upgrade to
3.23.43, and drop and reimport the table if CHECK TABLE
reports an error!
@item
@code{InnoDB} will calculate better table cardinality
estimates.
@item
Change in deadlock resolution:
in .43 a deadlock rolls back only the
SQL statement, in .44 it will roll back the whole transaction.
@item
Deadlock, lock wait timeout, and foreign key
constraint violations (no parent row, child rows exist)
now return native MySQL
error codes 1213, 1205, 1216, 1217, respectively.
@item
A new my.cnf parameter innodb_thread_concurrency
helps in performance tuning in high concurrency environments.
@item
A new my.cnf option innodb_force_recovery will
help you in dumping tables from a corrupted database.
@item
A new my.cnf option innodb_fast_shutdown will
speed up shutdown. Normally @code{InnoDB} does a full purge
and an insert buffer merge at shutdown.
@item
Raised maximum key length to 7000 bytes from a
previous limit of 500 bytes.
@item
Fixed a bug in replication of auto-inc columns with multiline inserts.
@item
Fixed a bug when the case of letters changes in an update of an indexed
secondary column.
@item
Fixed a hang when there are more than 24 data files.
@item
Fixed a crash when MAX(col) is selected from an empty table, and col is a
not the first column in a multi-column index.
@item
Fixed a bug in purge which could cause crashes.
@end itemize


@node InnoDB news-3.23.43, InnoDB news-3.23.42, InnoDB news-3.23.44, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.43, October 4, 2001

@itemize @bullet
@item
This is essentially the same as InnoDB-3.23.42.
@end itemize


@node InnoDB news-3.23.42, InnoDB news-3.23.41, InnoDB news-3.23.43, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.42, September 9, 2001

@itemize @bullet
@item
Fixed a bug which corrupted the table if the primary key
of a > 8000-byte row was updated.
@item
There are now 3 types of @code{InnoDB} Monitors: innodb_monitor,
innodb_lock_monitor, and innodb_tablespace_monitor.
innodb_monitor now prints also buffer pool hit rate and the total
number of rows inserted, updated, deleted, read.
@item
Fixed a bug in RENAME TABLE.
@item
Fixed a bug in replication with an auto-increment column.
@end itemize


@node InnoDB news-3.23.41, InnoDB news-3.23.40, InnoDB news-3.23.42, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.41, August 13, 2001

@itemize @bullet
@item
Support for < 4GB rows. The previous limit was
8000 bytes.
@item
Use the doublewrite file flush method.
@item
Raw disk partitions supported as data files.
@item
@code{InnoDB} Monitor.
@item
Several hang bugs fixed and an @code{ORDER BY}
bug (``Sort aborted'') fixed.
@end itemize


@node InnoDB news-3.23.40, InnoDB news-3.23.39, InnoDB news-3.23.41, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.40, July 16, 2001

@itemize @bullet
@item
Only a few rare bugs fixed.
@end itemize


@node InnoDB news-3.23.39, InnoDB news-3.23.38, InnoDB news-3.23.40, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.39, June 13, 2001

@itemize @bullet
@item
@code{CHECK TABLE} now works for @code{InnoDB} tables.
@item
A new @file{my.cnf} parameter @code{innodb_unix_file_flush_method}
introduced. It can be used to tune disk write performance.
@item
An auto-increment column now gets new values past the
transaction mechanism. This saves CPU time and eliminates
transaction deadlocks in new value assignment.
@item
Several bugfixes, most notably the rollback bug in 3.23.38.
@end itemize


@node InnoDB news-3.23.38,  , InnoDB news-3.23.39, InnoDB change history
@appendixsubsec MySQL/InnoDB-3.23.38, May 12, 2001

@itemize @bullet
@item
The new syntax @code{SELECT ... LOCK IN SHARE MODE} is introduced.
@item
@code{InnoDB} now calls @code{fsync()} after every disk write and calculates
a checksum
for every database page it writes or reads, which will reveal disk defects.
@item
Several bugfixes.
@end itemize


@node MySQL Cluster change history,  , InnoDB change history, News
@appendixsec @code{MySQL Cluster} Change History

@menu
* MySQL Cluster news-4.1.8::    MySQL Cluster-4.1.8 (not released yet)
* MySQL Cluster news-4.1.7::    MySQL Cluster-4.1.7 (23 Oct 2004)
* MySQL Cluster news-4.1.6::    MySQL Cluster-4.1.6 (10 Oct 2004)
* MySQL Cluster news-4.1.5::    MySQL Cluster-4.1.5 (16 Sep 2004)
* MySQL Cluster news-4.1.4::    MySQL Cluster-4.1.4 (31 Aug 2004)
* MySQL Cluster news-5.0.1::    MySQL Cluster-5.0.1 (27 Jul 2004)
* MySQL Cluster news-4.1.3::    MySQL Cluster-4.1.3 (28 Jun 2004)
@end menu

@node MySQL Cluster news-4.1.8, MySQL Cluster news-4.1.7, MySQL Cluster change history, MySQL Cluster change history
@appendixsubsec MySQL Cluster-4.1.8 (not released yet)

Functionality added or changed:
@itemize @bullet
@item Default port for @command{ndb_mgmd} was changed to 1186 (from 2200) as
      this port number was officially assigned to MySQL Cluster by IANA.
@item New command in @command{ndb_mgm}, PURGE STALE SESSIONS, as a workaround
      for cases where nodes fail to allocate a node id even if it is free
      to use.
@item New command in @command{ndb_mgm}, CONNECT.
@item The ndb executables have been changed to make use of the 
      regular MySQL command line option parsing features. 
      See @ref{MySQL Cluster Command Options} for notes on changes.
@item As bonus of the above you can now specify all command
      line options in @file{my.cnf} using the executable names
      as sections, i.e. @code{[ndbd]}, @code{[ndb_mgmd]},
      @code{[ndb_mgm]}, @code{[ndb_restore]} etc.
      @example
      [ndbd]
      ndb-connectstring=myhost.domain.com:1234
      [ndb_mgm]
      ndb-connectstring=myhost.domain.com:1234
      @end example
@item Added use of section @code{[mysql_cluster]} in @file{my.cnf}. All cluster
      executables, including mysqld, parse this section. Convenient place to
      put e.g. @code{ndb-connectstring} so that it only needs to be specified once.
@item Added cluster log info events on allocation and deallocation of nodeid's.
@item Added cluster log info events on connection refuse as a result of version
      mismatch.
@item Extended connectstring syntax to allow for leaving the port number out.
      E.g. @code{ndb-connectstring|connect-string=myhost1,myhost2,myhost3} is 
      a valid connectstring and connect will occur on default port 1186.
@item Clear text ndb error messages provided also for error codes that are mapped
      to corresponding mysql error codes, by executing @code{SHOW WARNINGS} after
      an error has occured which relates to the ndb storage engine.
@item Significant performance improvements done for read performance,
      especially for blobs.
@item Added some variables for performance tuning, @code{ndb_force_send} and
      @code{ndb_use_exact_count}. Do @code{show variables like 'ndb%';} in mysql
      client for listing. Use @code{set} command to alter variables.
@item Added variables to set some options, @code{ndb_use_transactions} and
      @code{ndb_autoincrement_prefetch_sz}.
@end itemize

@c open bugs
@c Bug #5660: Send of uninitialized data
@c Bug #6546: NDB does not interpret a single KEY definition as PRIMARY KEY
@c Bug #6716: ndb_restore core dumps (on HP-UX 11)
@c Bug #6762: ALTER TABLE gives weird results and error message
@c Bug #6794: Wrong outcome of update operation of ndb table
@c Bug #6935: table rename does not work with ndb tables

Bugs fixed:
@itemize @bullet
@item (Bug #6919)
      all status only shows 2 nodes on a 8-node cluster
@item (Bug #6871)
      DBD execute failed: Got error 897 'Unknown error code' from ndbcluster
@item (Bug #6791) 
      Segmentation fault when config.ini is not correctly set
@item (Bug #6775) 
      failure in acc when running many mysql clients
@item (Bug #6696) 
      ndb_mgm command line options inconsistent with behaviour
@item (Bug #6684) 
      ndb_restore doesn't give error messages if inproper command given
@item (Bug #6677) 
      ndb_mgm can crash on "ALL CLUSTERLOG"
@item (Bug #6538) 
      Error code returned when select max() on empty table with index
@item (Bug #6451) 
      failing create table givers "ghost" tables which are impossible to remove
@item (Bug #6435) 
      strange behaviour of left join
@item (Bug #6426) 
      update with long pk fails
@item (Bug #6398) 
      update of primary key fails
@item (Bug #6354) 
      mysql does not complain about --ndbcluster option when NDB is not compiled in
@item (Bug #6331) 
      INSERT IGNORE .. SELECT breaks subsequent inserts
@item (Bug #6288) 
      cluster nodes crash on data import
@item (Bug #6031) 
      To drop database you have to execute DROP DATABASE command twice
@item (Bug #6020) 
      LOCK TABLE + delete returns error 208
@item (Bug #6018) 
      REPLACE does not work for BLOBs + NDB
@item (Bug #6016) 
      Strange crash with blobs + different DATABASES
@item (Bug #5973) 
      ndb table belonging to different database shows up in show tables
@item (Bug #5872) 
      ALTER TABLE with blob from ndb table to myisam fails
@item (Bug #5844) 
      Failing mysql-test-run leaves stray NDB processes behind
@item (Bug #5824) 
      HELP text messed up in ndb_mgm
@item (Bug #5786) 
      Duplicate key error after restore
@item (Bug #5785) 
      lock timeout during concurrent update
@item (Bug #5782) 
      Unknown error when using LIMIT with ndb table
@item (Bug #5756) 
      RESTART node from ndb_mgm fails
@item A few more not reported bugs fixed
@end itemize

@node MySQL Cluster news-4.1.7, MySQL Cluster news-4.1.6, MySQL Cluster news-4.1.8, MySQL Cluster change history
@appendixsubsec MySQL Cluster-4.1.7 (23 Oct 2004)

Functionality added or changed:
@itemize @bullet
@item
Optimization 1: Improved performance on index scans. Measured 30% performance increase on query which do large amounts of index scans.
@item
Optimization 2: Improved performance on primary key lookups. Around double performance for autocommitted primary key lookups.
@item
Optimization 3: Improved performance when using blobs by avoiding usage of exclusive locks for blobs.
@end itemize

Bugs fixed:
@itemize @bullet
@item
A few bugs fixed.
@end itemize

@node MySQL Cluster news-4.1.6, MySQL Cluster news-4.1.5, MySQL Cluster news-4.1.7, MySQL Cluster change history
@appendixsubsec MySQL Cluster-4.1.6 (10 Oct 2004)

Functionality added or changed:
@itemize @bullet
@item
Limited character set support for storage engine NDBCLUSTER:

@multitable @columnfractions .40 .60
@item Char set   @tab Collation
@item big5       @tab big5_chinese_ci
@item            @tab big5_bin
@item binary     @tab binary
@item euckr      @tab euckr_korean_ci
@item            @tab euckr_bin
@item gb2312     @tab gb2312_chinese_ci
@item            @tab gb2312_bin
@item gbk        @tab gbk_chinese_ci
@item            @tab gbk_bin
@item latin1     @tab latin1_swedish_ci
@item            @tab latin1_bin
@item sjis       @tab sjis_japanese_ci
@item            @tab sjis_bin
@item tis620     @tab tis620_bin
@item ucs2       @tab ucs2_general_ci
@item            @tab ucs2_bin
@item ujis       @tab ujis_japanese_ci
@item            @tab ujis_bin
@item utf8       @tab utf8_general_ci
@item            @tab utf8_bin
@end multitable


@item
The SCI Transporter has been brought up-to-date with all changes and
now works and has been documented as well.

@c @item
@c A performance improvement on primary key access with constants have been
@c made which executes all accesses in one batch for improved performance
@c when many tables are const.

@item
Optimizations when several clients to a MySQL Server access ndb tables.

@item
Added more checks and warnings for erroneous and unappropriate cluster configurations.

@item
@code{SHOW TABLES} now directly shows ndb tables created on a different mysql server,
i.e. without a prior table access.

@item
Enhanced support for starting MySQL Server independently of ndbd and ndb_mgmd.

@item
Clear text ndb error messages provided by executing @code{SHOW WARNINGS} after
an error has occured which relates to the ndb storage engine.

@end itemize

Bugs fixed:
@itemize @bullet
@item
Quite a few bugs fixed.

@end itemize

@node MySQL Cluster news-4.1.5, MySQL Cluster news-4.1.4, MySQL Cluster news-4.1.6, MySQL Cluster change history
@appendixsubsec MySQL Cluster-4.1.5 (16 Sep 2004)

Functionality added or changed:
@itemize @bullet
@item
Many queries in MySQL Cluster are executed as range scans or full
table scans. All queries that don't use a unique hash index or the
primary hash index will use this access method. In a distributed
system it is crucial that batching is properly performed.

In previous version the batch size was fixed to 16 per storage node.
In this version it is configurable per MySQL Server. So for queries
using lots of large scans it is appropriate to set this parameter
rather large and for queries using lots of small scans only fetching
a small amount of records it is appropriate to set it low.

The performance of queries can easily change as much as 40% based on
how this variable is set.

In future versions more logic will be made to assess the batch size
on per query basis. Thus the semantics of this new configuration
variable @code{ScanBatchSize} is likely to change.

@item
The fixed size overhead of the ndbd process was greatly decreased. Also
overhead per operation record was greatly decreased and also overhead
per table and index was greatly decreased.

A number of new configuration variables was introduced to be able to
configure more buffers in the system. Configuration variables to
specify the number of tables, unique hash indexes and ordered indexes
was introduced as well.

New configuration variables:
@code{MaxNoOfOrderedIndexes}, @code{MaxNoOfUniqueHashIndexes}

Configuration variables no longer used:
@code{MaxNoOfIndexes} (split into the two above).

@item
In previous versions @code{ALTER TABLE}, @code{TRUNCATE TABLE}, and @code{LOAD
DATA} were performed as one big transaction. In this version, all those
statements will be automatically separated into a number of transactions.

This removes the limitation that one could not change very large tables
due to the @code{MaxNoOfConcurrentOperations} parameter.

@item
The online backup feature of MySQL Cluster now also backs up the
indexes such that the restore ensures that both data and indexes are
restored.

@item
In previous versions it was not possible to use @code{NULL} in indexes. This
is now possible in all indexes.

@item
Much work has been put onto making @code{AUTO_INCREMENT} features work as for
other table handlers. Autoincrements as a partial key is still only
supported by @code{MyISAM}.

@item
In previous version,s @command{mysqld} would crash if the cluster wasn't
started and the @code{--ndbcluster} option was used. Now @command{mysqld}
will handle cluster crashes and not started without crashing.

@item
The @code{-i} option for initial startup has been removed from
@command{ndbd}. Initial startup still can be specified by using the
@code{--initial} option. The reason is to ensure that it is clearer what
takes place when using the @code{--initial} option. This option completely
removes all data from the disk and should only be used at initial start, in
certain software upgrade cases, and in some cases when node restarts don't
work as a workaround.

@item
The management client (@command{ndb_mgm}) now has more commands and more
information is printed in some commands such as @code{show}.

@item
In previous versions, the files were called @file{ndb_0..} when it wasn't
possible to allocate a node ID when starting the node. To ensure
that files are not so easily overwritten, these files are now
named @file{ndb_pid..}, where pid is the process ID assigned by the OS.

@item
The default parameters have changed for @command{ndb_mgmd} and
@command{ndbd}.  Yn particular, they are now started as daemons by default.
The @code{-n} option was removed since it could confusion as to whether its
meaning is nostart or nodaemon.

@item
In the configuration file, you can now use @code{[NDBD]} as an alias for
@code{[DB]}, @code{[MYSQLD]} as an alias for @code{[API]}, and
@code{[NDB_MGMD]} as an alias for @code{[MGM]}.

@item
Many more checks of the consistency of the configuration have been
introduced to provide quicker feedback on configuration errors. 

@item
In the connect string, it is now possible to use both @samp{;} and @samp{,}
as the separator between entries. So "nodeid=2,host=localhost:2200" is
equivalent to "nodeid=2;host=localhost:2200".

In the configuration, it is possible to use @samp{:} or @samp{=} as the
assignment symbol. Thus @code{MaxNoOfOrderedIndexes : 128} and
@code{MaxNoOfOrderedIndexes = 128} are equivalent.

@item
The configuration variable names are now case insensitive so
@code{MaxNoOfOrderedIndexes: 128}
is equivalent to
@code{MAXNOOFORDEREDINDEXES = 128}.

@item
It is possible now to set the backup directory separately from the
@code{FileSystemPath} by using the @code{BackupDir} config variable.

Log files and trace files can now be put in any directory by setting
the @code{DataDir} configuration variable.

@code{FileSystemPath} is no longer mandatory and defaults to @code{DataDir}.

@item
It is now supported to perform queries involving tables from different
databases in MySQL.

@item
It is now possible to update the primary key.

@item
The performance of the ordered index has been greatly improved,
particularly the maintenance of the index at updates, inserts and
deletes.

@end itemize

Bugs fixed:
@itemize @bullet
@item
Quite a few bugs fixed.
@end itemize

@node MySQL Cluster news-4.1.4, MySQL Cluster news-5.0.1, MySQL Cluster news-4.1.5, MySQL Cluster change history
@appendixsubsec MySQL Cluster-4.1.4 (31 Aug 2004)

Functionality added or changed:
@itemize @bullet
@item
The names of the log files and trace files created by the @command{ndbd} and
@command{ndb_mgmd} processes have changed.

@item
Support for the many @code{BLOB} data types was introduced in this version.

@end itemize

Bugs fixed:
@itemize @bullet
@item
Quite a few bugs were fixed in the 4.1.4 release.
@end itemize

@node MySQL Cluster news-5.0.1, MySQL Cluster news-4.1.3, MySQL Cluster news-4.1.4, MySQL Cluster change history
@appendixsubsec MySQL Cluster-5.0.1 (27 Jul 2004)

Functionality added or changed:
@itemize @bullet
@item
This was the first MySQL Cluster release in 5.0. Actually almost all
attention was on getting 4.1 stable so it is not recommended to use
MySQL 5.0.1 for MySQL Cluster usage.
@end itemize

Bugs fixed:
@itemize @bullet
@item
@end itemize

@node MySQL Cluster news-4.1.3,  , MySQL Cluster news-5.0.1, MySQL Cluster change history
@appendixsubsec MySQL Cluster-4.1.3 (28 Jun 2004)

Functionality added or changed:
@itemize @bullet
@item
This was the first MySQL Cluster release so all the functionality was
new.
@end itemize

Bugs fixed:
@itemize @bullet
@item
Various bugs fixed in the development process leading up to 4.1.3.
@end itemize


@node Porting, Environment variables, News, Top
@appendix Porting to Other Systems

@cindex porting, to other systems

This appendix will help you port MySQL to other operating systems.
Do check the list of currently supported operating systems first.
@xref{Which OS}.
If you have created a new port of MySQL, please let us know so that
we can list it here and on our Web site (@uref{http://www.mysql.com/}),
recommending it to other users.

Note: If you create a new port of MySQL, you are free to copy and
distribute it under the GPL license, but it does not make you a
copyright holder of MySQL.

A working POSIX thread library is needed for the server. On Solaris 2.5
we use Sun PThreads (the native thread support in 2.4 and earlier
versions is not good enough), on Linux we use LinuxThreads by Xavier
Leroy, @email{Xavier.Leroy@@inria.fr}.

The hard part of porting to a new Unix variant without good native
thread support is probably to port MIT-pthreads. See
@file{mit-pthreads/README} and Programming POSIX Threads
(@uref{http://www.humanfactor.com/pthreads/}).

Up to MySQL 4.0.2, the MySQL distribution included a patched version of
Chris Provenzano's Pthreads from MIT (see the MIT Pthreads Web page at
@uref{http://www.mit.edu/afs/sipb/project/pthreads/} and a programming
introduction at @uref{http://www.mit.edu:8001/people/proven/IAP_2000/}).
These can be used for some operating systems that do not have POSIX threads.
@xref{MIT-pthreads}.

It is also possible to use another user level thread package named
FSU Pthreads (see @uref{http://moss.csc.ncsu.edu/~mueller/pthreads/}).
This implementation is being used for the SCO port.

See the @file{thr_lock.c} and @file{thr_alarm.c} programs in the @file{mysys}
directory for some tests/examples of these problems.

Both the server and the client need a working C++ compiler. We use @command{gcc}
on many platforms. Other compilers that are known to work are SPARCworks,
Sun Forte, Irix @command{cc}, HP-UX @command{aCC}, IBM AIX @command{xlC_r}), Intel
@command{ecc/icc} and Compaq @command{cxx}).

To compile only the client use @command{./configure --without-server}.

There is currently no support for only compiling the server, nor is it
likly to be added unless someone has a good reason for it.

If you want/need to change any @file{Makefile} or the configure script you
will also need GNU Automake and Autoconf.
@xref{Installing source tree}.

All steps needed to remake everything from the most basic files.

@example
/bin/rm */.deps/*.P
/bin/rm -f config.cache
aclocal
autoheader
aclocal
automake
autoconf
./configure --with-debug=full --prefix='your installation directory'

# The makefiles generated above need GNU make 3.75 or newer.
# (called gmake below)
gmake clean all install init-db
@end example

If you run into problems with a new port, you may have to do some debugging
of MySQL!
@xref{Debugging server}.

@strong{Note}: Before you start debugging @command{mysqld}, first get the test
programs @code{mysys/thr_alarm} and @code{mysys/thr_lock} to work.  This
will ensure that your thread installation has even a remote chance to work!

@menu
* Debugging server::            Debugging a MySQL Server
* Debugging client::            Debugging a MySQL Client
* The DBUG package::            The DBUG Package
* RTS-threads::                 Comments about RTS Threads
* Thread packages::             Differences Between Thread Packages
@end menu


@node Debugging server, Debugging client, Porting, Porting
@appendixsec Debugging a MySQL Server

@cindex server, debugging
@cindex debugging, server
@cindex crash

If you are using some functionality that is very new in MySQL,
you can try to run @command{mysqld} with the @code{--skip-new} (which will disable all
new, potentially unsafe functionality) or with @code{--safe-mode} which
disables a lot of optimization that may cause problems.
@xref{Crashing}.

If @command{mysqld} doesn't want to start, you should verify that you don't have
any @file{my.cnf} files that interfere with your setup!
You can check your @file{my.cnf} arguments with @command{mysqld --print-defaults}
and avoid using them by starting with @command{mysqld --no-defaults ...}.

If @command{mysqld} starts to eat up CPU or memory or if it ``hangs,'' you
can use @command{mysqladmin processlist status} to find out if someone is
executing a query that takes a long time.  It may be a good idea to
run @command{mysqladmin -i10 processlist status} in some window if you are
experiencing performance problems or problems when new clients can't connect.

The command @command{mysqladmin debug} will dump some information about
locks in use, used memory and query usage to the MySQL log file. This
may help solve some problems.  This command also provides some useful
information even if you haven't compiled MySQL for debugging!

If the problem is that some tables are getting slower and slower you
should try to optimize the table with @code{OPTIMIZE TABLE} or
@command{myisamchk}.  @xref{MySQL Database Administration}. You should also
check the slow queries with @code{EXPLAIN}.

You should also read the OS-specific section in this manual for
problems that may be unique to your environment.
@xref{Operating System Specific Notes}.

@menu
* Compiling for debugging::     Compiling MySQL for Debugging
* Making trace files::          Creating Trace Files
* Using gdb on mysqld::         Debugging @command{mysqld} under @command{gdb}
* Using stack trace::           Using a Stack Trace
* Using log files::             Using Log Files to Find Cause of Errors in @command{mysqld}
* Reproduceable test case::     Making a Test Case If You Experience Table Corruption
@end menu


@node Compiling for debugging, Making trace files, Debugging server, Debugging server
@appendixsubsec Compiling MySQL for Debugging

If you have some very specific problem, you can always try to debug
MySQL.  To do this you must configure MySQL with the
@code{--with-debug} or the @code{--with-debug=full} option.  You can check
whether MySQL was compiled with debugging by doing:
@command{mysqld --help}.  If the @code{--debug} flag is listed with the
options then you have debugging enabled.  @command{mysqladmin ver} also
lists the @command{mysqld} version as @command{mysql ... --debug} in this case.

If you are using @command{gcc} or @command{egcs}, the recommended @command{configure} line is:

@example
CC=gcc CFLAGS="-O2" CXX=gcc CXXFLAGS="-O2 -felide-constructors \
   -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql \
   --with-debug --with-extra-charsets=complex
@end example

This will avoid problems with the @code{libstdc++} library and with C++
exceptions (many compilers have problems with C++ exceptions in threaded
code) and compile a MySQL version with support for all character sets.

If you suspect a memory overrun error, you can configure MySQL
with @code{--with-debug=full}, which will install a memory allocation
(@code{SAFEMALLOC}) checker. However, running with @code{SAFEMALLOC} is
quite slow, so if you get performance problems you should start
@command{mysqld} with the @code{--skip-safemalloc} option. This will
disable the memory overrun checks for each call to @code{malloc()} and
@code{free()}.

If @command{mysqld} stops crashing when you compile it with
@code{--with-debug}, you probably have found a compiler bug or a timing
bug within MySQL.  In this case, you can try to add @code{-g} to
the @code{CFLAGS} and @code{CXXFLAGS} variables above and not use
@code{--with-debug}. If @command{mysqld} now dies, you can at least attach
to it with @command{gdb} or use @command{gdb} on the core file to find out
what happened.

When you configure MySQL for debugging you automatically enable a
lot of extra safety check functions that monitor the health of @command{mysqld}.
If they find something ``unexpected,'' an entry will be written to
@code{stderr}, which @command{safe_mysqld} directs to the error log!  This also
means that if you are having some unexpected problems with MySQL and
are using a source distribution, the first thing you should do is to
configure MySQL for debugging!  (The second thing is to
send mail to a MySQL mailing list and ask for help.
@xref{Mailing-list}.
Please use the
@command{mysqlbug} script for all bug reports or questions regarding the
MySQL version you are using!

In the Windows MySQL distribution, @code{mysqld.exe} is by
default compiled with support for trace files.


@node Making trace files, Using gdb on mysqld, Compiling for debugging, Debugging server
@appendixsubsec Creating Trace Files

If the @command{mysqld} server doesn't start or if you can cause it
to crash quickly, you can try to create a trace file to find the problem.

To do this, you must have a @command{mysqld} that has been compiled with
debugging support.
You can check this by executing @code{mysqld -V}.  If the version number
ends with @code{-debug}, it's compiled with support for trace files.

Start the @command{mysqld} server with a trace log in @file{/tmp/mysqld.trace}
on Unix or @file{C:\mysqld.trace} on Windows:

@example
shell> mysqld --debug
@end example

On Windows, you should also use the @code{--standalone} flag to not start
@command{mysqld} as a service.  In a console window, use this command:

@example
C:\> mysqld --debug --standalone
@end example

After this, you can use the @code{mysql.exe} command-line tool in a
second console window to reproduce the problem. You can stop the
@command{mysqld} server with @command{mysqladmin shutdown}.

Note that the trace file will become @strong{very big}!
If you want to generate a smaller trace file, you can use debugging options
something like this:

@command{mysqld --debug=d,info,error,query,general,where:O,/tmp/mysqld.trace}

This only prints information with the most interesting tags to the trace file.

If you make a bug report about this, please only send the lines from the
trace file to the appropriate mailing list where something seems to go
wrong! If you can't locate the wrong place, you can ftp the trace file,
together with a full bug report, to
@uref{ftp://ftp.mysql.com/pub/mysql/upload/} so that a MySQL
developer can take a look a this.

The trace file is made with the @strong{DBUG} package by Fred Fish.
@xref{The DBUG package}.


@node Using gdb on mysqld, Using stack trace, Making trace files, Debugging server
@appendixsubsec Debugging @command{mysqld} under @command{gdb}

@cindex gdb, using

On most systems you can also start @command{mysqld} from @command{gdb} to get
more information if @command{mysqld} crashes.

With some older @command{gdb} versions on Linux you must use @code{run
--one-thread} if you want to be able to debug @command{mysqld} threads.  In
this case, you can only have one thread active at a time.  We recommend you
to upgrade to gdb 5.1 ASAP as thread debugging works much better with this
version!

NTPL threads (the new thread library on Linux) may cause problems while
running @command{mysqld} under @command{gdb}. Some symptoms are:

@itemize @bullet
@item
@command{mysqld} hangs during startup (before it writes
 @code{ready for connections}).
@item
@command{mysqld} crashes during a
@code{pthread_mutex_lock()} or @code{pthread_mutex_unlock()} call.
@end itemize

In this case you should set the following environment variable
in the shell before starting @command{gdb}:

@example
LD_ASSUME_KERNEL=2.4.1
export LD_ASSUME_KERNEL
@end example

When running @command{mysqld} under @command{gdb}, you should disable
the stack trace with @code{--skip-stack-trace} to be able to catch
segfaults within @command{gdb}.

In MySQL 4.0.14 and above you should use the @code{--gdb} option to
mysqld.  This will install an interrupt handler for @code{SIGINT} (needed
to stop @command{mysqld} with @code{^C} to set breakpoints) and disable stack
tracing and core file handling.

It's very hard to debug MySQL under @command{gdb} if you do a lot of
new connections the whole time as @command{gdb} doesn't free the memory for
old threads.  You can avoid this problem by starting @command{mysqld} with
@code{-O thread_cache_size= 'max_connections +1'}.  In most cases just
using @code{-O thread_cache_size=5'} will help a lot!

If you want to get a core dump on Linux if @command{mysqld} dies with a
SIGSEGV signal, you can start @command{mysqld} with the @code{--core-file} option.
This core file can be used to make a backtrace that may help you
find out why @command{mysqld} died:

@example
shell> gdb mysqld core
gdb>   backtrace full
gdb>   exit
@end example

@xref{Crashing}.

If you are using @command{gdb} 4.17.x or above on Linux, you should install a
@file{.gdb} file, with the following information, in your current
directory:

@example
set print sevenbit off
handle SIGUSR1 nostop noprint
handle SIGUSR2 nostop noprint
handle SIGWAITING nostop noprint
handle SIGLWP nostop noprint
handle SIGPIPE nostop
handle SIGALRM nostop
handle SIGHUP nostop
handle SIGTERM nostop noprint
@end example

If you have problems debugging threads with @command{gdb}, you should download
gdb 5.x and try this instead. The new @command{gdb} version has very improved
thread handling!

Here is an example how to debug mysqld:

@example
shell> gdb /usr/local/libexec/mysqld
gdb> run
...
backtrace full # Do this when mysqld crashes
@end example

Include the above output in a mail generated with @command{mysqlbug} and
mail this to the general MySQL mailing list.
@xref{Mailing-list}.

If @command{mysqld} hangs you can try to use some system tools like
@code{strace} or @code{/usr/proc/bin/pstack} to examine where
@command{mysqld} has hung.

@example
strace /tmp/log libexec/mysqld
@end example

@findex DBI->trace
@findex trace DBI method
@tindex DBI_TRACE environment variable
@tindex Environment variable, DBI_TRACE
If you are using the Perl @code{DBI} interface, you can turn on
debugging information by using the @code{trace} method or by
setting the @code{DBI_TRACE} environment variable.


@node Using stack trace, Using log files, Using gdb on mysqld, Debugging server
@appendixsubsec Using a Stack Trace

On some operating systems, the error log will contain a stack trace if
@command{mysqld} dies unexpectedly. You can use this to find out where (and
maybe why) @command{mysqld} died. @xref{Error log}.  To get a stack trace,
you must not compile @command{mysqld} with the @code{-fomit-frame-pointer}
option to gcc. @xref{Compiling for debugging}.

If the error file contains something like the following:

@example
mysqld got signal 11;
The manual section 'Debugging a MySQL server' tells you how to use a
stack trace and/or the core file to produce a readable backtrace that may
help in finding out why mysqld died
Attempting backtrace. You can use the following information to find out
where mysqld died.  If you see no messages after this, something went
terribly wrong...
stack range sanity check, ok, backtrace follows
0x40077552
0x81281a0
0x8128f47
0x8127be0
0x8127995
0x8104947
0x80ff28f
0x810131b
0x80ee4bc
0x80c3c91
0x80c6b43
0x80c1fd9
0x80c1686
@end example

you can find where @command{mysqld} died by doing the following:

@enumerate
@item
Copy the preceding numbers to a file, for example @file{mysqld.stack}.

@item
Make a symbol file for the @command{mysqld} server:
@example
nm -n libexec/mysqld > /tmp/mysqld.sym
@end example

Note that most MySQL binary distributions (except for the "debug" packages,
where this information is included inside of the binaries themselves)
already ship with the above file, named @code{mysqld.sym.gz}.
In this case, you can simply unpack it by doing:

@example
gunzip < bin/mysqld.sym.gz > /tmp/mysqld.sym
@end example

@item
Execute @code{resolve_stack_dump -s /tmp/mysqld.sym -n mysqld.stack}.

This will print out where @command{mysqld} died. If this doesn't help you
find out why @command{mysqld} died, you should make a bug report and include
the output from the above command with the bug report.

Note however that in most cases it will not help us to just have a stack
trace to find the reason for the problem.  To be able to locate the bug
or provide a workaround, we would in most cases need to know the query
that killed @command{mysqld} and preferable a test case so that we can
repeat the problem!  @xref{Bug reports}.
@end enumerate


@node Using log files, Reproduceable test case, Using stack trace, Debugging server
@appendixsubsec Using Log Files to Find Cause of Errors in @command{mysqld}

Note that before starting @command{mysqld} with @code{--log} you should
check all your tables with @command{myisamchk}.
@xref{MySQL Database Administration}.

If @command{mysqld} dies or hangs, you should start @command{mysqld} with
@code{--log}.  When @command{mysqld} dies again, you can examine the end of
the log file for the query that killed @command{mysqld}.

If you are using @code{--log} without a file name, the log is stored in
the database directory as @file{@var{host_name}.log} In most cases it is the last
query in the log file that killed @command{mysqld}, but if possible you
should verify this by restarting @command{mysqld} and executing the found
query from the @command{mysql} command-line tools. If this works, you
should also test all complicated queries that didn't complete.

You can also try the command @code{EXPLAIN} on all @code{SELECT}
statements that takes a long time to ensure that @command{mysqld} is using
indexes properly. @xref{EXPLAIN, , @code{EXPLAIN}}.

You can find the queries that take a long time to execute by starting
@command{mysqld} with @code{--log-slow-queries}. @xref{Slow query log}.

If you find the text @code{mysqld restarted} in the error log file
(normally named @file{hostname.err}) you probably have found a query
that causes @command{mysqld} to fail.  If this happens, you should check all
your tables with @command{myisamchk} (@pxref{MySQL Database Administration}),
and test the queries in the MySQL log files to see if one doesn't
work.  If you find such a query, try first upgrading to the newest
MySQL version.  If this doesn't help and you can't find anything
in the @code{mysql} mail archive, you should report the bug to a MySQL
mailing list.
The mailing lists are described at
@uref{http://lists.mysql.com/}, which also has links to online
list archives.

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

It's not a good sign if @command{mysqld} did died unexpectedly,
but in this case one shouldn't investigate the @code{Checking table...}
messages but instead try to find out why @command{mysqld} died.


@c TODO: correct the spelling of this node to "Reproducible"

@node Reproduceable test case,  , Using log files, Debugging server
@appendixsubsec Making a Test Case If You Experience Table Corruption

If you get corrupted tables or if @command{mysqld} always fails after some
update commands, you can test whether this bug is reproducible by doing the
following:

@itemize @bullet
@item
Take down the MySQL daemon (with @command{mysqladmin shutdown}).
@item
Make a backup of the tables (to guard against the very unlikely case that
the repair will do something bad).
@item
Check all tables with @command{myisamchk -s database/*.MYI}.  Repair any
wrong tables with @command{myisamchk -r database/@var{table}.MYI}.
@item
Make a second backup of the tables.
@item
Remove (or move away) any old log files from the MySQL data
directory if you need more space.
@item
Start @command{mysqld} with @code{--log-bin}. @xref{Binary log}.
If you want to find a query that crashes @command{mysqld}, you should use
@code{--log --log-bin}.
@item
When you have gotten a crashed table, stop the @code{mysqld server}.
@item
Restore the backup.
@item
Restart the @command{mysqld} server @strong{without} @code{--log-bin}
@item
Re-execute the commands with @command{mysqlbinlog update-log-file | mysql}.
The update log is saved in the MySQL database directory with
the name @code{hostname-bin.#}.
@item
If the tables are corrupted again or you can get @command{mysqld} to die with the
above command, you have found reproducible bug that should be easy to
fix! FTP the tables and the binary log to
@uref{ftp://ftp.mysql.com/pub/mysql/upload/} and enter it into
our bugs system at @uref{http://bugs.mysql.com/}.
If you are a support customer, you can use the MySQL Customer Support Center
@uref{https://support.mysql.com/} to alert the MySQL team about the
problem and have it fixed as soon as possible.

@end itemize

You can also use the script @code{mysql_find_rows} to just execute some of the
update statements if you want to narrow down the problem.


@node Debugging client, The DBUG package, Debugging server, Porting
@appendixsec Debugging a MySQL Client

@cindex debugging, client
@cindex clients, debugging

To be able to debug a MySQL client with the integrated debug package,
you should configure MySQL with @code{--with-debug} or
@code{--with-debug=full}.
@xref{configure options,  , @command{configure} options}.

@tindex MYSQL_DEBUG environment variable
@tindex Environment variable, MYSQL_DEBUG
Before running a client, you should set the @code{MYSQL_DEBUG} environment
variable:

@example
shell> MYSQL_DEBUG=d:t:O,/tmp/client.trace
shell> export MYSQL_DEBUG
@end example

This causes clients to generate a trace file in @file{/tmp/client.trace}.

If you have problems with your own client code, you should attempt to
connect to the server and run your query using a client that is known to
work.  Do this by running @command{mysql} in debugging mode (assuming that you
have compiled MySQL with debugging on):

@example
shell> mysql --debug=d:t:O,/tmp/client.trace
@end example

This will provide useful information in case you mail a bug report.
@xref{Bug reports}.

If your client crashes at some 'legal' looking code, you should check
that your @file{mysql.h} include file matches your MySQL library file.
A very common mistake is to use an old @file{mysql.h} file from an old
MySQL installation with new MySQL library.


@node The DBUG package, RTS-threads, Debugging client, Porting
@appendixsec The DBUG Package

@cindex DBUG package

The MySQL server and most MySQL clients are compiled with the DBUG package
originally created by Fred Fish.  When you have configured MySQL for
debugging, this package makes it possible to get a trace file of what the
program is debugging.
@xref{Making trace files}.

This section summaries the argument values that you can specify in debug
options on the command line for MySQL programs that have been built with
debugging support. For more information about programming with the DBUG
package, see the DBUG manual in the @file{dbug} directory of MySQL source
distributions. It's best to use a recent distribution for MySQL 5.0 to get the
most updated DBUG manual.

You use the debug package by invoking a program with the
@code{--debug="..."} or the @code{-#...} option.

Most MySQL programs have a default debug string that will be
used if you don't specify an option to @code{--debug}.  The default
trace file is usually @code{/tmp/program_name.trace} on Unix and
@code{\program_name.trace} on Windows.

The debug control string is a sequence of colon-separated fields
as follows:

@example
<field_1>:<field_2>:...:<field_N>
@end example

Each field consists of a mandatory flag character followed by
an optional @samp{,} and comma-separated list of modifiers:

@example
flag[,modifier,modifier,...,modifier]
@end example

The currently recognized flag characters are:

@multitable @columnfractions .05 .95

@item @strong{Flag} @tab @strong{Description}

@item @code{d} @tab Enable output from DBUG_<N> macros for the current state. May be followed by a list of keywords which selects output only for the DBUG macros with that keyword. An empty list of keywords implies output for all macros.

@item @code{D} @tab Delay after each debugger output line. The argument is the number of tenths of seconds to delay, subject to machine capabilities. For example, @code{-#D,20} specifies a delay of two seconds.

@item @code{f} @tab Limit debugging and/or tracing, and profiling to the list of named functions.  Note that a null list disables all functions.   The appropriate @code{d} or @code{t} flags must still be given; this flag only limits their actions if they are enabled.

@item @code{F} @tab Identify the source file name for each line of debug or trace output.

@item @code{i} @tab Identify the process with the PID or thread ID for each line of debug or trace output.

@item @code{g} @tab Enable profiling.  Create a file called @file{dbugmon.out} containing information that can be used to profile the program.  May be followed by a list of keywords that select profiling only for the functions in that list.  A null list implies that all functions are considered.

@item @code{L} @tab Identify the source file line number for each line of debug or trace output.

@item @code{n} @tab Print the current function nesting depth for each line of debug or trace output.

@item @code{N} @tab Number each line of debug output.

@item @code{o} @tab Redirect the debugger output stream to the specified file.  The default output is @code{stderr}.

@item @code{O} @tab Like @code{o}, but the file is really flushed between each write. When needed, the file is closed and reopened between each write.

@item @code{p} @tab Limit debugger actions to specified processes. A process must be identified with the @code{DBUG_PROCESS} macro and match one in the list for debugger actions to occur.

@item @code{P} @tab Print the current process name for each line of debug or trace output.

@item @code{r} @tab When pushing a new state, do not inherit the previous state's function nesting level. Useful when the output is to start at the left margin.

@item @code{S} @tab Do function @code{_sanity(_file_,_line_)} at each debugged function until @code{_sanity()} returns something that differs from 0. (Mostly used with @code{safemalloc} to find memory leaks)

@item @code{t} @tab Enable function call/exit trace lines. May be followed by a list (containing only one modifier) giving a numeric maximum trace level, beyond which no output will occur for either debugging or tracing macros.  The default is a compile time option.

@end multitable

Some examples of debug control strings that might appear on a shell command
line (the @code{-#} is typically used to introduce a control string to an
application program) are:

@example
-#d:t
-#d:f,main,subr1:F:L:t,20
-#d,input,output,files:n
-#d:t:i:O,\\mysqld.trace
@end example

In MySQL, common tags to print (with the @code{d} option) are
@code{enter}, @code{exit}, @code{error}, @code{warning}, @code{info}, and
@code{loop}.


@node RTS-threads, Thread packages, The DBUG package, Porting
@appendixsec Comments about RTS Threads

@cindex RTS-threads
@cindex threads, RTS

I have tried to use the RTS thread packages with MySQL but
stumbled on the following problems:

They use old versions of many POSIX calls and it is very tedious to
make wrappers for all functions. I am inclined to think that it would
be easier to change the thread libraries to the newest POSIX
specification.

Some wrappers are already written. See @file{mysys/my_pthread.c} for more info.

At least the following should be changed:

@code{pthread_get_specific} should use one argument.
@code{sigwait} should take two arguments.
A lot of functions (at least @code{pthread_cond_wait},
@code{pthread_cond_timedwait()})
should return the error code on error. Now they return -1 and set @code{errno}.

Another problem is that user-level threads use the @code{ALRM} signal and this
aborts a lot of functions (@code{read}, @code{write}, @code{open}...).
MySQL should do a retry on interrupt on all of these but it is
not that easy to verify it.

The biggest unsolved problem is the following:

To get thread-level alarms I changed @file{mysys/thr_alarm.c} to wait between
alarms with @code{pthread_cond_timedwait()}, but this aborts with error
@code{EINTR}.  I tried to debug the thread library as to why this happens,
but couldn't find any easy solution.

If someone wants to try MySQL with RTS threads I suggest the
following:

@itemize @bullet
@item
Change functions MySQL uses from the thread library to POSIX.
This shouldn't take that long.
@item
Compile all libraries with the @code{-DHAVE_rts_threads}.
@item
Compile @code{thr_alarm}.
@item
If there are some small differences in the implementation, they may be fixed
by changing @file{my_pthread.h} and @file{my_pthread.c}.
@item
Run @code{thr_alarm}. If it runs without any ``warning,'' ``error,'' or aborted
messages, you are on the right track. Here is a successful run on
Solaris:
@example
Main thread: 1
Thread 0 (5) started
Thread: 5  Waiting
process_alarm
Thread 1 (6) started
Thread: 6  Waiting
process_alarm
process_alarm
thread_alarm
Thread: 6  Slept for 1 (1) sec
Thread: 6  Waiting
process_alarm
process_alarm
thread_alarm
Thread: 6  Slept for 2 (2) sec
Thread: 6  Simulation of no alarm needed
Thread: 6  Slept for 0 (3) sec
Thread: 6  Waiting
process_alarm
process_alarm
thread_alarm
Thread: 6  Slept for 4 (4) sec
Thread: 6  Waiting
process_alarm
thread_alarm
Thread: 5  Slept for 10 (10) sec
Thread: 5  Waiting
process_alarm
process_alarm
thread_alarm
Thread: 6  Slept for 5 (5) sec
Thread: 6  Waiting
process_alarm
process_alarm

...
thread_alarm
Thread: 5  Slept for 0 (1) sec
end
@end example
@end itemize


@node Thread packages,  , RTS-threads, Porting
@appendixsec Differences Between Thread Packages

@cindex thread packages, differences between

MySQL is very dependent on the thread package used. So when
choosing a good platform for MySQL, the thread package is very
important.

There are at least three types of thread packages:

@itemize @bullet
@item
User threads in a single process. Thread switching is managed with
alarms and the threads library manages all non-thread-safe functions
with locks. Read, write and select operations are usually managed with a
thread-specific select that switches to another thread if the running
threads have to wait for data.  If the user thread packages are
integrated in the standard libs (FreeBSD and BSDI threads) the thread
package requires less overhead than thread packages that have to map all
unsafe calls (MIT-pthreads, FSU Pthreads and RTS threads).  In some
environments (for example, SCO), all system calls are thread-safe so the
mapping can be done very easily (FSU Pthreads on SCO).  Downside: All
mapped calls take a little time and it's quite tricky to be able to
handle all situations. There are usually also some system calls that are
not handled by the thread package (like MIT-pthreads and sockets). Thread
scheduling isn't always optimal.
@item
User threads in separate processes. Thread switching is done by the
kernel and all data are shared between threads.  The thread package
manages the standard thread calls to allow sharing data between threads.
LinuxThreads is using this method.  Downside: Lots of processes. Thread
creating is slow. If one thread dies the rest are usually left hanging
and you must kill them all before restarting. Thread switching is
somewhat expensive.
@item
Kernel threads. Thread switching is handled by the thread library or the
kernel and is very fast. Everything is done in one process, but on some
systems, @command{ps} may show the different threads. If one thread aborts, the
whole process aborts. Most system calls are thread-safe and should
require very little overhead.  Solaris, HP-UX, AIX and OSF/1 have kernel
threads.
@end itemize

In some systems kernel threads are managed by integrating user
level threads in the system libraries. In such cases, the thread
switching can only be done by the thread library and the kernel isn't
really ``thread aware.''




@node Environment variables, Regexp, Porting, Top
@appendix Environment Variables

@cindex environment variables, list of

This appendix lists all the environment variables that are used directly or
indirectly by MySQL. Most of these can also be found in other
places in this manual.

Note that any options on the command line take precedence over
values specified in option files and environment variables, and
values in option files take precedence over values in environment
variables.

In many cases, it's preferable to use an option file instead of environment
variables to modify the behavior of MySQL. @xref{Option files}.

@tindex CXX environment variable
@tindex Environment variable, CXX
@tindex CC environment variable
@tindex Environment variable, CC
@tindex CFLAGS environment variable
@tindex Environment variable, CFLAGS
@tindex CXXFLAGS environment variable
@tindex Environment variable, CXXFLAGS
@tindex DBI_USER environment variable
@tindex Environment variable, DBI_USER
@tindex DBI_TRACE environment variable
@tindex Environment variable, DBI_TRACE
@tindex HOME environment variable
@tindex Environment variable, HOME
@tindex LD_RUN_PATH environment variable
@tindex Environment variable, LD_RUN_PATH
@tindex MYSQL_DEBUG environment variable
@tindex Environment variable, MYSQL_DEBUG
@tindex MYSQL_HISTFILE environment variable
@tindex Environment variable, MYSQL_HISTFILE
@tindex MYSQL_HOST environment variable
@tindex Environment variable, MYSQL_HOST
@tindex MYSQL_PS1 environment variable
@tindex Environment variable, MYSQL_PS1
@tindex MYSQL_PWD environment variable
@tindex Environment variable, MYSQL_PWD
@tindex MYSQL_TCP_PORT environment variable
@tindex Environment variable, MYSQL_TCP_PORT
@tindex MYSQL_UNIX_PORT environment variable
@tindex Environment variable, MYSQL_UNIX_PORT
@tindex PATH environment variable
@tindex Environment variable, PATH
@tindex TMPDIR environment variable
@tindex Environment variable, TMPDIR
@tindex TZ environment variable
@tindex Environment variable, TZ
@tindex UMASK_DIR environment variable
@tindex Environment variable, UMASK_DIR
@tindex UMASK environment variable
@tindex Environment variable, UMASK
@tindex USER environment variable
@tindex Environment variable, USER

@multitable @columnfractions .25 .70
@item @strong{Variable} @tab @strong{Description}
@item @code{CXX}  @tab The name of your C++ compiler (for running @command{configure}).
@item @code{CC}  @tab The name of your C compiler (for running @command{configure}).
@item @code{CFLAGS} @tab Flags for your C compiler (for running @command{configure}).
@item @code{CXXFLAGS} @tab Flags for your C++ compiler (for running @command{configure}).
@item @code{DBI_USER} @tab The default username for Perl DBI.
@item @code{DBI_TRACE} @tab Trace options for Perl DBI.
@item @code{HOME} @tab The default path for the @command{mysql} history file is @file{$HOME/.mysql_history}.
@item @code{LD_RUN_PATH} @tab Used to specify where your @file{libmysqlclient.so} is located.
@item @code{MYSQL_DEBUG} @tab Debug trace options when debugging.
@item @code{MYSQL_HISTFILE} @tab The path to the @command{mysql} history file. If this variable is set, its value overrides the default of @file{$HOME/.mysql_history}.
@item @code{MYSQL_HOST} @tab The default hostname used by the @command{mysql} command-line client.
@item @code{MYSQL_PS1} @tab The command prompt to use in the @command{mysql} command-line client.
@item @code{MYSQL_PWD} @tab The default password when connecting to @command{mysqld}. Note that use of this is insecure!  @xref{Password security}.
@item @code{MYSQL_TCP_PORT} @tab The default TCP/IP port number.
@item @code{MYSQL_UNIX_PORT} @tab The default Unix socket filename; used for connections to @code{localhost}.
@item @code{PATH} @tab Used by the shell to find MySQL programs.
@item @code{TMPDIR} @tab The directory where temporary files are created.
@item @code{TZ} @tab This should be set to your local time zone. @xref{Timezone problems}.
@item @code{UMASK_DIR} @tab The user-directory creation mask when creating directories. Note that this is ANDed with @code{UMASK}!
@item @code{UMASK} @tab The user-file creation mask when creating files.
@item @code{USER} @tab The default username on Windows and NetWare to use when
connecting to @command{mysqld}.
@end multitable




@node Regexp, GPL license, Environment variables, Top
@appendix MySQL Regular Expressions

@cindex regex
@cindex regular expression syntax, described
@cindex syntax, regular expression

A regular expression is a powerful way of specifying a pattern for a complex
search.

MySQL uses Henry Spencer's implementation of regular expressions, which is
aimed at conformance with POSIX 1003.2.
@xref{Credits}.
MySQL uses the extended version to support pattern-matching operations
performed with the @code{REGEXP} operator in SQL statements.
@xref{Pattern matching}.

This appendix is a summary, with examples, of the special characters and
constructs that can be used in MySQL for @code{REGEXP} operations.
It does not contain all the details that can be found in
Henry Spencer's @code{regex(7)} manual page. That manual page is
included in MySQL source distributions, in the @file{regex.7} file under the
@file{regex} directory.

A regular expression describes a set of strings. The simplest regular
expression is one that has no special characters in it. For example, the
regular expression @code{hello} matches @code{hello} and nothing else.

Non-trivial regular expressions use certain special constructs so that
they can match more than one string. For example, the regular expression
@code{hello|word} matches either the string @code{hello} or the string
@code{word}.

As a more complex example, the regular expression @code{B[an]*s} matches any
of the strings @code{Bananas}, @code{Baaaaas}, @code{Bs}, and any other
string starting with a @code{B}, ending with an @code{s}, and containing any
number of @code{a} or @code{n} characters in between.

A regular expression for the @code{REGEXP} operator may use any of the
following special characters and constructs:

@table @code
@item ^
Match the beginning of a string.
@example
mysql> SELECT 'fo\nfo' REGEXP '^fo$';                   -> 0
mysql> SELECT 'fofo' REGEXP '^fo';                      -> 1
@end example
@item $
Match the end of a string.
@example
mysql> SELECT 'fo\no' REGEXP '^fo\no$';                 -> 1
mysql> SELECT 'fo\no' REGEXP '^fo$';                    -> 0
@end example
@item .
Match any character (including carriage return and newline).
@example
mysql> SELECT 'fofo' REGEXP '^f.*$';                    -> 1
mysql> SELECT 'fo\r\nfo' REGEXP '^f.*$';                -> 1
@end example
@item a*
Match any sequence of zero or more @code{a} characters.
@example
mysql> SELECT 'Ban' REGEXP '^Ba*n';                     -> 1
mysql> SELECT 'Baaan' REGEXP '^Ba*n';                   -> 1
mysql> SELECT 'Bn' REGEXP '^Ba*n';                      -> 1
@end example
@item a+
Match any sequence of one or more @code{a} characters.
@example
mysql> SELECT 'Ban' REGEXP '^Ba+n';                     -> 1
mysql> SELECT 'Bn' REGEXP '^Ba+n';                      -> 0
@end example
@item a?
Match either zero or one @code{a} character.
@example
mysql> SELECT 'Bn' REGEXP '^Ba?n';                      -> 1
mysql> SELECT 'Ban' REGEXP '^Ba?n';                     -> 1
mysql> SELECT 'Baan' REGEXP '^Ba?n';                    -> 0
@end example
@item de|abc
Match either of the sequences @code{de} or @code{abc}.
@example
mysql> SELECT 'pi' REGEXP 'pi|apa';                     -> 1
mysql> SELECT 'axe' REGEXP 'pi|apa';                    -> 0
mysql> SELECT 'apa' REGEXP 'pi|apa';                    -> 1
mysql> SELECT 'apa' REGEXP '^(pi|apa)$';                -> 1
mysql> SELECT 'pi' REGEXP '^(pi|apa)$';                 -> 1
mysql> SELECT 'pix' REGEXP '^(pi|apa)$';                -> 0
@end example
@item (abc)*
Match zero or more instances of the sequence @code{abc}.
@example
mysql> SELECT 'pi' REGEXP '^(pi)*$';                    -> 1
mysql> SELECT 'pip' REGEXP '^(pi)*$';                   -> 0
mysql> SELECT 'pipi' REGEXP '^(pi)*$';                  -> 1
@end example
@item @{1@}
@itemx @{2,3@}
@code{@{n@}} or @code{@{m,n@}} notation provides
a more general way of writing regular expressions that match many
occurrences of the previous atom (or ``piece'') of the pattern.
@code{m} and @code{n} are integers.

@table @code
@item a*
Can be written as @code{a@{0,@}}.
@item a+
Can be written as @code{a@{1,@}}.
@item a?
Can be written as @code{a@{0,1@}}.
@end table

To be more precise, @code{a@{n@}} matches exactly @code{n} instances of
@code{a}.
@code{a@{n,@}} matches @code{n} or more instances of @code{a}.
@code{a@{m,n@}} matches @code{m} through @code{n} instances of @code{a},
inclusive.

@code{m} and @code{n} must be in the range from @code{0} to
@code{RE_DUP_MAX} (default 255), inclusive.  If both @code{m} and @code{n}
are given, @code{m} must be less than or equal to @code{n}.

@example
mysql> SELECT 'abcde' REGEXP 'a[bcd]@{2@}e';              -> 0
mysql> SELECT 'abcde' REGEXP 'a[bcd]@{3@}e';              -> 1
mysql> SELECT 'abcde' REGEXP 'a[bcd]@{1,10@}e';           -> 1
@end example

@item [a-dX]
@itemx [^a-dX]
Matches any character that is (or is not, if ^ is used) either @code{a},
@code{b}, @code{c}, @code{d} or @code{X}.  A @code{-} character between two other
characters forms a range that matches all characters from the first
character to the second. For example, @code{[0-9]} matches any decimal
digit.  To include a literal @code{]} character, it must immediately follow
the opening bracket @code{[}.  To include a literal @code{-} character, it
must be written first or last.  Any character that does not have a defined
special meaning inside a @code{[]} pair matches only itself.

@example
mysql> SELECT 'aXbc' REGEXP '[a-dXYZ]';                 -> 1
mysql> SELECT 'aXbc' REGEXP '^[a-dXYZ]$';               -> 0
mysql> SELECT 'aXbc' REGEXP '^[a-dXYZ]+$';              -> 1
mysql> SELECT 'aXbc' REGEXP '^[^a-dXYZ]+$';             -> 0
mysql> SELECT 'gheis' REGEXP '^[^a-dXYZ]+$';            -> 1
mysql> SELECT 'gheisa' REGEXP '^[^a-dXYZ]+$';           -> 0
@end example

@item [.characters.]
Within a bracket expression (written using @code{[} and @code{]}),
matches the sequence of characters of that collating element. @code{characters}
is either a single character or a character name like @code{newline}.
You can find the full list of character names in the @file{regexp/cname.h}
file.

@example
mysql> SELECT '~' REGEXP '[[.~.]]';                     -> 1
mysql> SELECT '~' REGEXP '[[.tilde.]]';                 -> 1
@end example

@item [=character_class=]
Within a bracket expression (written using @code{[} and @code{]}),
@code{[=character_class=]} represents
an equivalence class. It matches all characters with the same collation
value, including itself.
For example, if @code{o} and @code{(+)} are the members of an
equivalence class, then @code{[[=o=]]}, @code{[[=(+)=]]}, and
@code{[o(+)]} are all synonymous.
An equivalence class may not be used as an endpoint of a range.

@item [:character_class:]
Within a bracket expression (written using @code{[} and @code{]}),
@code{[:character_class:]} represents a character class that matches all
characters belonging to that class. The standard class names are:

@multitable @columnfractions .10 .90
@item @code{alnum}  @tab Alphanumeric characters
@item @code{alpha}  @tab Alphabetic characters
@item @code{blank}  @tab Whitespace characters
@item @code{cntrl}  @tab Control characters
@item @code{digit}  @tab Digit characters
@item @code{graph}  @tab Graphic characters
@item @code{lower}  @tab Lowercase alphabetic characters
@item @code{print}  @tab Graphic or space characters
@item @code{punct}  @tab Punctuation characters
@item @code{space}  @tab Space, tab, newline, and carriage return
@item @code{upper}  @tab Uppercase alphabetic characters
@item @code{xdigit} @tab Hexadecimal digit characters
@end multitable

These stand for the character classes defined in the @code{ctype(3)} manual
page. A particular locale may provide other class names.
A character class may not be used as an endpoint of a range.

@example
mysql> SELECT 'justalnums' REGEXP '[[:alnum:]]+';       -> 1
mysql> SELECT '!!' REGEXP '[[:alnum:]]+';               -> 0
@end example

@item [[:<:]]
@itemx [[:>:]]
These markers stand for word boundaries. They match the beginning and end of
words, respectively.  A word is a sequence of word characters that is not
preceded by or followed by word characters. A word character is an
alphanumeric character in the @code{alnum} class or an underscore
(@code{_}).

@example
mysql> SELECT 'a word a' REGEXP '[[:<:]]word[[:>:]]';   -> 1
mysql> SELECT 'a xword a' REGEXP '[[:<:]]word[[:>:]]';  -> 0
@end example

@end table

To use a literal instance of a special character in a regular expression,
precede it by two backslash (\) characters. The MySQL parser
interprets one of the backslashes, and the regular expression library
interprets the other. For example, to match the string @code{1+2} that
contains the special @code{+} character, only the last of the following
regular expressions is the correct one:

@example
mysql> SELECT '1+2' REGEXP '1+2';                       -> 0
mysql> SELECT '1+2' REGEXP '1\+2';                      -> 0
mysql> SELECT '1+2' REGEXP '1\\+2';                     -> 1
@end example


@node GPL license, MySQL FLOSS License Exception, Regexp, Top
@appendix GNU General Public License

@cindex GPL, General Public License
@cindex GPL, GNU General Public License

@center Version 2, June 1991

@display
Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA  02111-1307, USA

Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@end display

@heading Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software---to make sure the software is free for all its users.  This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it.  (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.)  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.

  To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the
source code.  And you must show them these terms so they know their
rights.

  We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

  Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

  Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary.  To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.

  The precise terms and conditions for copying, distribution and
modification follow.

@iftex
@heading TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@end iftex
@ifinfo
@center GNU GENERAL PUBLIC LICENSE
@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@end ifinfo

@enumerate 0
@item
This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License.  The ``Program'', below,
refers to any such program or work, and a ``work based on the Program''
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language.  (Hereinafter, translation is included without limitation in
the term ``modification''.)  Each licensee is addressed as ``you''.

Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.

@item
You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.

You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.

@item
You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

@enumerate a
@item
You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.

@item
You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.

@item
If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License.  (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
@end enumerate

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.

In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

@item
You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:

@enumerate a
@item
Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,

@item
Accompany it with a written offer, valid for at least three
years, to give any third-party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,

@item
Accompany it with the information you received as to the offer
to distribute corresponding source code.  (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
@end enumerate

The source code for a work means the preferred form of the work for
making modifications to it.  For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable.  However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.

If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.

@item
You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License.  Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.

@item
You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Program or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.

@item
Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.

@item
If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all.  For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

@item
If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded.  In such case, this License incorporates
the limitation as if written in the body of this License.

@item
The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

Each version is given a distinguishing version number.  If the Program
specifies a version number of this License which applies to it and ``any
later version'', you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation.  If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.

@item
If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission.  For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this.  Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.

@iftex
@heading NO WARRANTY
@end iftex
@ifinfo
@center NO WARRANTY
@end ifinfo

@item
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.

@item
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
@end enumerate

@iftex
@heading END OF TERMS AND CONDITIONS
@end iftex
@ifinfo
@center END OF TERMS AND CONDITIONS
@end ifinfo

@page
@heading How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the ``copyright'' line and a pointer to where the full notice is found.

@smallexample
@var{one line to give the program's name and a brief idea of what it does.}
Copyright (C) @var{yyyy}  @var{name of author}

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
@end smallexample

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:

@smallexample
Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author}
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
@end smallexample

The hypothetical commands @samp{show w} and @samp{show c} should show
the appropriate parts of the General Public License.  Of course, the
commands you use may be called something other than @samp{show w} and
@samp{show c}; they could even be mouse-clicks or menu items---whatever
suits your program.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a ``copyright disclaimer'' for the program, if
necessary.  Here is a sample; alter the names:

@example
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.

@var{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
@end example

This General Public License does not permit incorporating your program into
proprietary programs.  If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library.  If this is what you want to do, use the GNU Library General
Public License instead of this License.

@page



@node MySQL FLOSS License Exception, Function Index, GPL license, Top
@appendix MySQL FLOSS License Exception

@cindex GPL, MySQL FLOSS License Exception
@cindex License

@center Version 0.2, July 2004

The MySQL AB Exception for Free/Libre and Open Source Software-only
Applications Using MySQL Client Libraries (the ``FLOSS Exception'').

@heading Exception Intent

We want specified Free/Libre and Open Source Software (``FLOSS'') applications
to be able to use specified GPL-licensed MySQL client libraries (the
``Program'') despite the fact that not all FLOSS licenses are compatible with
version 2 of the GNU General Public License (the ``GPL''). 

@heading Legal Terms and Conditions

As a special exception to the terms and conditions of version 2.0 of the
GPL:

@enumerate
@item
You are free to distribute a Derivative Work that is formed entirely from
the Program and one or more works (each, a ``FLOSS Work'') licensed under
one or more of the licenses listed below in section 1, as long as:

@enumerate a
@item
You obey the GPL in all respects for the Program and the Derivative
Work, except for identifiable sections of the Derivative Work which
are not derived from the Program, and which can reasonably be
considered independent and separate works in themselves, 

@item
all identifiable sections of the Derivative Work which are not
derived from the Program, and which can reasonably be considered
independent and separate works in themselves,

@table @asis
@item i
are distributed subject to one of the FLOSS licenses listed below, and
@item ii
the object code or executable form of those sections are
accompanied by the complete corresponding machine-readable
source code for those sections on the same medium and under the
same FLOSS license as the corresponding object code or
executable forms of those sections, and
@end table

@item
any works which are aggregated with the Program or with a Derivative
Work on a volume of a storage or distribution medium in accordance
with the GPL, can reasonably be considered independent and separate
works in themselves which are not derivatives of either the Program,
a Derivative Work or a FLOSS Work.
@end enumerate

If the above conditions are not met, then the Program may only be copied,
modified, distributed or used under the terms and conditions of the GPL or
another valid licensing option from MySQL AB.


@item FLOSS License List

@multitable @columnfractions .60 .40
@item @strong{License name}                                 @tab @strong{Version(s)/Copyright Date}
@item Academic Free License                                 @tab 2.0
@item Apache Software License                               @tab 1.0/1.1/2.0
@item Apple Public Source License                           @tab 2.0
@item Artistic license                                      @tab From Perl 5.8.0
@item BSD license                                           @tab "July 22 1999"
@item Common Public License                                 @tab 1.0
@item GNU Library or "Lesser" General Public License (LGPL) @tab 2.0/2.1
@item Jabber Open Source License                            @tab 1.0
@item MIT license                                           @tab -
@item Mozilla Public License (MPL)                          @tab 1.0/1.1
@item Open Software License                                 @tab 2.0
@item PHP License                                           @tab 3.0
@item Python license (CNRI Python License)                  @tab -
@item Python Software Foundation License                    @tab 2.1.1
@item Sleepycat License                                     @tab "1999"
@item W3C License                                           @tab "2001"
@item X11 License                                           @tab "2001"
@item Zlib/libpng License                                   @tab -
@item Zope Public License                                   @tab 2.0
@end multitable

Due to the many variants of some of the above licenses, we require that any
version follow the 2003 version of the Free Software Foundation's Free
Software Definition (@uref{http://www.gnu.org/philosophy/free-sw.html}) or version
1.9 of the Open Source Definition by the Open Source Initiative
(@uref{http://www.opensource.org/docs/definition.php}).


@item Definitions

@enumerate a
@item
Terms used, but not defined, herein shall have the meaning provided in
the GPL.
@item
Derivative Work means a derivative work under copyright law.
@end enumerate


@item Applicability
This FLOSS Exception applies to all Programs that contain a notice placed by
MySQL AB saying that the Program may be distributed under the terms of this
FLOSS Exception.  If you create or distribute a work which is a Derivative
Work of both the Program and any other work licensed under the GPL, then
this FLOSS Exception is not available for that work; thus, you must remove
the FLOSS Exception notice from that work and comply with the GPL in all
respects, including by retaining all GPL notices.  You may choose to
redistribute a copy of the Program exclusively under the terms of the GPL by
removing the FLOSS Exception notice from that copy of the Program, provided
that the copy has never been modified by you or any third party.
@end enumerate

@page



@node Function Index, Concept Index, MySQL FLOSS License Exception, Top
@unnumbered SQL Command, Type, and Function Index

@printindex fn

@page


@node Concept Index,  , Function Index, Top
@unnumbered Concept Index

@printindex cp




@bye
