InnoDB Engine in MySQL-Max- 3.23.53/MySQL-4.0.4
InnoDB Engine in MySQL-Max- 3.23.53/MySQL-4.0.4
InnoDB Engine in MySQL-Max- 3.23.53/MySQL-4.0.4
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 1 de 45<br />
<strong>InnoDB</strong> home<br />
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>-<strong>Max</strong>-<br />
<strong>3.23.53</strong>/<strong>MySQL</strong>-<strong>4.0.4</strong><br />
The Up-to-Date Reference Manual of <strong>InnoDB</strong><br />
Updated October 14, 2002: <strong>MySQL</strong>-<strong>3.23.53</strong> is released<br />
Updated October 2, 2002: <strong>MySQL</strong>-<strong>4.0.4</strong> is released<br />
Updated September 30, 2002: Added to section 8.5 a note that CREATE TABLE commits the current<br />
<strong>InnoDB</strong> transaction if the <strong>MySQL</strong> b<strong>in</strong>logg<strong>in</strong>g is used<br />
Updated August 27, 2002: Added to sections 4.2 and 4.3 tips on new commands SET<br />
UNIQUE_CHECKS=0 and SET FOREIGN_KEY_CHECKS=0<br />
Updated August 12, 2002: Improved section 8.8 about how to cope with deadlocks<br />
• 1 <strong>InnoDB</strong> tables overview<br />
• 1.1 Different <strong>MySQL</strong>/<strong>InnoDB</strong> distributions<br />
• 2 <strong>InnoDB</strong> startup options<br />
• 3 Creat<strong>in</strong>g an <strong>InnoDB</strong> database<br />
• 3.1 If someth<strong>in</strong>g goes wrong <strong>in</strong> database creation<br />
• 3.2 Shutt<strong>in</strong>g down the <strong>MySQL</strong> server<br />
• 4 Creat<strong>in</strong>g <strong>InnoDB</strong> tables<br />
• 4.1 How to use transactions <strong>in</strong> <strong>InnoDB</strong><br />
• 4.2 Convert<strong>in</strong>g MyISAM tables to <strong>InnoDB</strong><br />
• 4.3 Foreign key constra<strong>in</strong>ts<br />
• 4.4 How an auto-<strong>in</strong>crement column works <strong>in</strong> <strong>InnoDB</strong><br />
• 5 Add<strong>in</strong>g and remov<strong>in</strong>g <strong>InnoDB</strong> data and log files<br />
• 6 Back<strong>in</strong>g up and recover<strong>in</strong>g an <strong>InnoDB</strong> database<br />
• 6.1 Forc<strong>in</strong>g recovery<br />
• 7 Mov<strong>in</strong>g an <strong>InnoDB</strong> database to another mach<strong>in</strong>e<br />
• 8 <strong>InnoDB</strong> transaction model and lock<strong>in</strong>g<br />
• 8.8 How to cope with deadlocks?<br />
• 9 Performance tun<strong>in</strong>g tips<br />
• 9.1 The <strong>InnoDB</strong> Monitor<br />
• 10 Implementation of multiversion<strong>in</strong>g<br />
• 11 Table and <strong>in</strong>dex structures<br />
• 12 File space management and disk i/o<br />
• 12.1 Disk i/o and raw devices<br />
• 12.2 File space management<br />
• 12.3 Defragment<strong>in</strong>g a table<br />
• 13 Error handl<strong>in</strong>g<br />
• 13.1 Some error codes <strong>MySQL</strong> returns<br />
• 13.2 Some operat<strong>in</strong>g system error numbers<br />
• 14 Restrictions on <strong>InnoDB</strong> tables<br />
• 15 Troubleshoot<strong>in</strong>g<br />
• 15.1 Troubleshoot<strong>in</strong>g data dictionary operations<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 2 de 45<br />
• 16 <strong>InnoDB</strong> version history<br />
• 17 Contact <strong>in</strong>formation<br />
• 18 The GNU GPL License Version 2<br />
• 19 Known bugs and their fixes <strong>in</strong> old versions of <strong>InnoDB</strong><br />
• 20 The TODO list of new features to <strong>InnoDB</strong><br />
• 21 Some books and articles on <strong>MySQL</strong>/<strong>InnoDB</strong><br />
1 <strong>InnoDB</strong> tables overview<br />
<strong>InnoDB</strong> provides <strong>MySQL</strong> with a transaction-safe table handler with commit, rollback, and crash<br />
recovery capabilities. <strong>InnoDB</strong> does lock<strong>in</strong>g on row level and also provides an Oracle-style consistent<br />
non-lock<strong>in</strong>g read <strong>in</strong> SELECTs. These features <strong>in</strong>crease multiuser concurrency and performance. There<br />
is no need for lock escalation <strong>in</strong> <strong>InnoDB</strong>, because row level locks <strong>in</strong> <strong>InnoDB</strong> fit <strong>in</strong> very small space.<br />
<strong>InnoDB</strong> tables support FOREIGN KEY constra<strong>in</strong>ts as the first table type <strong>in</strong> <strong>MySQL</strong>. In SQL queries<br />
you can freely mix <strong>InnoDB</strong> type tables with other table types of <strong>MySQL</strong>, even with<strong>in</strong> the same<br />
query.<br />
<strong>InnoDB</strong> has been designed for maximum performance when process<strong>in</strong>g large data volumes. Its CPU<br />
efficiency is probably not matched by any other disk-based relational database eng<strong>in</strong>e.<br />
Technically, <strong>InnoDB</strong> is a complete database backend placed under <strong>MySQL</strong>. <strong>InnoDB</strong> has its own<br />
buffer pool for cach<strong>in</strong>g data and <strong>in</strong>dexes <strong>in</strong> ma<strong>in</strong> memory. <strong>InnoDB</strong> stores its tables and <strong>in</strong>dexes <strong>in</strong> a<br />
tablespace, which may consist of several files. This is different from, for example, MyISAM tables<br />
where each table is stored as a separate file. <strong>InnoDB</strong> tables can be of any size also on those operat<strong>in</strong>g<br />
systems where file size is limited to 2 GB.<br />
<strong>InnoDB</strong> is currently (October 2001) used <strong>in</strong> production at several large database sites requir<strong>in</strong>g high<br />
performance. The famous Internet news site Slashdot.org runs on <strong>InnoDB</strong> and uses also the <strong>MySQL</strong><br />
replication feature to <strong>InnoDB</strong> tables. Mytrix, Inc. stores over 1 TB of data <strong>in</strong> <strong>InnoDB</strong>, and another<br />
site handles an average load of 800 <strong>in</strong>serts/updates per second <strong>in</strong> <strong>InnoDB</strong>.<br />
<strong>InnoDB</strong> tables are <strong>in</strong>cluded <strong>in</strong> the <strong>MySQL</strong> source distribution start<strong>in</strong>g from 3.23.34a and are<br />
activated <strong>in</strong> the <strong>MySQL</strong> -<strong>Max</strong> b<strong>in</strong>ary. For W<strong>in</strong>dows the -<strong>Max</strong> b<strong>in</strong>aries are conta<strong>in</strong>ed <strong>in</strong> the standard<br />
distribution.<br />
If you have downloaded a b<strong>in</strong>ary version of <strong>MySQL</strong> that <strong>in</strong>cludes support for <strong>InnoDB</strong>, simply follow<br />
the <strong>in</strong>structions of the <strong>MySQL</strong> manual for <strong>in</strong>stall<strong>in</strong>g a b<strong>in</strong>ary version of <strong>MySQL</strong>. If you already have<br />
a recent version <strong>MySQL</strong>-3.23.4x <strong>in</strong>stalled, then the simplest way to <strong>in</strong>stall <strong>MySQL</strong> -<strong>Max</strong> with the<br />
same version number 3.23.4x is to replace the server executable mysqld with the correspond<strong>in</strong>g<br />
executable <strong>in</strong> the -<strong>Max</strong> distribution. <strong>MySQL</strong> and <strong>MySQL</strong> -<strong>Max</strong> differ only <strong>in</strong> the server executable.<br />
To compile <strong>MySQL</strong>-3.23 with <strong>InnoDB</strong> support, download <strong>MySQL</strong>-3.23.34a or newer version from<br />
the <strong>MySQL</strong> website and configure <strong>MySQL</strong> with the --with-<strong>in</strong>nodb option. See the <strong>MySQL</strong> manual<br />
about <strong>in</strong>stall<strong>in</strong>g a <strong>MySQL</strong> source distribution. In <strong>MySQL</strong>-4.0 <strong>InnoDB</strong> is compiled <strong>in</strong> by default.<br />
cd /path/to/source/of/mysql-3.23.47<br />
./configure --with-<strong>in</strong>nodb<br />
To use <strong>InnoDB</strong> <strong>in</strong> <strong>MySQL</strong>-<strong>Max</strong>-3.23 you have to specify <strong>InnoDB</strong> startup options <strong>in</strong> your my.cnf or<br />
my.<strong>in</strong>i file. The m<strong>in</strong>imal way to modify it is to add to the [mysqld] section the l<strong>in</strong>e<br />
<strong>in</strong>nodb_data_file_path=ibdata:30M<br />
but to get good performance it is best that you specify options as recommended below <strong>in</strong> the section<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 3 de 45<br />
'<strong>InnoDB</strong> startup options'.<br />
<strong>InnoDB</strong> is distributed under the GNU GPL License Version 2 (of June 1991). In the source<br />
distribution of <strong>MySQL</strong>, <strong>InnoDB</strong> appears as a subdirectory.<br />
1.1 Different <strong>MySQL</strong>/<strong>InnoDB</strong> distributions<br />
• <strong>MySQL</strong>-<strong>Max</strong>-3.23: This is the recommended distribution for production use. This version is<br />
classified as stable.<br />
• <strong>MySQL</strong>-4.0: This is the development version of <strong>MySQL</strong>. Compared to 3.23 it <strong>in</strong>cludes some<br />
new features, like multi-table delete, cached query results, and SSL communication. <strong>InnoDB</strong><br />
<strong>in</strong> 4.0 is the same as <strong>in</strong> 3.23. The stability of 4.0.1 can be classified as beta.<br />
• <strong>MySQL</strong>-4.0 embedded server library: You can l<strong>in</strong>k this <strong>in</strong>to your application. The benefits<br />
are easier deployment for your application, better performance, and easier use. The stability of<br />
the embedded library is classified as alpha, but it should be gamma with<strong>in</strong> a few months.<br />
2 <strong>InnoDB</strong> startup options<br />
To use <strong>InnoDB</strong> tables <strong>in</strong> <strong>MySQL</strong>-<strong>Max</strong>-3.23 you MUST specify configuration parameters <strong>in</strong> the<br />
[mysqld] section of the configuration file my.cnf, or on W<strong>in</strong>dows optionally <strong>in</strong> my.<strong>in</strong>i.<br />
At the m<strong>in</strong>imum, <strong>in</strong> 3.23 you must specify <strong>in</strong>nodb_data_file_path where you give the names and<br />
the sizes of data files. If you do not mention <strong>in</strong>nodb_data_home_dir <strong>in</strong> your my.cnf the default is<br />
that <strong>InnoDB</strong> creates these data files to the datadir of <strong>MySQL</strong>. If you specify<br />
<strong>in</strong>nodb_data_home_dir as an empty str<strong>in</strong>g, then you can give absolute paths to your data files. In<br />
<strong>MySQL</strong>-4.0 you do not need to specify even <strong>in</strong>nodb_data_file_path: the default for 4.0 is to<br />
create an auto-extend<strong>in</strong>g 10 MB file ibdata1 to the datadir of <strong>MySQL</strong>. (In <strong>MySQL</strong>-4.0.0 and 4.0.1<br />
the data file is 64 MB and not auto-extend<strong>in</strong>g.)<br />
But to get good performance you MUST explicitly set the <strong>InnoDB</strong> parameters listed below <strong>in</strong> the<br />
examples.<br />
Start<strong>in</strong>g from versions 3.23.50 and 4.0.2 <strong>InnoDB</strong> allows the last data file on the<br />
<strong>in</strong>nodb_data_file_path l<strong>in</strong>e to be specified as auto-extend<strong>in</strong>g. The syntax for<br />
<strong>in</strong>nodb_data_file_path is then the follow<strong>in</strong>g:<br />
pathtodatafile:sizespecification;pathtodatafile:sizespec;...<br />
...;pathtodatafile:sizespec[:autoextend[:max:sizespecification]]<br />
If you specify the last data file with the autoextend option, <strong>InnoDB</strong> will extend the last data file if it<br />
runs out of free space <strong>in</strong> the tablespace. The <strong>in</strong>crement is 8 MB at a time. An example:<br />
<strong>in</strong>nodb_data_home_dir =<br />
<strong>in</strong>nodb_data_file_path = /ibdata/ibdata1:100M:autoextend<br />
<strong>in</strong>structs <strong>InnoDB</strong> to create just a s<strong>in</strong>gle data file whose <strong>in</strong>itial size is 100 MB and which is extended<br />
<strong>in</strong> 8 MB blocks when space runs out. If the disk becomes full you may want to add another data file<br />
to another disk, for example. Then you have to look the size of ibdata1, round the size downward to<br />
the closest multiple of 1024 * 1024 bytes (= 1 MB), and specify the rounded size of ibdata1<br />
explicitly <strong>in</strong> <strong>in</strong>nodb_data_file_path. After that you can add another data file:<br />
<strong>in</strong>nodb_data_home_dir =<br />
<strong>in</strong>nodb_data_file_path = /ibdata/ibdata1:988M;/disk2/ibdata2:50M:autoextend<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 4 de 45<br />
Be cautious on file systems where the maximum file size is 2 GB! <strong>InnoDB</strong> is not aware of the OS<br />
maximum file size. On those file systems you might want to specify the max size for the data file:<br />
<strong>in</strong>nodb_data_home_dir =<br />
<strong>in</strong>nodb_data_file_path = /ibdata/ibdata1:100M:autoextend:max:2000M<br />
A simple my.cnf example. Suppose you have a computer with 128 MB RAM and one hard disk.<br />
Below is an example of possible configuration parameters <strong>in</strong> my.cnf or my.<strong>in</strong>i for <strong>InnoDB</strong>. We<br />
assume you are runn<strong>in</strong>g <strong>MySQL</strong>-<strong>Max</strong>-3.23.50 or later, or <strong>MySQL</strong>-4.0.2 or later.<br />
This example suits most users, both on Unix and W<strong>in</strong>dows, who do not want to distribute <strong>InnoDB</strong><br />
data files and log files on several disks. This creates an auto-extend<strong>in</strong>g data file ibdata1 and two<br />
<strong>InnoDB</strong> log files ib_logfile0 and ib_logfile1 to the datadir of <strong>MySQL</strong><br />
(typically /mysql/data). Also the small archived <strong>InnoDB</strong> log file ib_arch_log_0000000000 ends<br />
up <strong>in</strong> the datadir.<br />
[mysqld]<br />
# You can write your other <strong>MySQL</strong> server options here<br />
# ...<br />
# Data file(s) must be able to<br />
# hold your data and <strong>in</strong>dexes.<br />
# Make sure you have enough<br />
# free disk space.<br />
<strong>in</strong>nodb_data_file_path = ibdata1:10M:autoextend<br />
# Set buffer pool size to<br />
# 50 - 80 % of your computer's<br />
# memory<br />
set-variable = <strong>in</strong>nodb_buffer_pool_size=70M<br />
set-variable = <strong>in</strong>nodb_additional_mem_pool_size=10M<br />
# Set the log file size to about<br />
# 25 % of the buffer pool size<br />
set-variable = <strong>in</strong>nodb_log_file_size=20M<br />
set-variable = <strong>in</strong>nodb_log_buffer_size=8M<br />
# Set ..flush_log_at_trx_commit<br />
# to 0 if you can afford los<strong>in</strong>g<br />
# some last transactions<br />
<strong>in</strong>nodb_flush_log_at_trx_commit=1<br />
Check that the <strong>MySQL</strong> server has the rights to create files <strong>in</strong> datadir.<br />
Note that data files must be < 2G <strong>in</strong> some file systems! The comb<strong>in</strong>ed size of the log files must be <<br />
4G. The comb<strong>in</strong>ed size of data files must be >= 10 MB.<br />
When you for the first time create an <strong>InnoDB</strong> database, it is best that you start the <strong>MySQL</strong> server<br />
from the command prompt. Then <strong>InnoDB</strong> will pr<strong>in</strong>t the <strong>in</strong>formation about the database creation to<br />
the screen, and you see what is happen<strong>in</strong>g. See below <strong>in</strong> section 3 what the pr<strong>in</strong>tout should look like.<br />
For example, <strong>in</strong> W<strong>in</strong>dows you can start mysqld-max.exe with:<br />
your-path-to-mysqld>mysqld-max --console<br />
Where to put my.cnf or my.<strong>in</strong>i <strong>in</strong> W<strong>in</strong>dows? The rules for W<strong>in</strong>dows are the follow<strong>in</strong>g:<br />
• Only one of my.cnf or my.<strong>in</strong>i should be created.<br />
• The my.cnf file should be placed <strong>in</strong> the root directory of the drive C:.<br />
• The my.<strong>in</strong>i file should be placed <strong>in</strong> the WINDIR directory, e.g, C:\WINDOWS or C:\WINNT.<br />
You can use the SET command of MS-DOS to pr<strong>in</strong>t the value of WINDIR.<br />
• If your PC uses a boot loader where the C: drive is not the boot drive, then your only option is<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 5 de 45<br />
to use the my.<strong>in</strong>i file.<br />
Where to specify options <strong>in</strong> Unix? On Unix mysqld reads options from the follow<strong>in</strong>g files, if they<br />
exist, <strong>in</strong> the follow<strong>in</strong>g order:<br />
• /etc/my.cnf Global options.<br />
• COMPILATION_DATADIR/my.cnf Server-specific options.<br />
• defaults-extra-file The file specified with --defaults-extra-file=....<br />
• ~/.my.cnf User-specific options.<br />
COMPILATION_DATADIR is the <strong>MySQL</strong> data directory which was specified as a ./configure option<br />
when mysqld was compiled (typically /usr/local/mysql/data for a b<strong>in</strong>ary <strong>in</strong>stallation<br />
or /usr/local/var for a source <strong>in</strong>stallation).<br />
If you are not sure from where mysqld reads its my.cnf or my.<strong>in</strong>i, you can give the path as the first<br />
command-l<strong>in</strong>e option to the server: mysqld --defaults-file=your_path_to_my_cnf.<br />
<strong>InnoDB</strong> forms the directory path to a data file by textually catenat<strong>in</strong>g <strong>in</strong>nodb_data_home_dir to a<br />
data file name or path <strong>in</strong> <strong>in</strong>nodb_data_file_path, add<strong>in</strong>g a possible slash or backslash <strong>in</strong> between<br />
if needed. If the keyword <strong>in</strong>nodb_data_home_dir is not mentioned <strong>in</strong> my.cnf at all, the default for<br />
it is the 'dot' directory ./ which means the datadir of <strong>MySQL</strong>.<br />
An advanced my.cnf example. Suppose you have a L<strong>in</strong>ux computer with 2 GB RAM and three 60<br />
GB hard disks (at directory paths `/', `/dr2' and `/dr3'). Below is an example of possible<br />
configuration parameters <strong>in</strong> my.cnf for <strong>InnoDB</strong>.<br />
Note that <strong>InnoDB</strong> does not create directories: you have to create them yourself. Use the Unix or<br />
MS-DOS mkdir command to create the data and log group home directories.<br />
[mysqld]<br />
# You can write your other <strong>MySQL</strong> server options here<br />
# ...<br />
<strong>in</strong>nodb_data_home_dir =<br />
# Data files must be able to<br />
# hold your data and <strong>in</strong>dexes<br />
<strong>in</strong>nodb_data_file_path = /ibdata/ibdata1:2000M;/dr2/ibdata/ibdata2:2000M:autoextend<br />
# Set buffer pool size to<br />
# 50 - 80 % of your computer's<br />
# memory, but make sure on L<strong>in</strong>ux<br />
# x86 total memory usage is<br />
# < 2 GB<br />
set-variable = <strong>in</strong>nodb_buffer_pool_size=1G<br />
set-variable = <strong>in</strong>nodb_additional_mem_pool_size=20M<br />
<strong>in</strong>nodb_log_group_home_dir = /dr3/iblogs<br />
# .._log_arch_dir must be the same<br />
# as .._log_group_home_dir<br />
<strong>in</strong>nodb_log_arch_dir = /dr3/iblogs<br />
set-variable = <strong>in</strong>nodb_log_files_<strong>in</strong>_group=3<br />
# Set the log file size to about<br />
# 15 % of the buffer pool size<br />
set-variable = <strong>in</strong>nodb_log_file_size=150M<br />
set-variable = <strong>in</strong>nodb_log_buffer_size=8M<br />
# Set ..flush_log_at_trx_commit to<br />
# 0 if you can afford los<strong>in</strong>g<br />
# some last transactions<br />
<strong>in</strong>nodb_flush_log_at_trx_commit=1<br />
set-variable = <strong>in</strong>nodb_lock_wait_timeout=50<br />
#<strong>in</strong>nodb_flush_method=fdatasync<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 6 de 45<br />
#set-variable = <strong>in</strong>nodb_thread_concurrency=5<br />
Note that we have placed the two data files on different disks. <strong>InnoDB</strong> will fill the tablespace formed<br />
by the data files from bottom up. In some cases it will improve the performance of the database if all<br />
data is not placed on the same physical disk. Putt<strong>in</strong>g log files on a different disk from data is very<br />
often beneficial for performance. You can also use raw disk partitions (raw devices) as data files. In<br />
some Unixes they speed up i/o. See section 12.1 about how to specify them <strong>in</strong> my.cnf.<br />
Warn<strong>in</strong>g: on L<strong>in</strong>ux x86 you must be careful you do not set memory usage too high. glibc will<br />
allow the process heap to grow over thread stacks, which will crash your server. It is a risk if the<br />
value of<br />
<strong>in</strong>nodb_buffer_pool_size + key_buffer +<br />
max_connections * (sort_buffer + record_buffer) + max_connections * 2 MB<br />
is close to 2 GB or exceeds 2 GB. Each thread will use a stack (often 2 MB, but <strong>in</strong> <strong>MySQL</strong> AB<br />
b<strong>in</strong>aries only 256 kB) and <strong>in</strong> the worst case also sort_buffer + record_buffer additional<br />
memory.<br />
How to tune other mysqld server parameters? For detailed <strong>in</strong>formation on how to tune other<br />
<strong>MySQL</strong> server parameters, see the <strong>MySQL</strong> manual. Typical values which suit most users are:<br />
skip-lock<strong>in</strong>g<br />
set-variable = max_connections=200<br />
set-variable = record_buffer=1M<br />
set-variable = sort_buffer=1M<br />
# Set key_buffer to 5 - 50 %<br />
# of your RAM depend<strong>in</strong>g on how<br />
# much you use MyISAM tables, but<br />
# keep key_buffer + <strong>InnoDB</strong><br />
# buffer pool size < 80 % of<br />
# your RAM<br />
set-variable = key_buffer=...<br />
Note that some parameters are given us<strong>in</strong>g the numeric my.cnf parameter format: set-variable =<br />
<strong>in</strong>nodb... = 123, others (str<strong>in</strong>g and boolean parameters) with another format: <strong>in</strong>nodb_... = ...<br />
.<br />
The mean<strong>in</strong>gs of the configuration parameters are the follow<strong>in</strong>g:<br />
<strong>in</strong>nodb_data_home_dir<br />
<strong>in</strong>nodb_data_file_path<br />
The common part of the directory path for all <strong>InnoDB</strong> data<br />
files. If you do not mention this option <strong>in</strong> my.cnf, <strong>InnoDB</strong><br />
will use the <strong>MySQL</strong> datadir as the default. You can<br />
specify this also as an empty str<strong>in</strong>g, <strong>in</strong> which case you can<br />
use absolute file paths <strong>in</strong> <strong>in</strong>nodb_data_file_path.<br />
Paths to <strong>in</strong>dividual data files and their sizes. The full<br />
directory path to each data file is acquired by concatenat<strong>in</strong>g<br />
<strong>in</strong>nodb_data_home_dir to the paths specified here. The file<br />
sizes are specified <strong>in</strong> megabytes, hence the 'M' after the size<br />
specification above. <strong>InnoDB</strong> also understands the<br />
abbreviation 'G', 1G mean<strong>in</strong>g 1024M. Start<strong>in</strong>g from 3.23.44<br />
you can set the file size bigger than 4 GB on those<br />
operat<strong>in</strong>g systems which support big files. On some<br />
operat<strong>in</strong>g systems files must be < 2 GB. The sum of the<br />
sizes of the data files must be at least 10 MB. In <strong>MySQL</strong>-<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 7 de 45<br />
<strong>in</strong>nodb_mirrored_log_groups<br />
<strong>in</strong>nodb_log_group_home_dir<br />
<strong>in</strong>nodb_log_files_<strong>in</strong>_group<br />
<strong>in</strong>nodb_log_file_size<br />
<strong>in</strong>nodb_log_buffer_size<br />
<strong>in</strong>nodb_flush_log_at_trx_commit<br />
<strong>in</strong>nodb_log_arch_dir<br />
<strong>in</strong>nodb_log_archive<br />
<strong>in</strong>nodb_buffer_pool_size<br />
3.23 this parameter must always be specified <strong>in</strong> my.cnf. In<br />
<strong>MySQL</strong>-4.0.2 and later, if you do not specify this, the<br />
default is to create a 16 MB auto-extend<strong>in</strong>g data file<br />
ibdata1 to the datadir of <strong>MySQL</strong>. You can also use raw<br />
disk partitions as data files. See section 12.1 about how to<br />
specify them <strong>in</strong> my.cnf.<br />
Number of identical copies of log groups we keep for the<br />
database. Currently this should be set to 1. Numeric my.cnf<br />
parameter format.<br />
Directory path to <strong>InnoDB</strong> log files. Must be set the same as<br />
<strong>in</strong>nodb_log_arch_dir. If you do not specify any <strong>InnoDB</strong><br />
log parameters, the default is to create two 5 MB files<br />
ib_logfile... to the datadir of <strong>MySQL</strong>.<br />
Number of log files <strong>in</strong> the log group. <strong>InnoDB</strong> writes to the<br />
files <strong>in</strong> a circular fashion. Value 3 is recommended here.<br />
Numeric my.cnf parameter format.<br />
Size of each log file <strong>in</strong> a log group <strong>in</strong> megabytes. If n is the<br />
number of log files you specified for the log group, then<br />
sensible values range from 1M to 1/nth of the size of the<br />
buffer pool specified below, The bigger the value, the less<br />
checkpo<strong>in</strong>t flush activity is needed <strong>in</strong> the buffer pool,<br />
sav<strong>in</strong>g disk i/o. But bigger log files also mean that recovery<br />
will be slower <strong>in</strong> case of a crash. The comb<strong>in</strong>ed size of log<br />
files must be < 4 GB. Numeric my.cnf parameter format.<br />
The size of the buffer which <strong>InnoDB</strong> uses to write log to the<br />
log files on disk. Sensible values range from 1M to 8M. A<br />
big log buffer allows large transactions to run without a<br />
need to write the log to disk until the transaction commit.<br />
Thus, if you have big transactions, mak<strong>in</strong>g the log buffer<br />
big will save disk i/o. Numeric my.cnf parameter format.<br />
Normally this is set to 1, mean<strong>in</strong>g that at a transaction<br />
commit the log is flushed to disk, and the modifications<br />
made by the transaction become permanent, and survive a<br />
database crash. If you are will<strong>in</strong>g to compromise this safety,<br />
and you are runn<strong>in</strong>g small transactions, you may set this to<br />
0 to reduce disk i/o to the logs. The default value of this<br />
parameter is 0.<br />
The directory where fully written log files would be<br />
archived if we used log archiv<strong>in</strong>g. The value of this<br />
parameter should currently be set the same as<br />
<strong>in</strong>nodb_log_group_home_dir.<br />
This value should currently be set to 0. As recovery from a<br />
backup is done by <strong>MySQL</strong> us<strong>in</strong>g its own log files, there is<br />
currently no need to archive <strong>InnoDB</strong> log files. The default<br />
value of this parameter is 0.<br />
The size of the memory buffer <strong>InnoDB</strong> uses to cache data<br />
and <strong>in</strong>dexes of its tables. The bigger you set this the less<br />
disk i/o is needed to access data <strong>in</strong> tables. On a dedicated<br />
database server you may set this parameter up to 80 % of<br />
the mach<strong>in</strong>e physical memory size. Do not set it too large<br />
though, because competition of the physical memory may<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 8 de 45<br />
<strong>in</strong>nodb_additional_mem_pool_size<br />
<strong>in</strong>nodb_file_io_threads<br />
<strong>in</strong>nodb_lock_wait_timeout<br />
<strong>in</strong>nodb_flush_method<br />
<strong>in</strong>nodb_force_recovery<br />
<strong>in</strong>nodb_fast_shutdown<br />
cause pag<strong>in</strong>g <strong>in</strong> the operat<strong>in</strong>g system. Numeric my.cnf<br />
parameter format.<br />
Size of a memory pool <strong>InnoDB</strong> uses to store data dictionary<br />
<strong>in</strong>formation and other <strong>in</strong>ternal data structures. A sensible<br />
value for this might be 2M, but the more tables you have <strong>in</strong><br />
your application the more you will need to allocate here. If<br />
<strong>InnoDB</strong> runs out of memory <strong>in</strong> this pool, it will start to<br />
allocate memory from the operat<strong>in</strong>g system, and write<br />
warn<strong>in</strong>g messages to the <strong>MySQL</strong> error log. Numeric<br />
my.cnf parameter format.<br />
Number of file i/o threads <strong>in</strong> <strong>InnoDB</strong>. Normally, this should<br />
be 4, but on W<strong>in</strong>dows disk i/o may benefit from a larger<br />
number. Numeric my.cnf parameter format.<br />
Timeout <strong>in</strong> seconds an <strong>InnoDB</strong> transaction may wait for a<br />
lock before be<strong>in</strong>g rolled back. <strong>InnoDB</strong> automatically<br />
detects transaction deadlocks <strong>in</strong> its own lock table and rolls<br />
back the transaction. If you use LOCK TABLES command, or<br />
other transaction safe table handlers than <strong>InnoDB</strong> <strong>in</strong> the<br />
same transaction, then a deadlock may arise which <strong>InnoDB</strong><br />
cannot notice. In cases like this the timeout is useful to<br />
resolve the situation. Numeric my.cnf parameter format.<br />
The default value of this parameter is 50 seconds.<br />
This is only relevant on Unix. The default value for this is<br />
fdatasync. Another option is O_DSYNC. This affects only<br />
log flush<strong>in</strong>g, data files <strong>in</strong> Unix are always flushed with<br />
fsync. <strong>InnoDB</strong> versions start<strong>in</strong>g from 3.23.40b <strong>in</strong> Unix use<br />
fsync if you specify fdatasync and O_SYNC if you specify<br />
O_DSYNC. The 'data' versions are not used because there<br />
have been problems with them on many Unix flavors.<br />
Warn<strong>in</strong>g: this option should only be def<strong>in</strong>ed <strong>in</strong> an<br />
emergency situation when you want to dump your tables<br />
from a corrupt database! Possible values are 1 - 6. See<br />
below at section 'Forc<strong>in</strong>g recovery' about the mean<strong>in</strong>gs of<br />
the values. As a safety measure <strong>InnoDB</strong> prevents a user<br />
from modify<strong>in</strong>g data when this option is > 0. This option is<br />
available start<strong>in</strong>g from version 3.23.44. Numeric my.cnf<br />
parameter format.<br />
By default, <strong>InnoDB</strong> does a full purge and an <strong>in</strong>sert buffer<br />
merge before a shutdown. These operations can take<br />
m<strong>in</strong>utes, or <strong>in</strong> extreme cases even hours. If you set this<br />
parameter to 1, then <strong>InnoDB</strong> skips these operations at<br />
shutdown. Available start<strong>in</strong>g from 3.23.44 and 4.0.1. The<br />
default value of this parameter is 1 start<strong>in</strong>g from 3.23.50.<br />
<strong>in</strong>nodb_thread_concurrency<br />
<strong>InnoDB</strong> tries to keep the number of operat<strong>in</strong>g system<br />
threads concurrently <strong>in</strong>side <strong>InnoDB</strong> below or equal to the<br />
limit given <strong>in</strong> this parameter. The default value for this<br />
parameter is 8. If you have low performance and<br />
<strong>in</strong>nodb_monitor reveals many threads wait<strong>in</strong>g for<br />
semaphores, then you may have thread thrash<strong>in</strong>g and<br />
should try sett<strong>in</strong>g this parameter lower. If you have a<br />
computer with many processors and disks, you can try<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 9 de 45<br />
sett<strong>in</strong>g this value higher to better utilize the resources of<br />
you computer. A value 'number of processors + number of<br />
disks' is recommended. Available start<strong>in</strong>g from 3.23.44 and<br />
4.0.1. Numeric my.cnf parameter format.<br />
3 Creat<strong>in</strong>g an <strong>InnoDB</strong> database<br />
Suppose you have <strong>in</strong>stalled <strong>MySQL</strong> and have edited my.cnf so that it conta<strong>in</strong>s the necessary <strong>InnoDB</strong><br />
configuration parameters. Before start<strong>in</strong>g <strong>MySQL</strong> you should check that the directories you have<br />
specified for <strong>InnoDB</strong> data files and log files exist and that you have access rights to those directories.<br />
<strong>InnoDB</strong> cannot create directories, only files. Check also you have enough disk space for the data and<br />
log files.<br />
It is best to run the <strong>MySQL</strong> server mysqld from the command prompt when you create an <strong>InnoDB</strong><br />
database, not from the safe_mysqld wrapper or as a W<strong>in</strong>dows service. When you run from a<br />
command prompt you see what mysqld pr<strong>in</strong>ts and what is happen<strong>in</strong>g.<br />
When you now start the <strong>MySQL</strong> server, <strong>InnoDB</strong> will start creat<strong>in</strong>g your data files and log files.<br />
<strong>InnoDB</strong> will pr<strong>in</strong>t someth<strong>in</strong>g like the follow<strong>in</strong>g:<br />
heikki@donna:~/mysql-3.23.48/sql> mysqld<br />
020204 23:17:12 <strong>InnoDB</strong>: The first specified data file /dr2/tmp/heikki/data/ibdata1<br />
did not exist:<br />
<strong>InnoDB</strong>: a new database to be created!<br />
<strong>InnoDB</strong>: Sett<strong>in</strong>g file /dr2/tmp/heikki/data/ibdata1 size to 20 MB<br />
<strong>InnoDB</strong>: Database physically writes the file full: wait...<br />
020204 23:17:16 <strong>InnoDB</strong>: Data file /dr2/tmp/heikki/data/ibdata2 did not exist: new<br />
to be created<br />
<strong>InnoDB</strong>: Sett<strong>in</strong>g file /dr2/tmp/heikki/data/ibdata2 size to 200 MB<br />
<strong>InnoDB</strong>: Database physically writes the file full: wait...<br />
020204 23:17:41 <strong>InnoDB</strong>: Data file /dr2/tmp/heikki/data/ibdata3 did not exist: new<br />
to be created<br />
<strong>InnoDB</strong>: Sett<strong>in</strong>g file /dr2/tmp/heikki/data/ibdata3 size to 1000 MB<br />
<strong>InnoDB</strong>: Database physically writes the file full: wait...<br />
020204 23:21:37 <strong>InnoDB</strong>: Log file ./ib_logfile0 did not exist: new to be created<br />
<strong>InnoDB</strong>: Sett<strong>in</strong>g log file ./ib_logfile0 size to 10 MB<br />
<strong>InnoDB</strong>: Database physically writes the file full: wait...<br />
020204 23:21:39 <strong>InnoDB</strong>: Log file ./ib_logfile1 did not exist: new to be created<br />
<strong>InnoDB</strong>: Sett<strong>in</strong>g log file ./ib_logfile1 size to 10 MB<br />
<strong>InnoDB</strong>: Database physically writes the file full: wait...<br />
020204 23:21:41 <strong>InnoDB</strong>: Log file ./ib_logfile2 did not exist: new to be created<br />
<strong>InnoDB</strong>: Sett<strong>in</strong>g log file ./ib_logfile2 size to 10 MB<br />
<strong>InnoDB</strong>: Database physically writes the file full: wait...<br />
<strong>InnoDB</strong>: Doublewrite buffer not found: creat<strong>in</strong>g new<br />
<strong>InnoDB</strong>: Doublewrite buffer created<br />
<strong>InnoDB</strong>: Creat<strong>in</strong>g foreign key constra<strong>in</strong>t system tables<br />
<strong>InnoDB</strong>: Foreign key constra<strong>in</strong>t system tables created<br />
020204 23:21:45 <strong>InnoDB</strong>: Started<br />
mysqld: ready for connections<br />
A new <strong>InnoDB</strong> database has now been created. You can connect to the <strong>MySQL</strong> server with the usual<br />
<strong>MySQL</strong> client programs like mysql. When you shut down the <strong>MySQL</strong> server with mysqladm<strong>in</strong><br />
shutdown, <strong>InnoDB</strong> output will be like the follow<strong>in</strong>g:<br />
020204 23:34:45 mysqld: Normal shutdown<br />
020204 23:34:45 <strong>InnoDB</strong>: Start<strong>in</strong>g shutdown...<br />
020204 23:34:47 <strong>InnoDB</strong>: Shutdown completed<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 10 de 45<br />
020204 23:34:47 mysqld: Shutdown Complete<br />
You can now look at the data files and logs directories and you will see the files created. The log<br />
directory will also conta<strong>in</strong> a small file named ib_arch_log_0000000000. That file resulted from the<br />
database creation, after which <strong>InnoDB</strong> switched off log archiv<strong>in</strong>g. When <strong>MySQL</strong> is aga<strong>in</strong> started, the<br />
output will be like the follow<strong>in</strong>g:<br />
heikki@donna:~/mysql-3.23.48/sql> mysqld<br />
020204 23:34:27 <strong>InnoDB</strong>: Started<br />
mysqld: ready for connections<br />
3.1 If someth<strong>in</strong>g goes wrong <strong>in</strong> database creation<br />
If <strong>InnoDB</strong> pr<strong>in</strong>ts an operat<strong>in</strong>g system error <strong>in</strong> a file operation, look from section 13.2 what that error<br />
code means. Usually the problem is one of the follow<strong>in</strong>g:<br />
• You did not create <strong>InnoDB</strong> data or log directories.<br />
• mysqld does not have the rights to create files <strong>in</strong> those directories.<br />
• mysqld does not read the right my.cnf or my.<strong>in</strong>i file, and consequently does not see the<br />
options you specified.<br />
• The disk is full or a disk quota is exceeded.<br />
• You have created a subdirectory whose name is equal to a data file you specified.<br />
• There is a syntax error <strong>in</strong> <strong>in</strong>nodb_data_home_dir or <strong>in</strong>nodb_data_file_path.<br />
If someth<strong>in</strong>g goes wrong <strong>in</strong> an <strong>InnoDB</strong> database creation, you should delete all files created by<br />
<strong>InnoDB</strong>. This means all data files, all log files, the small archived log file, and <strong>in</strong> the case you<br />
already did create some <strong>InnoDB</strong> tables, delete also the correspond<strong>in</strong>g .frm files for these tables from<br />
the <strong>MySQL</strong> database directories. Then you can try the <strong>InnoDB</strong> database creation aga<strong>in</strong>. It is best to<br />
start the <strong>MySQL</strong> server from a command prompt so that you see what is happen<strong>in</strong>g.<br />
3.2 Shutt<strong>in</strong>g down the <strong>MySQL</strong> server<br />
Normally you have to shut down the database server before shutt<strong>in</strong>g down your computer. You can<br />
do this from the command l<strong>in</strong>e with the command mysqladm<strong>in</strong> shutdown.<br />
On W<strong>in</strong>dows NT and 2000 you can <strong>in</strong>stall the <strong>MySQL</strong> server also as a W<strong>in</strong>dows service. In that case<br />
the <strong>MySQL</strong> startup happens automatically at the computer boot time, or you can start it with the MS-<br />
DOS command NET START <strong>MySQL</strong> or from the Services menu of your operat<strong>in</strong>g system.<br />
If you run <strong>MySQL</strong> as a service, you can shut down the <strong>MySQL</strong> server with the MS-DOS NET STOP<br />
<strong>MySQL</strong> command, or from the Services menu of your operat<strong>in</strong>g system. You can also let the operat<strong>in</strong>g<br />
system automatically shut down <strong>MySQL</strong> at the computer shutdown time. In <strong>MySQL</strong> versions <<br />
3.23.47 the W<strong>in</strong>dows operat<strong>in</strong>g system only waited for a few seconds for the <strong>InnoDB</strong> shutdown to<br />
complete, and killed the database server process if the time limit was exceeded. Then at the next<br />
startup <strong>InnoDB</strong> had to do a crash recovery. Start<strong>in</strong>g from the <strong>MySQL</strong> version 3.23.48, the operat<strong>in</strong>g<br />
system will wait longer for the <strong>InnoDB</strong> shutdown to complete.<br />
If you notice that the operat<strong>in</strong>g system does not wait long enough for the <strong>InnoDB</strong> shutdown to<br />
complete, it is safest to run the <strong>MySQL</strong> server from an MS-DOS prompt, and shut it down with<br />
mysqladm<strong>in</strong> shutdown.<br />
On W<strong>in</strong>dows NT (but not on W<strong>in</strong>dows 2000), at the computer shutdown, there is the problem that<br />
W<strong>in</strong>dows NT by default only waits for 20 seconds for a service to shut down, and after that kills the<br />
service process. You can <strong>in</strong>crease this default by open<strong>in</strong>g the Registry Editor \w<strong>in</strong>nt\system32<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 11 de 45<br />
\regedt32.exe and edit<strong>in</strong>g the value of WaitToKillServiceTimeout at<br />
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control <strong>in</strong> the Registry tree. Give the new<br />
larger value <strong>in</strong> milliseconds.<br />
4 Creat<strong>in</strong>g <strong>InnoDB</strong> tables<br />
Suppose you have started the <strong>MySQL</strong> client with the command mysql test. To create a table <strong>in</strong> the<br />
<strong>InnoDB</strong> format you must specify TYPE = <strong>InnoDB</strong> <strong>in</strong> the table creation SQL command:<br />
CREATE TABLE CUSTOMER (A INT, B CHAR (20), INDEX (A)) TYPE = <strong>InnoDB</strong>;<br />
This SQL command will create a table and an <strong>in</strong>dex on column A <strong>in</strong>to the <strong>InnoDB</strong> tablespace<br />
consist<strong>in</strong>g of the data files you specified <strong>in</strong> my.cnf. In addition <strong>MySQL</strong> will create a file<br />
CUSTOMER.frm to the <strong>MySQL</strong> database directory test. Internally, <strong>InnoDB</strong> will add to its own data<br />
dictionary an entry for table 'test/CUSTOMER'. Thus you can create a table of the same name<br />
CUSTOMER <strong>in</strong> another database of <strong>MySQL</strong>, and the table names will not collide <strong>in</strong>side <strong>InnoDB</strong>.<br />
You can query the amount of free space <strong>in</strong> the <strong>InnoDB</strong> tablespace by issu<strong>in</strong>g the table status<br />
command of <strong>MySQL</strong> for any table you have created with TYPE = <strong>InnoDB</strong>. Then the amount of free<br />
space <strong>in</strong> the tablespace appears <strong>in</strong> the table comment section <strong>in</strong> the output of SHOW. An example:<br />
SHOW TABLE STATUS FROM test LIKE 'CUSTOMER'<br />
Note that the statistics SHOW gives about <strong>InnoDB</strong> tables are only approximate: they are used <strong>in</strong> SQL<br />
optimization. Table and <strong>in</strong>dex reserved sizes <strong>in</strong> bytes are accurate, though.<br />
Also take care not to delete or add .frm files to your <strong>InnoDB</strong> database manually: use CREATE TABLE<br />
and DROP TABLE commands. <strong>InnoDB</strong> has its own <strong>in</strong>ternal data dictionary, and you will get problems<br />
if the <strong>MySQL</strong> .frm files are out of 'sync' with the <strong>InnoDB</strong> <strong>in</strong>ternal data dictionary.<br />
4.1 How to use transactions <strong>in</strong> <strong>InnoDB</strong> with different APIs<br />
By default, <strong>MySQL</strong> always starts a new connection <strong>in</strong> the autocommit mode which automatically<br />
commits every SQL statement you run. To use transactions, you can switch the autocommit off with<br />
the SQL command SET AUTOCOMMIT = 0 and use COMMIT and ROLLBACK to commit or rollback your<br />
transaction. If you want to leave the autocommit on, you can enclose your transactions between<br />
BEGIN and COMMIT or ROLLBACK.<br />
heikki@hund<strong>in</strong>:~/mysql/client> mysql test<br />
Welcome to the <strong>MySQL</strong> monitor. Commands end with ; or \g.<br />
Your <strong>MySQL</strong> connection id is 5 to server version: 3.23.50-log<br />
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.<br />
mysql> CREATE TABLE CUSTOMER (A INT, B CHAR (20), INDEX (A)) TYPE = <strong>InnoDB</strong>;<br />
Query OK, 0 rows affected (0.00 sec)<br />
mysql> BEGIN;<br />
Query OK, 0 rows affected (0.00 sec)<br />
mysql> INSERT INTO CUSTOMER VALUES (10, 'Heikki');<br />
Query OK, 1 row affected (0.00 sec)<br />
mysql> COMMIT;<br />
Query OK, 0 rows affected (0.00 sec)<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 12 de 45<br />
mysql> SET AUTOCOMMIT=0;<br />
Query OK, 0 rows affected (0.00 sec)<br />
mysql> INSERT INTO CUSTOMER VALUES (15, 'John');<br />
Query OK, 1 row affected (0.00 sec)<br />
mysql> ROLLBACK;<br />
Query OK, 0 rows affected (0.00 sec)<br />
mysql> SELECT * FROM CUSTOMER;<br />
+------+--------+<br />
| A | B |<br />
+------+--------+<br />
| 10 | Heikki |<br />
+------+--------+<br />
1 row <strong>in</strong> set (0.00 sec)<br />
mysql><br />
In APIs like PHP, Perl DBI/DBD, JDBC, ODBC, or the standard C call <strong>in</strong>terface of <strong>MySQL</strong>, send<br />
the transaction control statements like "COMMIT" to the <strong>MySQL</strong> server as str<strong>in</strong>gs like any other SQL<br />
statements, e.g., "SELECT..." or "INSERT...". APIs often conta<strong>in</strong> separate special committransaction<br />
methods, but s<strong>in</strong>ce transaction support is still relatively young <strong>in</strong> <strong>MySQL</strong>, those do not<br />
always work with all versions of the APIs.<br />
4.2 Convert<strong>in</strong>g MyISAM tables to <strong>InnoDB</strong><br />
Important: you should not convert <strong>MySQL</strong> system tables like 'user' or 'host' to the <strong>InnoDB</strong> type.<br />
The system tables must always be of the MyISAM type.<br />
If you want all your tables to be created <strong>in</strong> the <strong>InnoDB</strong> type, you can, start<strong>in</strong>g from the <strong>MySQL</strong><br />
version 3.23.43, add the l<strong>in</strong>e<br />
default-table-type=<strong>in</strong>nodb<br />
to the [mysqld] section of your my.cnf or my.<strong>in</strong>i.<br />
<strong>InnoDB</strong> does not have a special optimization for separate <strong>in</strong>dex creation. Therefore it does not pay to<br />
export and import the table and create <strong>in</strong>dexes afterwards. The fastest way to alter a table to <strong>InnoDB</strong><br />
is to do the <strong>in</strong>serts directly to an <strong>InnoDB</strong> table, that is, use ALTER TABLE ... TYPE=INNODB, or<br />
create an empty <strong>InnoDB</strong> table with identical def<strong>in</strong>itions and <strong>in</strong>sert the rows with INSERT INTO ...<br />
SELECT * FROM ....<br />
If you have UNIQUE constra<strong>in</strong>ts on secondary keys, start<strong>in</strong>g from 3.23.52 you can speed up a table<br />
import by turn<strong>in</strong>g the uniqueness checks off for a while <strong>in</strong> the import session:<br />
SET UNIQUE_CHECKS=0;<br />
For big tables this saves a lot of disk i/o because <strong>InnoDB</strong> can then use its <strong>in</strong>sert buffer to write<br />
secondary <strong>in</strong>dex records <strong>in</strong> a batch.<br />
To get better control over the <strong>in</strong>sertion process, it may be good to <strong>in</strong>sert big tables <strong>in</strong> pieces:<br />
INSERT INTO newtable SELECT * FROM oldtable WHERE yourkey > someth<strong>in</strong>g<br />
AND yourkey
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 13 de 45<br />
Dur<strong>in</strong>g the conversion of big tables you should set the <strong>InnoDB</strong> buffer pool size big to reduce disk i/o.<br />
Not bigger than 80 % of the physical memory, though. You should set <strong>InnoDB</strong> log files big, and also<br />
the log buffer large.<br />
Make sure you do not run out of tablespace: <strong>InnoDB</strong> tables take a lot more space than MyISAM<br />
tables. If an ALTER TABLE runs out of space, it will start a rollback, and that can take hours if it is<br />
disk-bound. In <strong>in</strong>serts <strong>InnoDB</strong> uses the <strong>in</strong>sert buffer to merge secondary <strong>in</strong>dex records to <strong>in</strong>dexes <strong>in</strong><br />
batches. That saves a lot of disk i/o. In rollback no such mechanism is used, and the rollback can take<br />
30 times longer than the <strong>in</strong>sertion.<br />
In the case of a runaway rollback, if you do not have valuable data <strong>in</strong> your just imported table,<br />
start<strong>in</strong>g from version <strong>3.23.53</strong> and 4.0.3 you can use the trick expla<strong>in</strong>ed <strong>in</strong> section 6.1 to stop the<br />
runaway rollback.<br />
4.3 Foreign key constra<strong>in</strong>ts<br />
Start<strong>in</strong>g from version 3.23.43b <strong>InnoDB</strong> features foreign key constra<strong>in</strong>ts. <strong>InnoDB</strong> is the first <strong>MySQL</strong><br />
table type which allows you to def<strong>in</strong>e foreign key constra<strong>in</strong>ts to guard the <strong>in</strong>tegrity of your data.<br />
The syntax of a foreign key constra<strong>in</strong>t def<strong>in</strong>ition <strong>in</strong> <strong>InnoDB</strong>:<br />
[CONSTRAINT symbol] FOREIGN KEY (<strong>in</strong>dex_col_name, ...)<br />
REFERENCES table_name (<strong>in</strong>dex_col_name, ...)<br />
[ON DELETE CASCADE | ON DELETE SET NULL]<br />
Both tables have to be <strong>InnoDB</strong> type and there must be an <strong>in</strong>dex where the foreign key and the<br />
referenced key are listed as the first columns. <strong>InnoDB</strong> does not auto-create <strong>in</strong>dexes on foreign<br />
keys or referenced keys: you have to create them explicitly.<br />
Correspond<strong>in</strong>g columns <strong>in</strong> the foreign key and the referenced key must have similar <strong>in</strong>ternal data<br />
types <strong>in</strong>side <strong>InnoDB</strong> so that they can be compared without a type conversion. The size and the<br />
signedness of <strong>in</strong>teger types has to be the same. The length of str<strong>in</strong>g types need not be the same.<br />
Start<strong>in</strong>g from version 3.23.50, <strong>InnoDB</strong> does not check foreign key constra<strong>in</strong>ts on those foreign key<br />
or referenced key values which conta<strong>in</strong> a NULL column.<br />
Start<strong>in</strong>g from version 3.23.50 you can also associate the ON DELETE CASCADE or ON DELETE SET<br />
NULL clause with the foreign key constra<strong>in</strong>t. If ON DELETE CASCADE is specified, and a row <strong>in</strong> the<br />
parent table is deleted, then <strong>InnoDB</strong> automatically deletes also all those rows <strong>in</strong> the child table whose<br />
foreign key values are equal to the referenced key value <strong>in</strong> the parent row. If ON DELETE SET NULL<br />
is specified, the child rows are automatically updated so that the columns <strong>in</strong> the foreign key are set to<br />
the SQL NULL value.<br />
An example:<br />
CREATE TABLE parent(id INT NOT NULL,<br />
PRIMARY KEY (id)) TYPE=INNODB;<br />
CREATE TABLE child(id INT, parent_id INT,<br />
INDEX par_<strong>in</strong>d (parent_id),<br />
FOREIGN KEY (parent_id) REFERENCES parent(id)<br />
ON DELETE CASCADE<br />
) TYPE=INNODB;<br />
If <strong>MySQL</strong> gives the error number 1005 from a CREATE TABLE statement, and the error message<br />
str<strong>in</strong>g refers to errno 150, then the table creation failed because a foreign key constra<strong>in</strong>t was not<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 14 de 45<br />
correctly formed. Similarly, if an ALTER TABLE fails and it refers to errno 150, that means a foreign<br />
key def<strong>in</strong>ition would be <strong>in</strong>correctly formed for the altered table.<br />
Start<strong>in</strong>g from version 3.23.50 <strong>InnoDB</strong> allows you to add a new foreign key constra<strong>in</strong>t to a table<br />
through<br />
ALTER TABLE yourtablename<br />
ADD [CONSTRAINT symbol] FOREIGN KEY (...) REFERENCES anothertablename(...)<br />
Remember to create the required <strong>in</strong>dexes first, though. You can also add a self-referential foreign<br />
key constra<strong>in</strong>t to a table us<strong>in</strong>g ALTER TABLE.<br />
If you want to import several dumps of tables, but the dumps are not correctly ordered for foreign<br />
keys, start<strong>in</strong>g from 3.23.52 and 4.0.3 you can turn the foreign key checks off for a while <strong>in</strong> the<br />
import session:<br />
SET FOREIGN_KEY_CHECKS=0;<br />
This allows you to import the tables <strong>in</strong> any order, and also speeds up the import.<br />
Start<strong>in</strong>g from 3.23.50 the <strong>InnoDB</strong> parser allows you to use also backquotes around table and column<br />
names <strong>in</strong> a FOREIGN KEY ... REFERENCES ... clause, but the <strong>InnoDB</strong> parser is not yet aware of<br />
possible variable lower_case_table_names you give <strong>in</strong> my.cnf.<br />
In <strong>InnoDB</strong> versions < 3.23.50 ALTER TABLE or CREATE INDEX should not be used <strong>in</strong> connection with<br />
tables which have foreign key constra<strong>in</strong>ts or which are referenced <strong>in</strong> foreign key constra<strong>in</strong>ts: Any<br />
ALTER TABLE removes all foreign key constra<strong>in</strong>st def<strong>in</strong>ed for the table. You should not use ALTER<br />
TABLE to the referenced table either, but use DROP TABLE and CREATE TABLE to modify the schema.<br />
When <strong>MySQL</strong> does an ALTER TABLE it may <strong>in</strong>ternally use RENAME TABLE, and that will confuse the<br />
foreign key costra<strong>in</strong>ts which refer to the table. A CREATE INDEX statement is <strong>in</strong> <strong>MySQL</strong> processed as<br />
an ALTER TABLE, and these restrictions apply also to it.<br />
When do<strong>in</strong>g foreign key checks <strong>InnoDB</strong> sets shared row level locks on child or parent records it has<br />
to look at. <strong>InnoDB</strong> checks foreign key constra<strong>in</strong>ts immediately: the check is not deferred to<br />
transaction commit.<br />
<strong>InnoDB</strong> allows you to drop any table even though that would break the foreign key constra<strong>in</strong>ts which<br />
reference the table. When you drop a table the constra<strong>in</strong>ts which were def<strong>in</strong>ed <strong>in</strong> its create statement<br />
are also dropped.<br />
If you re-create a table which was dropped, it has to have a def<strong>in</strong>ition which conforms to the foreign<br />
key constra<strong>in</strong>ts referenc<strong>in</strong>g it. It must have the right column names and types, and it must have<br />
<strong>in</strong>dexes on the referenced keys, as stated above. If these are not satisfied, <strong>MySQL</strong> returns error<br />
number 1005 and refers to errno 150 <strong>in</strong> the error message str<strong>in</strong>g.<br />
Start<strong>in</strong>g from version 3.23.50 <strong>InnoDB</strong> returns the foreign key def<strong>in</strong>itions of a table when you call<br />
SHOW CREATE TABLE yourtablename<br />
Then also mysqldump produces correct def<strong>in</strong>itions of tables to the dump file, and does not forget<br />
about the foreign keys.<br />
You can also list the foreign key constra<strong>in</strong>ts for a table T with<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 15 de 45<br />
SHOW TABLE STATUS FROM yourdatabasename LIKE 'T'<br />
The foreign key constra<strong>in</strong>ts are listed <strong>in</strong> the table comment of the output.<br />
4.4 How an auto-<strong>in</strong>crement column works <strong>in</strong> <strong>InnoDB</strong><br />
If you specify an auto-<strong>in</strong>crement column for a table, then the <strong>InnoDB</strong> table handle <strong>in</strong> the data<br />
dictionary will conta<strong>in</strong> a special counter called the auto-<strong>in</strong>crement counter which is used <strong>in</strong> assign<strong>in</strong>g<br />
new values for the column. The auto-<strong>in</strong>crement counter is only stored <strong>in</strong> ma<strong>in</strong> memory, not on disk.<br />
<strong>InnoDB</strong> uses the follow<strong>in</strong>g algorith to <strong>in</strong>itialize the auto-<strong>in</strong>crement counter. After a database startup,<br />
when a user the first time does an <strong>in</strong>sert to a table T or calls SHOW TABLE STATUS where the table T is<br />
shown, then <strong>InnoDB</strong> executes<br />
SELECT MAX(auto-<strong>in</strong>c-column) FROM T FOR UPDATE,<br />
and assigns that value <strong>in</strong>cremented by one to the the column and the auto-<strong>in</strong>crement counter of the<br />
table. If the table is empty then the value 1 is assigned. Note that <strong>in</strong> this <strong>in</strong>itialization we do a normal<br />
x-lock<strong>in</strong>g read on the table and the lock lasts to the end of the transaction.<br />
<strong>InnoDB</strong> follows the same procedure <strong>in</strong> <strong>in</strong>itializ<strong>in</strong>g the auto-<strong>in</strong>crement counter for a freshly created<br />
table.<br />
If the user specifies <strong>in</strong> an <strong>in</strong>sert the value 0 to the auto-<strong>in</strong>crement column, then <strong>InnoDB</strong> treats the row<br />
like the value would not have been specified and generates a new value to it.<br />
After the auto-<strong>in</strong>crement counter has been <strong>in</strong>itialized, if a user <strong>in</strong>serts a row where he explicitly<br />
specifies the column value, and the value is bigger than the current counter value, then the counter is<br />
set to the specified column value. If the user does not explicitly specify a value, then <strong>InnoDB</strong><br />
<strong>in</strong>crements the counter by one and assigns its new value to the column.<br />
When access<strong>in</strong>g the auto-<strong>in</strong>crement counter <strong>InnoDB</strong> uses a special table level lock AUTO-INC lock<br />
which it keeps to the end of the current SQL statement, not to the end of the transaction. The special<br />
lock release strategy was <strong>in</strong>troduced to improve concurrency for <strong>in</strong>serts <strong>in</strong>to a table conta<strong>in</strong><strong>in</strong>g an<br />
auto-<strong>in</strong>crement column. Two transactions cannot have the AUTO-INC lock on the same table<br />
simultaneously.<br />
Note that you may get gaps <strong>in</strong> the auto-<strong>in</strong>crement column number sequence if you roll back<br />
transactions which have got numbers from the counter.<br />
The behavior of the auto-<strong>in</strong>crement mechanism is not def<strong>in</strong>ed if a user gives a negative value to the<br />
column or if the value becomes bigger than the maximum <strong>in</strong>teger that can be stored <strong>in</strong> the specified<br />
<strong>in</strong>teger type.<br />
5 Add<strong>in</strong>g and remov<strong>in</strong>g <strong>InnoDB</strong> data and log files<br />
To add a new data file to the tablespace you have to shut down your <strong>MySQL</strong> database, edit the<br />
my.cnf file, add<strong>in</strong>g a new file to <strong>in</strong>nodb_data_file_path, and then start <strong>MySQL</strong> aga<strong>in</strong>.<br />
Currently you cannot remove a data file from <strong>InnoDB</strong>. To decrease the size of your database you<br />
have to use mysqldump to dump all your tables, create a new database, and import your tables to the<br />
new database.<br />
If you want to change the number or the size of your <strong>InnoDB</strong> log files, you have to shut down<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 16 de 45<br />
<strong>MySQL</strong> and make sure that it shuts down without errors. Then copy the old log files <strong>in</strong>to a safe place<br />
just <strong>in</strong> case someth<strong>in</strong>g went wrong <strong>in</strong> the shutdown and you will need them to recover the database.<br />
Delete then the old log files from the log file directory, edit my.cnf, and start <strong>MySQL</strong> aga<strong>in</strong>. <strong>InnoDB</strong><br />
will tell you at the startup that it is creat<strong>in</strong>g new log files.<br />
6 Back<strong>in</strong>g up and recover<strong>in</strong>g an <strong>InnoDB</strong> database<br />
The key to safe database management is tak<strong>in</strong>g regular backups.<br />
<strong>InnoDB</strong> Hot Backup is an onl<strong>in</strong>e backup tool you can use to backup your <strong>InnoDB</strong> database while it<br />
is runn<strong>in</strong>g. <strong>InnoDB</strong> Hot Backup does not require you to shut down your database and it does not set<br />
any locks or disturb your normal database process<strong>in</strong>g. <strong>InnoDB</strong> Hot Backup is a non-free additional<br />
tool whose annual license fee is 400 euros per computer where the <strong>MySQL</strong> server is run. See the<br />
<strong>InnoDB</strong> Hot Backup homepage for detailed <strong>in</strong>formation and screenshots.<br />
If you are able to shut down your <strong>MySQL</strong> server, then to take a 'b<strong>in</strong>ary' backup of your database you<br />
have to do the follow<strong>in</strong>g:<br />
• Shut down your <strong>MySQL</strong> database and make sure it shuts down without errors.<br />
• Copy all your data files <strong>in</strong>to a safe place.<br />
• Copy all your <strong>InnoDB</strong> log files to a safe place.<br />
• Copy your my.cnf configuration file(s) to a safe place.<br />
• Copy all the .frm files for your <strong>InnoDB</strong> tables <strong>in</strong>to a safe place.<br />
At database sites requir<strong>in</strong>g high availability you can use the <strong>MySQL</strong> replication feature to keep a<br />
copy of your database. Replication works also with <strong>InnoDB</strong> type tables.<br />
In addition to tak<strong>in</strong>g the b<strong>in</strong>ary backups described above, you should also regularly take dumps of<br />
your tables with mysqldump. The reason to this is that a b<strong>in</strong>ary file may be corrupted without you<br />
notic<strong>in</strong>g it. Dumped tables are stored <strong>in</strong>to text files which are human-readable and much simpler than<br />
database b<strong>in</strong>ary files. See<strong>in</strong>g table corruption from dumped files is easier, and s<strong>in</strong>ce their format is<br />
simpler, the chance for serious data corruption <strong>in</strong> them is smaller.<br />
A good idea is to take the dumps at the same time you take a b<strong>in</strong>ary backup of your database. You<br />
have to shut out all clients from your database to get a consistent snapshot of all your tables <strong>in</strong>to your<br />
dumps. Then you can take the b<strong>in</strong>ary backup, and you will then have a consistent snapshot of your<br />
database <strong>in</strong> two formats.<br />
To be able to recover your <strong>InnoDB</strong> database to the present from the b<strong>in</strong>ary backup described above,<br />
you have to run your <strong>MySQL</strong> database with the b<strong>in</strong>logg<strong>in</strong>g of <strong>MySQL</strong> switched on. Then you can<br />
apply the b<strong>in</strong>log to the backup database to achieve po<strong>in</strong>t-<strong>in</strong>-time recovery:<br />
mysqlb<strong>in</strong>log yourhostname-b<strong>in</strong>.123 | mysql<br />
To recover from a crash of your <strong>MySQL</strong> server process, the only th<strong>in</strong>g you have to do is to restart it.<br />
<strong>InnoDB</strong> will automatically check the logs and perform a roll-forward of the database to the present.<br />
<strong>InnoDB</strong> will automatically roll back uncommitted transactions which were present at the time of the<br />
crash. Dur<strong>in</strong>g recovery, mysqld will pr<strong>in</strong>t out someth<strong>in</strong>g like the follow<strong>in</strong>g:<br />
heikki@donna:~/mysql-3.23.48/sql> mysqld<br />
020204 23:08:31 <strong>InnoDB</strong>: Database was not shut down normally.<br />
<strong>InnoDB</strong>: Start<strong>in</strong>g recovery from log files...<br />
<strong>InnoDB</strong>: Start<strong>in</strong>g log scan based on checkpo<strong>in</strong>t at<br />
<strong>InnoDB</strong>: log sequence number 0 177573790<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 177638912<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 17 de 45<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 177704448<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 177769984<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 177835520<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 177901056<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 177966592<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 178032128<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 178097664<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 178163200<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 178228736<br />
<strong>InnoDB</strong>: After this pr<strong>in</strong>ts a l<strong>in</strong>e for every 10th scan sweep:<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 178884096<br />
...<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 193302016<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 193957376<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 194612736<br />
020204 23:08:40 <strong>InnoDB</strong>: Start<strong>in</strong>g an apply batch of log records to the database.<br />
..<br />
<strong>InnoDB</strong>: Progress <strong>in</strong> percents: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19<br />
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46<br />
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 7<br />
3 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99<br />
<strong>InnoDB</strong>: Apply batch completed<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 195268096<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 195923456<br />
...<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 203132416<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 203787776<br />
<strong>InnoDB</strong>: Do<strong>in</strong>g recovery: scanned up to log sequence number 0 204443136<br />
<strong>InnoDB</strong>: 5 uncommitted transaction(s) which must be rolled back<br />
<strong>InnoDB</strong>: Trx id counter is 0 129792<br />
<strong>InnoDB</strong>: Start<strong>in</strong>g rollback of uncommitted transactions<br />
<strong>InnoDB</strong>: Roll<strong>in</strong>g back trx with id 0 129400<br />
<strong>InnoDB</strong>: Roll<strong>in</strong>g back of trx id 0 129400 completed<br />
<strong>InnoDB</strong>: Roll<strong>in</strong>g back trx with id 0 129217<br />
<strong>InnoDB</strong>: Roll<strong>in</strong>g back of trx id 0 129217 completed<br />
<strong>InnoDB</strong>: Roll<strong>in</strong>g back trx with id 0 129098<br />
<strong>InnoDB</strong>: Roll<strong>in</strong>g back of trx id 0 129098 completed<br />
<strong>InnoDB</strong>: Roll<strong>in</strong>g back trx with id 0 128743<br />
<strong>InnoDB</strong>: Roll<strong>in</strong>g back of trx id 0 128743 completed<br />
<strong>InnoDB</strong>: Roll<strong>in</strong>g back trx with id 0 127939<br />
<strong>InnoDB</strong>: Roll<strong>in</strong>g back of trx id 0 127939 completed<br />
<strong>InnoDB</strong>: Rollback of uncommitted transactions completed<br />
020204 23:08:51 <strong>InnoDB</strong>: Start<strong>in</strong>g an apply batch of log records to the database.<br />
..<br />
<strong>InnoDB</strong>: Progress <strong>in</strong> percents: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19<br />
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46<br />
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 7<br />
3 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99<br />
<strong>InnoDB</strong>: Apply batch completed<br />
<strong>InnoDB</strong>: Last <strong>MySQL</strong> b<strong>in</strong>log file offset 0 40418561, file name ./donna-b<strong>in</strong>.001<br />
020204 23:08:53 <strong>InnoDB</strong>: Flush<strong>in</strong>g modified pages from the buffer pool...<br />
020204 23:09:03 <strong>InnoDB</strong>: Started<br />
mysqld: ready for connections<br />
If your database gets corrupted or your disk fails, you have to do the recovery from a backup. In the<br />
case of corruption, you should first f<strong>in</strong>d a backup which is not corrupted. From a backup do the<br />
recovery from the general log files of <strong>MySQL</strong> accord<strong>in</strong>g to <strong>in</strong>structions <strong>in</strong> the <strong>MySQL</strong> manual.<br />
In some cases of database corruption it is enough just to dump, drop, and recreate one or a few<br />
corrupt tables. You can use the CHECK TABLE SQL command to check if a table is corrupt, though<br />
CHECK TABLE naturally cannot detect all k<strong>in</strong>ds of corruption. You can use<br />
<strong>in</strong>nodb_tablespace_monitor to check the <strong>in</strong>tegrity of the file space management <strong>in</strong>side the data<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 18 de 45<br />
files.<br />
In some cases apparent database page corruption is actually due to the operat<strong>in</strong>g system which has<br />
corrupted its own file cache, and the data on disk may be ok. It is best first to try reboot<strong>in</strong>g your<br />
computer. It may remove the errors which appeared as database page corruption.<br />
6.1 Forc<strong>in</strong>g recovery<br />
If there is database page corruption, you may want to dump your tables from the database with<br />
SELECT INTO OUTFILE, and usually most of the data is <strong>in</strong>tact and correct. But the corruption may<br />
cause <strong>InnoDB</strong> background operations to crash or assert, or even the <strong>InnoDB</strong> roll-forward recovery to<br />
crash. Start<strong>in</strong>g from the <strong>InnoDB</strong> version 3.23.44 there is a my.cnf option with which you can force<br />
<strong>InnoDB</strong> to start up, and you can also prevent background operations from runn<strong>in</strong>g, so that you will<br />
be able to dump your tables. For example, you can set<br />
set-variable = <strong>in</strong>nodb_force_recovery = 4<br />
<strong>in</strong> my.cnf.<br />
The alternatives for <strong>in</strong>nodb_force_recovery are listed below. The database must not otherwise be<br />
used with these options! As a safety measure <strong>InnoDB</strong> prevents a user from do<strong>in</strong>g INSERT, UPDATE, or<br />
DELETE when this option is > 0.<br />
Start<strong>in</strong>g from version <strong>3.23.53</strong> and <strong>4.0.4</strong> you are allowed to DROP or CREATE a table even if forced<br />
recovery is used. If you know that certa<strong>in</strong> table is caus<strong>in</strong>g a crash <strong>in</strong> rollback, you can drop it. You<br />
can use this also to stop a runaway rollback caused by a fail<strong>in</strong>g mass import or ALTER TABLE. You<br />
can kill the mysqld process and use the my.cnf option <strong>in</strong>nodb_force_recovery=3 to br<strong>in</strong>g your<br />
database up without the rollback. Then DROP the table which is caus<strong>in</strong>g the runaway rollback.<br />
A bigger number below means that all precautions of lower numbers are <strong>in</strong>cluded. If you are able to<br />
dump your tables with an option at most 4, then you are relatively safe that only some data on<br />
corrupt <strong>in</strong>dividual pages is lost. Option 6 is more dramatic, because database pages are left <strong>in</strong> an<br />
obsolete state, which <strong>in</strong> turn may <strong>in</strong>troduce more corruption <strong>in</strong>to B-trees and other database<br />
structures.<br />
• 1 (SRV_FORCE_IGNORE_CORRUPT) let the server run even if it detects a corrupt page;<br />
• 2 (SRV_FORCE_NO_BACKGROUND) prevent the ma<strong>in</strong> thread from runn<strong>in</strong>g: if a crash<br />
would occur <strong>in</strong> purge, this prevents it;<br />
• 3 (SRV_FORCE_NO_TRX_UNDO) do not run transaction rollbacks after recovery;<br />
• 4 (SRV_FORCE_NO_IBUF_MERGE) prevent also <strong>in</strong>sert buffer merge operations: if they<br />
would cause a crash, better not do them;<br />
• 5 (SRV_FORCE_NO_UNDO_LOG_SCAN) do not look at undo logs when start<strong>in</strong>g the<br />
database: <strong>InnoDB</strong> will treat even <strong>in</strong>complete transactions as committed;<br />
• 6 (SRV_FORCE_NO_LOG_REDO) do not do the log roll-forward <strong>in</strong> connection with<br />
recovery.<br />
6.2 Checkpo<strong>in</strong>ts<br />
<strong>InnoDB</strong> implements a checkpo<strong>in</strong>t mechanism called a fuzzy checkpo<strong>in</strong>t. <strong>InnoDB</strong> will flush modified<br />
database pages from the buffer pool <strong>in</strong> small batches, there is no need to flush the buffer pool <strong>in</strong> one<br />
s<strong>in</strong>gle batch, which would <strong>in</strong> practice stop process<strong>in</strong>g of user SQL statements for a while.<br />
In crash recovery <strong>InnoDB</strong> looks for a checkpo<strong>in</strong>t label written to the log files. It knows that all<br />
modifications to the database before the label are already present on the disk image of the database.<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 19 de 45<br />
Then <strong>InnoDB</strong> scans the log files forward from the place of the checkpo<strong>in</strong>t apply<strong>in</strong>g the logged<br />
modifications to the database.<br />
<strong>InnoDB</strong> writes to the log files <strong>in</strong> a circular fashion. All committed modifications which make the<br />
database pages <strong>in</strong> the buffer pool different from the images on disk must be available <strong>in</strong> the log files<br />
<strong>in</strong> case <strong>InnoDB</strong> has to do a recovery. This means that when <strong>InnoDB</strong> starts to reuse a log file <strong>in</strong> the<br />
circular fashion, it has to make sure that the database page images on disk already conta<strong>in</strong> the<br />
modifications logged <strong>in</strong> the log file <strong>InnoDB</strong> is go<strong>in</strong>g to reuse. In other words, <strong>InnoDB</strong> has to make a<br />
checkpo<strong>in</strong>t and often this <strong>in</strong>volves flush<strong>in</strong>g of modified database pages to disk.<br />
The above expla<strong>in</strong>s why mak<strong>in</strong>g your log files very big may save disk i/o <strong>in</strong> checkpo<strong>in</strong>t<strong>in</strong>g. It can<br />
make sense to set the total size of the log files as big as the buffer pool or even bigger. The drawback<br />
<strong>in</strong> big log files is that crash recovery can last longer because there will be more log to apply to the<br />
database.<br />
7 Mov<strong>in</strong>g an <strong>InnoDB</strong> database to another mach<strong>in</strong>e<br />
<strong>InnoDB</strong> data and log files are b<strong>in</strong>ary-compatible on all platforms if the float<strong>in</strong>g po<strong>in</strong>t number format<br />
on the mach<strong>in</strong>es is the same. You can move an <strong>InnoDB</strong> database simply by copy<strong>in</strong>g all the relevant<br />
files, which we already listed <strong>in</strong> the previous section on back<strong>in</strong>g up a database. If the float<strong>in</strong>g po<strong>in</strong>t<br />
formats on the mach<strong>in</strong>es are different but you have not used FLOAT or DOUBLE data types <strong>in</strong> your<br />
tables then the procedure is the same: just copy the relevant files. If the formats are different and<br />
your tables conta<strong>in</strong> float<strong>in</strong>g po<strong>in</strong>t data, you have to use mysqldump and mysqlimport to move those<br />
tables.<br />
A performance tip is to switch off the autocommit when you import data <strong>in</strong>to your database,<br />
assum<strong>in</strong>g your tablespace has enough space for the big rollback segment the big import transaction<br />
will generate. Do the commit only after import<strong>in</strong>g a whole table or a segment of a table.<br />
8 <strong>InnoDB</strong> transaction model and lock<strong>in</strong>g<br />
In the <strong>InnoDB</strong> transaction model the goal has been to comb<strong>in</strong>e the best properties of a<br />
multiversion<strong>in</strong>g database to traditional two-phase lock<strong>in</strong>g. <strong>InnoDB</strong> does lock<strong>in</strong>g on row level and<br />
runs queries by default as non-lock<strong>in</strong>g consistent reads, <strong>in</strong> the style of Oracle. The lock table <strong>in</strong><br />
<strong>InnoDB</strong> is stored so space-efficiently that lock escalation is not needed: typically several users are<br />
allowed to lock every row <strong>in</strong> the database, or any random subset of the rows, without <strong>InnoDB</strong><br />
runn<strong>in</strong>g out of memory.<br />
In <strong>InnoDB</strong> all user activity happens <strong>in</strong>side transactions. If the autocommit mode is used <strong>in</strong> <strong>MySQL</strong>,<br />
then each SQL statement will form a s<strong>in</strong>gle transaction. <strong>MySQL</strong> always starts a new connection with<br />
the autocommit mode switched on. If the autocommit mode is switched off with SET AUTOCOMMIT =<br />
0, then we can th<strong>in</strong>k that a user always has a transaction open. If he issues the SQL COMMIT or<br />
ROLLBACK statement, that ends the current transaction, and a new starts. Both statements will release<br />
all <strong>InnoDB</strong> locks that were set dur<strong>in</strong>g the current transaction. A COMMIT means that the changes made<br />
<strong>in</strong> the current transaction are made permanent and become visible to other users. A ROLLBACK on the<br />
other hand cancels all modifications made by the current transaction.<br />
In terms of the SQL-92 transaction isolation levels the <strong>InnoDB</strong> default is REPEATABLE READ. Start<strong>in</strong>g<br />
from version 3.23.50 the <strong>MySQL</strong> command<br />
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL [SERIALIZABLE| ...]<br />
has the follow<strong>in</strong>g effect on <strong>InnoDB</strong> tables: if a transaction is def<strong>in</strong>ed as SERIALIZABLE then <strong>InnoDB</strong><br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 20 de 45<br />
conceptually adds LOCK IN SHARE MODE to all consistent reads. This produces truly serializable<br />
execution of transactions. If a transaction is def<strong>in</strong>ed to have any other isolation level than<br />
SERIALIZABLE, then <strong>InnoDB</strong> follows the default lock<strong>in</strong>g strategy which is REPEATABLE READ. That<br />
means, for example, that sett<strong>in</strong>g the isolation level to READ UNCOMMITTED has no effect <strong>in</strong> <strong>InnoDB</strong>. In<br />
versions < 3.23.50 SET TRANSACTION had no effect on <strong>InnoDB</strong> tables.<br />
8.1 Consistent read<br />
A consistent read means that <strong>InnoDB</strong> uses its multiversion<strong>in</strong>g to present to a query a snapshot of the<br />
database at a po<strong>in</strong>t <strong>in</strong> time. The query will see the changes made by exactly those transactions that<br />
committed before that po<strong>in</strong>t of time, and no changes made by later or uncommitted transactions. The<br />
exception to this rule is that the query will see the changes made by the transaction itself which<br />
issues the query.<br />
When a transaction issues its first consistent read, <strong>InnoDB</strong> assigns the snapshot, or the po<strong>in</strong>t of time,<br />
which all consistent reads <strong>in</strong> the same transaction will use. In the snapshot are all transactions that<br />
committed before assign<strong>in</strong>g the snapshot. Thus the consistent reads with<strong>in</strong> the same transaction will<br />
also be consistent with respect to each other. You can get a fresher snapshot for your queries by<br />
committ<strong>in</strong>g the current transaction and after that issu<strong>in</strong>g new queries.<br />
Consistent read is the default mode <strong>in</strong> which <strong>InnoDB</strong> processes SELECT statements. A consistent read<br />
does not set any locks on the tables it accesses, and therefore other users are free to modify those<br />
tables at the same time a consistent read is be<strong>in</strong>g performed on the table.<br />
8.2 Lock<strong>in</strong>g reads<br />
A consistent read is not convenient <strong>in</strong> some circumstances. Suppose you want to add a new row <strong>in</strong>to<br />
your table CHILD, and make sure that the child already has a parent <strong>in</strong> table PARENT.<br />
Suppose you use a consistent read to read the table PARENT and <strong>in</strong>deed see the parent of the child <strong>in</strong><br />
the table. Can you now safely add the child row to table CHILD? No, because it may happen that<br />
meanwhile some other user has deleted the parent row from the table PARENT, and you are not aware<br />
of that.<br />
The solution is to perform the SELECT <strong>in</strong> a lock<strong>in</strong>g mode, LOCK IN SHARE MODE.<br />
SELECT * FROM PARENT WHERE NAME = 'Jones' LOCK IN SHARE MODE;<br />
Perform<strong>in</strong>g a read <strong>in</strong> share mode means that we read the latest available data, and set a shared mode<br />
lock on the rows we read. If the latest data belongs to a yet uncommitted transaction of another user,<br />
we will wait until that transaction commits. A shared mode lock prevents others from updat<strong>in</strong>g or<br />
delet<strong>in</strong>g the row we have read. After we see that the above query returns the parent 'Jones', we can<br />
safely add his child to table CHILD, and commit our transaction. This example shows how to<br />
implement referential <strong>in</strong>tegrity <strong>in</strong> your application code.<br />
Let us look at another example: we have an <strong>in</strong>teger counter field <strong>in</strong> a table CHILD_CODES which we<br />
use to assign a unique identifier to each child we add to table CHILD. Obviously, us<strong>in</strong>g a consistent<br />
read to read the present value of the counter is not a good idea, s<strong>in</strong>ce then two users of the database<br />
may see the same value for the counter, and we will get a duplicate key error when we add the two<br />
children with the same identifier to the table. Us<strong>in</strong>g LOCK IN SHARE MODE <strong>in</strong> the read is not a good<br />
solution either because if two users read the counter at the same time, then at least one of them will<br />
end up <strong>in</strong> deadlock when he tries to update the counter.<br />
In this case there are two good ways to implement the read<strong>in</strong>g and <strong>in</strong>crement<strong>in</strong>g of the counter: (1)<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 21 de 45<br />
update the counter first by <strong>in</strong>crement<strong>in</strong>g it by 1 and only after that read it, or (2) read the counter first<br />
with a lock mode FOR UPDATE, and <strong>in</strong>crement after that:<br />
SELECT COUNTER_FIELD FROM CHILD_CODES FOR UPDATE;<br />
UPDATE CHILD_CODES SET COUNTER_FIELD = COUNTER_FIELD + 1;<br />
A SELECT ... FOR UPDATE will read the latest available data sett<strong>in</strong>g exclusive locks on each row it<br />
reads. Thus it sets the same locks a searched SQL UPDATE would set on the rows.<br />
8.3 Next-key lock<strong>in</strong>g: avoid<strong>in</strong>g the 'phantom problem'<br />
In row level lock<strong>in</strong>g <strong>InnoDB</strong> uses an algorithm called next-key lock<strong>in</strong>g. <strong>InnoDB</strong> does the row level<br />
lock<strong>in</strong>g so that when it searches or scans an <strong>in</strong>dex of a table, it sets shared or exclusive locks on the<br />
<strong>in</strong>dex records <strong>in</strong> encounters. Thus the row level locks are more precisely called <strong>in</strong>dex record locks.<br />
The locks <strong>InnoDB</strong> sets on <strong>in</strong>dex records also affect the 'gap' before that <strong>in</strong>dex record. If a user has a<br />
shared or exclusive lock on record R <strong>in</strong> an <strong>in</strong>dex, then another user cannot <strong>in</strong>sert a new <strong>in</strong>dex record<br />
immediately before R <strong>in</strong> the <strong>in</strong>dex order. This lock<strong>in</strong>g of gaps is done to prevent the so-called<br />
phantom problem. Suppose I want to read and lock all children with identifier bigger than 100 from<br />
table CHILD, and update some field <strong>in</strong> the selected rows.<br />
SELECT * FROM CHILD WHERE ID > 100 FOR UPDATE;<br />
Suppose there is an <strong>in</strong>dex on table CHILD on column ID. Our query will scan that <strong>in</strong>dex start<strong>in</strong>g from<br />
the first record where ID is bigger than 100. Now, if the locks set on the <strong>in</strong>dex records would not<br />
lock out <strong>in</strong>serts made <strong>in</strong> the gaps, a new child might meanwhile be <strong>in</strong>serted to the table. If now I <strong>in</strong><br />
my transaction execute<br />
SELECT * FROM CHILD WHERE ID > 100 FOR UPDATE;<br />
aga<strong>in</strong>, I will see a new child <strong>in</strong> the result set the query returns. This is aga<strong>in</strong>st the isolation pr<strong>in</strong>ciple<br />
of transactions: a transaction should be able to run so that the data it has read does not change dur<strong>in</strong>g<br />
the transaction. If we regard a set of rows as a data item, then the new 'phantom' child would break<br />
this isolation pr<strong>in</strong>ciple.<br />
When <strong>InnoDB</strong> scans an <strong>in</strong>dex it can also lock the gap after the last record <strong>in</strong> the <strong>in</strong>dex. Just that<br />
happens <strong>in</strong> the previous example: the locks set by <strong>InnoDB</strong> will prevent any <strong>in</strong>sert to the table where<br />
ID would be bigger than 100.<br />
You can use next-key lock<strong>in</strong>g to implement a uniqueness check <strong>in</strong> your application: if you read your<br />
data <strong>in</strong> share mode and do not see a duplicate for a row you are go<strong>in</strong>g to <strong>in</strong>sert, then you can safely<br />
<strong>in</strong>sert your row and know that the next-key lock set on the successor of your row dur<strong>in</strong>g the read will<br />
prevent anyone meanwhile <strong>in</strong>sert<strong>in</strong>g a duplicate for your row. Thus the next-key lock<strong>in</strong>g allows you<br />
to 'lock' the non-existence of someth<strong>in</strong>g <strong>in</strong> your table.<br />
8.4 Locks set by different SQL statements <strong>in</strong> <strong>InnoDB</strong><br />
• SELECT ... FROM ... : this is a consistent read, read<strong>in</strong>g a snapshot of the database and<br />
sett<strong>in</strong>g no locks, unless the transaction isolation level is set to SERIALIZABLE, <strong>in</strong> which case<br />
this sets shared next-key locks on the <strong>in</strong>dex records it encounters.<br />
• SELECT ... FROM ... LOCK IN SHARE MODE : sets shared next-key locks on all <strong>in</strong>dex<br />
records the read encounters.<br />
• SELECT ... FROM ... FOR UPDATE : sets exclusive next-key locks on all <strong>in</strong>dex records the<br />
read encounters.<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 22 de 45<br />
• INSERT INTO ... VALUES (...) : sets an exclusive lock on the <strong>in</strong>serted row; note that this<br />
lock is not a next-key lock and does not prevent other users from <strong>in</strong>sert<strong>in</strong>g to the gap before<br />
the <strong>in</strong>serted row. If a duplicate key error occurs, sets a shared lock on the duplicate <strong>in</strong>dex<br />
record.<br />
• If you have specified an AUTO_INCREMENT column on a table, then <strong>in</strong> <strong>in</strong>itializ<strong>in</strong>g the auto<strong>in</strong>crement<br />
counter <strong>InnoDB</strong> sets an exclusive lock on the end of the <strong>in</strong>dex associated with the<br />
auto-<strong>in</strong>c column. In access<strong>in</strong>g the auto-<strong>in</strong>crement counter <strong>InnoDB</strong> uses a specific table lock<br />
mode AUTO-INC where the lock lasts only to the end of the current SQL statement, not to the<br />
end of the transaction.<br />
• INSERT INTO T SELECT ... FROM S WHERE ... sets an exclusive (non-next-key) lock on<br />
each row <strong>in</strong>serted <strong>in</strong>to T. Does the search on S as a consistent read, but sets shared next-key<br />
locks on S if the <strong>MySQL</strong> logg<strong>in</strong>g is on. <strong>InnoDB</strong> has to set locks <strong>in</strong> the latter case because <strong>in</strong><br />
roll-forward recovery from a backup every SQL statement has to be executed <strong>in</strong> exactly the<br />
same way as it was done orig<strong>in</strong>ally.<br />
• CREATE TABLE ... SELECT ... performs the SELECT as a consistent read or with shared<br />
locks, like <strong>in</strong> the previous item.<br />
• REPLACE is done like an <strong>in</strong>sert if there is no collision on a unique key. Otherwise, an exclusive<br />
next-key lock is placed on the row which has to be updated.<br />
• UPDATE ... SET ... WHERE ... : sets an exclusive next-key lock on every record the search<br />
encounters.<br />
• DELETE FROM ... WHERE ... : sets an exclusive next-key lock on every record the search<br />
encounters.<br />
• If a FOREIGN KEY constra<strong>in</strong>t is def<strong>in</strong>ed on a table, any <strong>in</strong>sert, update, or delete which requires<br />
check<strong>in</strong>g of the constra<strong>in</strong>t condition sets shared record level locks on the records it looks at to<br />
check the constra<strong>in</strong>t. Also <strong>in</strong> the case where the constra<strong>in</strong>t fails, <strong>InnoDB</strong> sets these locks.<br />
• LOCK TABLES ... : sets table locks. In the implementation the <strong>MySQL</strong> layer of code sets<br />
these locks. The automatic deadlock detection of <strong>InnoDB</strong> cannot detect deadlocks where such<br />
table locks are <strong>in</strong>volved: see the next section below. See also section 14 '<strong>InnoDB</strong> restrictions'<br />
about the follow<strong>in</strong>g: s<strong>in</strong>ce <strong>MySQL</strong> does know about row level locks, it is possible that you get<br />
a table lock on a table where another user currently has row level locks. But that does not put<br />
transaction <strong>in</strong>tegerity <strong>in</strong>to danger.<br />
• In versions < 3.23.50 SHOW TABLE STATUS applied to an auto-<strong>in</strong>crement table sets an exclusive<br />
row level lock to the high end of the auto-<strong>in</strong>crement <strong>in</strong>dex. This means that also SHOW TABLE<br />
STATUS can cause a deadlock of transactions, someth<strong>in</strong>g which may surprise users. Start<strong>in</strong>g<br />
from version 3.23.50, it fetches the auto-<strong>in</strong>c column value without sett<strong>in</strong>g any locks, except <strong>in</strong><br />
the case when there have been no <strong>in</strong>serts to the table after the database startup.<br />
8.5 When does <strong>MySQL</strong> implicitly commit or rollback a transaction?<br />
• <strong>MySQL</strong> has the autocommit mode switched on <strong>in</strong> a session if you do not do set<br />
autocommit=0. In the autocommit mode <strong>MySQL</strong> does a commit after each SQL statement, if<br />
that statement did not return an error.<br />
• If an error is returned by an SQL statement, then the commit/rollback behavior depends on the<br />
error. See section 13 for details.<br />
• The follow<strong>in</strong>g SQL statements cause an implicit commit of the current transaction <strong>in</strong> <strong>MySQL</strong>:<br />
CREATE TABLE (if <strong>MySQL</strong> b<strong>in</strong>logg<strong>in</strong>g is used), ALTER TABLE, BEGIN, CREATE INDEX,<br />
DROP DATABASE, DROP TABLE, RENAME TABLE, TRUNCATE, LOCK TABLES, UNLOCK<br />
TABLES. The CREATE TABLE statement <strong>in</strong> <strong>InnoDB</strong> is processed as a s<strong>in</strong>gle transaction. It means<br />
that a ROLLBACK from the user does not undo CREATE TABLE statements the user made dur<strong>in</strong>g<br />
his transaction.<br />
• If you <strong>in</strong> the autocommit mode use LOCK TABLES it is like BEGIN TRANSACTION <strong>in</strong> the sense<br />
that it switches the autocommit mode off until you call UNLOCK TABLES.<br />
• If you you have the autocommit mode off and end a connection without call<strong>in</strong>g an explicit<br />
COMMIT of your transaction, then <strong>MySQL</strong> will roll back your transaction.<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 23 de 45<br />
8.6 Deadlock detection and rollback<br />
<strong>InnoDB</strong> automatically detects a deadlock of transactions and rolls back the transaction whose lock<br />
request was the last one to build a deadlock, that is, a cycle <strong>in</strong> the waits-for graph of transactions.<br />
<strong>InnoDB</strong> cannot detect deadlocks where a lock set by a <strong>MySQL</strong> LOCK TABLES statement is <strong>in</strong>volved,<br />
or if a lock set <strong>in</strong> another table handler than <strong>InnoDB</strong> is <strong>in</strong>volved. You have to resolve these situations<br />
us<strong>in</strong>g <strong>in</strong>nodb_lock_wait_timeout set <strong>in</strong> my.cnf.<br />
When <strong>InnoDB</strong> performs a complete rollback of a transaction, all the locks of the transaction are<br />
released. However, if just a s<strong>in</strong>gle SQL statement is rolled back as a result of an error, some of the<br />
locks set by the SQL statement may be preserved. This is because <strong>InnoDB</strong> stores row locks <strong>in</strong> a<br />
format where it cannot afterwards know which was set by which SQL statement.<br />
8.7 An example of how the consistent read works <strong>in</strong> <strong>InnoDB</strong><br />
When you issue a consistent read, that is, an ord<strong>in</strong>ary SELECT statement, <strong>InnoDB</strong> will give your<br />
transaction a timepo<strong>in</strong>t accord<strong>in</strong>g to which your query sees the database. Thus, if transaction B<br />
deletes a row and commits after your timepo<strong>in</strong>t was assigned, then you will not see the row deleted.<br />
Similarly with <strong>in</strong>serts and updates.<br />
You can advance your timepo<strong>in</strong>t by committ<strong>in</strong>g your transaction and then do<strong>in</strong>g another SELECT.<br />
This is called multiversioned concurrency control.<br />
User A<br />
User B<br />
set autocommit=0; set autocommit=0;<br />
time<br />
| SELECT * FROM t;<br />
| empty set<br />
| INSERT INTO t VALUES (1, 2);<br />
|<br />
v SELECT * FROM t;<br />
empty set<br />
COMMIT;<br />
SELECT * FROM t;<br />
empty set;<br />
COMMIT;<br />
SELECT * FROM t;<br />
---------------------<br />
| 1 | 2 |<br />
---------------------<br />
Thus user A sees the row <strong>in</strong>serted by B only when B has committed the <strong>in</strong>sert, and A has committed<br />
his own transaction so that the timepo<strong>in</strong>t is advanced past the the commit of B.<br />
If you want to see the 'freshest' state of the database, you should use a lock<strong>in</strong>g read:<br />
SELECT * FROM t LOCK IN SHARE MODE;<br />
8.8 How to cope with deadlocks?<br />
Deadlocks are a classic problem <strong>in</strong> transactional databases, but they are not dangerous unless they<br />
are so frequent that you cannot run certa<strong>in</strong> transactions at all. Normally you have to write your<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 24 de 45<br />
applications so that they are always prepared to re-issue a transaction if it gets rolled back because of<br />
a deadlock.<br />
<strong>InnoDB</strong> uses automatic row level lock<strong>in</strong>g. You can get deadlocks even <strong>in</strong> the case of transactions<br />
which just <strong>in</strong>sert or delete a s<strong>in</strong>gle row. That is because these operations are not really 'atomic': they<br />
automatically set locks on the (possibly several) <strong>in</strong>dex records of the row <strong>in</strong>serted/deleted.<br />
You can cope with deadlocks and reduce the number of them with the follow<strong>in</strong>g tricks:<br />
• Use SHOW INNODB STATUS <strong>in</strong> <strong>MySQL</strong> versions >= 3.23.52 and >= 4.0.3 to determ<strong>in</strong>e the cause<br />
of the latest deadlock. That can help to tune your application to avoid deadlocks.<br />
• Always be prepared to re-issue a transaction if it fails <strong>in</strong> a deadlock. Deadlocks are not<br />
dangerous. Just try aga<strong>in</strong>.<br />
• Commit your transactions often. Small transactions are less prone to collide.<br />
• Access your tables and rows <strong>in</strong> a fixed order. Then transactions will form nice queues, and do<br />
not deadlock.<br />
• Add good <strong>in</strong>dexes to your tables. Then your queries need to scan less <strong>in</strong>dex records and<br />
consequently set less locks. Use EXPLAIN SELECT to determ<strong>in</strong>e that <strong>MySQL</strong> picks appropriate<br />
<strong>in</strong>dexes for your queries.<br />
• Use less lock<strong>in</strong>g: if you can afford a SELECT to return data from an old snapshot, do not add<br />
the clause FOR UPDATE or LOCK IN SHARE MODE to it.<br />
• If noth<strong>in</strong>g helps, serialize your transactions with table level locks: LOCK TABLES t1 WRITE,<br />
t2 READ, ... ; [do someth<strong>in</strong>g with tables t1 and t2 here]; UNLOCK TABLES.<br />
Table level locks make you transactions to queue nicely, and deadlocks are avoided. Note that<br />
LOCK TABLES implicitly starts a transaction, just like the command BEGIN, and UNLOCK<br />
TABLES implicitly ends the transaction <strong>in</strong> a COMMIT.<br />
• Another solution to serialize transactions is to create an auxiliary 'semaphore' table where there<br />
is just a s<strong>in</strong>gle row. Each transaction updates that row before access<strong>in</strong>g other tables. In that<br />
way all transactions happen <strong>in</strong> a serial fashion. Note that then also the <strong>InnoDB</strong> <strong>in</strong>stant<br />
deadlock detection algorithm works, because the serializ<strong>in</strong>g lock is a row level lock. In<br />
<strong>MySQL</strong> table level locks we have to resort to the timeout method.<br />
9 Performance tun<strong>in</strong>g tips<br />
1. If the Unix top or the W<strong>in</strong>dows Task Manager shows that the CPU usage percentage with your<br />
workload is less than 70 %, your workload is probably disk-bound. Maybe you are mak<strong>in</strong>g too many<br />
transaction commits, or the buffer pool is too small. Mak<strong>in</strong>g the buffer pool bigger can help, but do<br />
not set it bigger than 80 % of physical memory.<br />
2. Wrap several modifications <strong>in</strong>to one transaction. <strong>InnoDB</strong> must flush the log to disk at each<br />
transaction commit, if that transaction made modifications to the database. S<strong>in</strong>ce the rotation speed<br />
of a disk is typically at most 167 revolutions/second, that constra<strong>in</strong>s the number of commits to the<br />
same 167/second per user if the disk does not fool the operat<strong>in</strong>g system.<br />
3. If you can afford the loss of some latest committed transactions, you can set the my.cnf parameter<br />
<strong>in</strong>nodb_flush_log_at_trx_commit to zero. <strong>InnoDB</strong> tries to flush the log anyway once <strong>in</strong> a second,<br />
though the flush is not guaranteed.<br />
4. Make your log files big, the comb<strong>in</strong>ed size of the log files even as big as the buffer pool. When<br />
<strong>InnoDB</strong> has written the log files full, it has to write the modified contents of the buffer pool to disk<br />
<strong>in</strong> a checkpo<strong>in</strong>t. Small log files will cause many unnecessary disk writes. The drawback <strong>in</strong> big log<br />
files is that recovery time will be longer.<br />
5. Also the log buffer should be quite big, say 8 MB.<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 25 de 45<br />
6. Use the VARCHAR column type <strong>in</strong>stead of CHAR if you are stor<strong>in</strong>g variable-length str<strong>in</strong>gs or the<br />
column may conta<strong>in</strong> many NULLs. A CHAR(n) column always takes n bytes to store data, even if the<br />
str<strong>in</strong>g is shorter, or its value is NULL. Smaller tables fit better <strong>in</strong> the buffer pool and reduce disk i/o.<br />
7. (Relevant from 3.23.41 up.) In some versions of L<strong>in</strong>ux and other Unixes flush<strong>in</strong>g files to disk with<br />
the Unix fsync and other similar methods is surpris<strong>in</strong>gly slow. The default method <strong>InnoDB</strong> uses is<br />
the fsync function. If you are not satisfied with the database write performance, you may try sett<strong>in</strong>g<br />
<strong>in</strong>nodb_flush_method <strong>in</strong> my.cnf to O_DSYNC, though the O_DSYNC option seems to be slower on<br />
most systems.<br />
8. In import<strong>in</strong>g data to <strong>InnoDB</strong>, make sure that <strong>MySQL</strong> does not have autocommit=1 on. Then every<br />
<strong>in</strong>sert requires a log flush to disk. Put before your pla<strong>in</strong> SQL import file l<strong>in</strong>e<br />
set autocommit=0;<br />
and after it<br />
commit;<br />
If you use the mysqldump option --opt, you will get dump files which are fast to import also to an<br />
<strong>InnoDB</strong> table, even without wrapp<strong>in</strong>g them to the above set autocommit=0; ... commit;<br />
wrappers.<br />
9. Beware of big rollbacks of mass <strong>in</strong>serts: <strong>InnoDB</strong> uses the <strong>in</strong>sert buffer to save disk i/o <strong>in</strong> <strong>in</strong>serts,<br />
but <strong>in</strong> a correspond<strong>in</strong>g rollback no such mechanism is used. A disk-bound rollback can take 30 times<br />
the time of the correspond<strong>in</strong>g <strong>in</strong>sert. If a runaway rollback hits, you can use the trick expla<strong>in</strong>ed <strong>in</strong><br />
section 6.1 to stop it.<br />
10. Beware also of other big disk-bound operations. Use DROP TABLE or TRUNCATE (from <strong>MySQL</strong>-<br />
4.0 up) to empty a table, not DELETE FROM yourtable.<br />
11. Use the multi-l<strong>in</strong>e INSERT to reduce communication overhead between the client and the server if<br />
you need to <strong>in</strong>sert many rows:<br />
INSERT INTO yourtable VALUES (1, 2), (5, 5);<br />
This tip is of course valid for <strong>in</strong>serts <strong>in</strong>to any table type, not just <strong>InnoDB</strong>.<br />
12. If you have UNIQUE constra<strong>in</strong>ts on secondary keys, start<strong>in</strong>g from 3.23.52 and 4.0.3 you can speed<br />
up table imports by turn<strong>in</strong>g the uniqueness checks off for a while <strong>in</strong> the import session:<br />
SET UNIQUE_CHECKS=0;<br />
For big tables this saves a lot of disk i/o because <strong>InnoDB</strong> can then use its <strong>in</strong>sert buffer to write<br />
secondary <strong>in</strong>dex records <strong>in</strong> a batch.<br />
13. If you have FOREIGN KEY constra<strong>in</strong>ts <strong>in</strong> your tables, start<strong>in</strong>g from 3.23.52 and 4.0.3 you can<br />
speed up table imports by turn<strong>in</strong>g the foreign key checks off for a while <strong>in</strong> the import session:<br />
SET FOREIGN_KEY_CHECKS=0;<br />
For big tables this can save a lot of disk i/o.<br />
9.1 <strong>InnoDB</strong> Monitors<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 26 de 45<br />
Start<strong>in</strong>g from version 3.23.42 <strong>InnoDB</strong> <strong>in</strong>cludes <strong>InnoDB</strong> Monitors which pr<strong>in</strong>t <strong>in</strong>formation on the<br />
<strong>InnoDB</strong> <strong>in</strong>ternal state. Start<strong>in</strong>g from versions 3.23.52 and 4.0.3 you can use a new SQL command<br />
SHOW INNODB STATUS<br />
to fetch the output of the standard <strong>InnoDB</strong> Monitor to the SQL client. The data is useful <strong>in</strong><br />
performance tun<strong>in</strong>g.<br />
Another way to use <strong>InnoDB</strong> Monitors is to let them cont<strong>in</strong>uosly write data to the standard output of<br />
the server mysqld. When switched on, <strong>InnoDB</strong> Monitors pr<strong>in</strong>t data (note: the <strong>MySQL</strong> client will not<br />
pr<strong>in</strong>t anyth<strong>in</strong>g) about once every 15 seconds. An easy way to use them is to start the mysqld<br />
executable from a command prompt. Otherwise the output is directed to the error log file of the<br />
<strong>MySQL</strong> server 'yourhostname'.err (on W<strong>in</strong>dows mysql.err). On W<strong>in</strong>dows you must start<br />
mysqld-max from an MS-DOS prompt with the --console option to direct the output to the<br />
command prompt w<strong>in</strong>dow.<br />
The pr<strong>in</strong>ted <strong>in</strong>formation <strong>in</strong>cludes data on:<br />
• table and record locks held by each active transaction,<br />
• lock waits of a transactions,<br />
• semaphore waits of threads,<br />
• pend<strong>in</strong>g file i/o requests,<br />
• buffer pool statistics, and<br />
• purge and <strong>in</strong>sert buffer merge activity of the ma<strong>in</strong> thread of <strong>InnoDB</strong>.<br />
You can make the standard <strong>InnoDB</strong> Monitor to write to the standard output of mysqld through the<br />
follow<strong>in</strong>g SQL command:<br />
CREATE TABLE <strong>in</strong>nodb_monitor(a <strong>in</strong>t) type = <strong>in</strong>nodb;<br />
and stop it by<br />
DROP TABLE <strong>in</strong>nodb_monitor;<br />
The CREATE TABLE syntax is just a way to pass a command to the <strong>InnoDB</strong> eng<strong>in</strong>e through the<br />
<strong>MySQL</strong> SQL parser: the created table is not relevant at all for the <strong>InnoDB</strong> Monitor. If you shut down<br />
the database when the monitor is runn<strong>in</strong>g, and you want to start the monitor aga<strong>in</strong>, you have to drop<br />
the table before you can issue a new CREATE TABLE to start the monitor.<br />
In a similar way you can start <strong>in</strong>nodb_lock_monitor which is otherwise the same as<br />
<strong>in</strong>nodb_monitor but it also pr<strong>in</strong>ts a lot of lock <strong>in</strong>formation. A separate<br />
<strong>in</strong>nodb_tablespace_monitor pr<strong>in</strong>ts a list of created file segments exist<strong>in</strong>g <strong>in</strong> the tablespace and<br />
also validates the tablespace allocation data structures. Start<strong>in</strong>g from 3.23.44 there is<br />
<strong>in</strong>nodb_table_monitor with which you can pr<strong>in</strong>t the contents of the <strong>in</strong>ternal data dictionary of<br />
<strong>InnoDB</strong>.<br />
A sample output of the <strong>InnoDB</strong> Monitor from version 3.23.52:<br />
=====================================<br />
020805 22:07:41 INNODB MONITOR OUTPUT<br />
=====================================<br />
Per second averages calculated from the last 3 seconds<br />
----------<br />
SEMAPHORES<br />
----------<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 27 de 45<br />
OS WAIT ARRAY INFO: reservation count 194, signal count 193<br />
--Thread 7176 has waited at ../<strong>in</strong>clude/btr0btr.ic l<strong>in</strong>e 28 for 0.00 seconds the s<br />
emaphore:<br />
X-lock on RW-latch at 44d980bc created <strong>in</strong> file buf0buf.c l<strong>in</strong>e 354<br />
a writer (thread id 7176) has reserved it <strong>in</strong> mode wait exclusive<br />
number of readers 1, waiters flag 1<br />
Last time read locked <strong>in</strong> file ../<strong>in</strong>clude/btr0btr.ic l<strong>in</strong>e 28<br />
Last time write locked <strong>in</strong> file ../<strong>in</strong>clude/btr0btr.ic l<strong>in</strong>e 28<br />
Mutex sp<strong>in</strong> waits 0, rounds 0, OS waits 0<br />
RW-shared sp<strong>in</strong>s 77, OS waits 33; RW-excl sp<strong>in</strong>s 188, OS waits 161<br />
------------<br />
TRANSACTIONS<br />
------------<br />
Trx id counter 0 657853517<br />
Purge done for trx's n:o < 0 657853429 undo n:o < 0 80<br />
Total number of lock structs <strong>in</strong> row lock hash table 22<br />
020805 22:07:36 LATEST DETECTED DEADLOCK:<br />
*** (1) TRANSACTION:<br />
TRANSACTION 0 657853503, ACTIVE 0 sec, OS thread id 15373 <strong>in</strong>sert<strong>in</strong>g<br />
LOCK WAIT 3 lock struct(s), heap size 336<br />
<strong>MySQL</strong> thread id 6, query id 3741 localhost heikki update<br />
<strong>in</strong>sert <strong>in</strong>to ibtest11b (D, B, C) values (5, 'khdkkkk' ,'khdkkkk')<br />
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:<br />
RECORD LOCKS space id 0 page no 104865 n bits 208 table test/ibtest11b <strong>in</strong>dex PRI<br />
MARY trx id 0 657853503 lock_mode X wait<strong>in</strong>g<br />
Record lock, heap no 1 RECORD: <strong>in</strong>fo bits 0 0: len 9; hex 73757072656d756d00; asc<br />
supremum.;;<br />
*** (2) TRANSACTION:<br />
TRANSACTION 0 657853500, ACTIVE 0 sec, OS thread id 11275 sett<strong>in</strong>g auto-<strong>in</strong>c lock<br />
19 lock struct(s), heap size 2672, undo log entries 5<br />
<strong>MySQL</strong> thread id 2, query id 3750 localhost heikki update<br />
<strong>in</strong>sert <strong>in</strong>to ibtest11b (D, B, C) values (5, 'khD' ,'khD')<br />
*** (2) HOLDS THE LOCK(S):<br />
RECORD LOCKS space id 0 page no 104865 n bits 200 table test/ibtest11b <strong>in</strong>dex PRI<br />
MARY trx id 0 657853500 lock_mode X<br />
Record lock, heap no 1 RECORD: <strong>in</strong>fo bits 0 0: len 9; hex 73757072656d756d00; asc<br />
supremum.;;<br />
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:<br />
TABLE LOCK table test/ibtest11b trx id 0 657853500 lock_mode AUTO-INC wait<strong>in</strong>g<br />
*** WE ROLL BACK TRANSACTION (2)<br />
LIST OF TRANSACTIONS FOR EACH SESSION:<br />
---TRANSACTION 0 657853516, ACTIVE 5 sec, OS thread id 15373 sett<strong>in</strong>g auto-<strong>in</strong>c lo<br />
ck<br />
LOCK WAIT 1 lock struct(s), heap size 336<br />
<strong>MySQL</strong> thread id 6, query id 3895 localhost heikki update<br />
<strong>in</strong>sert <strong>in</strong>to ibtest11b (D, B, C) values (5, 'khdkkkk' ,'khdkkkk')<br />
------- TRX HAS BEEN WAITING 5 SEC FOR THIS LOCK TO BE GRANTED:<br />
TABLE LOCK table test/ibtest11b trx id 0 657853516 lock_mode AUTO-INC wait<strong>in</strong>g<br />
------------------<br />
---TRANSACTION 0 657853514, ACTIVE 5 sec, OS thread id 11275 <strong>in</strong>sert<strong>in</strong>g<br />
LOCK WAIT 13 lock struct(s), heap size 2672, undo log entries 2<br />
<strong>MySQL</strong> thread id 2, query id 3898 localhost heikki update<br />
<strong>in</strong>sert <strong>in</strong>to ibtest11d (D, B, C) values (5, 'khdkkkk' ,'khdkkkk')<br />
------- TRX HAS BEEN WAITING 5 SEC FOR THIS LOCK TO BE GRANTED:<br />
RECORD LOCKS space id 0 page no 104879 n bits 384 table test/ibtest11d <strong>in</strong>dex B t<br />
rx id 0 657853514 lock_mode X gap type lock wait<strong>in</strong>g<br />
Record lock, heap no 130 RECORD: <strong>in</strong>fo bits 32 0: len 9; hex 6b48646b6b6b6b6b6b;<br />
asc kHdkkkkkk;; 1:<br />
------------------<br />
---TRANSACTION 0 657853512, ACTIVE 5 sec, OS thread id 14348 updat<strong>in</strong>g or delet<strong>in</strong><br />
g<br />
20 lock struct(s), heap size 2672, undo log entries 175<br />
<strong>MySQL</strong> thread id 5, query id 3874 localhost heikki updat<strong>in</strong>g<br />
delete from ibtest11a where A = 215<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 28 de 45<br />
--------<br />
FILE I/O<br />
--------<br />
I/O thread 0 state: wait<strong>in</strong>g for i/o request<br />
I/O thread 1 state: wait<strong>in</strong>g for i/o request<br />
I/O thread 2 state: wait<strong>in</strong>g for i/o request<br />
I/O thread 3 state: wait<strong>in</strong>g for i/o request<br />
Pend<strong>in</strong>g normal aio reads: 0, aio writes: 0,<br />
ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0<br />
Pend<strong>in</strong>g flushes (fsync) log: 0; buffer pool: 0<br />
272 OS file reads, 56 OS file writes, 29 OS fsyncs<br />
0.00 reads/s, 0 avg bytes/read, 0.00 writes/s, 0.00 fsyncs/s<br />
-------------------------------------<br />
INSERT BUFFER AND ADAPTIVE HASH INDEX<br />
-------------------------------------<br />
Ibuf for space 0: size 1, free list len 5, seg size 7,<br />
0 <strong>in</strong>serts, 0 merged recs, 0 merges<br />
Hash table size 124633, used cells 1530, node heap has 4 buffer(s)<br />
2895.70 hash searches/s, 126.62 non-hash searches/s<br />
---<br />
LOG<br />
---<br />
Log sequence number 19 3267291494<br />
Log flushed up to 19 3267283711<br />
Last checkpo<strong>in</strong>t at 19 3266545677<br />
0 pend<strong>in</strong>g log writes, 0 pend<strong>in</strong>g chkp writes<br />
30 log i/o's done, 0.00 log i/o's/second<br />
----------------------<br />
BUFFER POOL AND MEMORY<br />
----------------------<br />
Total memory allocated 82593970; <strong>in</strong> additional pool allocated 1406336<br />
Buffer pool size 1920<br />
Free buffers 1711<br />
Database pages 205<br />
Modified db pages 39<br />
Pend<strong>in</strong>g reads 0<br />
Pend<strong>in</strong>g writes: LRU 0, flush list 0, s<strong>in</strong>gle page 0<br />
Pages read 178, created 27, written 50<br />
0.00 reads/s, 0.00 creates/s, 0.00 writes/s<br />
Buffer pool hit rate 1000 / 1000<br />
--------------<br />
ROW OPERATIONS<br />
--------------<br />
1 queries <strong>in</strong>side <strong>InnoDB</strong>, 0 queries <strong>in</strong> queue; ma<strong>in</strong> thread: purg<strong>in</strong>g<br />
Number of rows <strong>in</strong>serted 2008, updated 264, deleted 162, read 9<br />
0.00 <strong>in</strong>serts/s, 0.00 updates/s, 14.66 deletes/s, 0.00 reads/s<br />
----------------------------<br />
END OF INNODB MONITOR OUTPUT<br />
============================<br />
Some notes on the output:<br />
• If the section TRANSACTIONS reports lock waits, then your application may have lock<br />
contention. The output can also help to trace reasons for transaction deadlocks.<br />
• Section SEMAPHORES reports threads wait<strong>in</strong>g for a semaphore and statistics on how many<br />
times threads have needed a sp<strong>in</strong> or a wait on a mutex or a rw-lock semaphore. A big number<br />
of threads wait<strong>in</strong>g for semaphores may be a result of disk i/o, or contention problems <strong>in</strong>side<br />
<strong>InnoDB</strong>. Contention can be due to heavy parallelism of queries, or problems <strong>in</strong> operat<strong>in</strong>g<br />
system thread schedul<strong>in</strong>g. Sett<strong>in</strong>g <strong>in</strong>nodb_thread_concurrency smaller than the default 8<br />
can help <strong>in</strong> such situations.<br />
• Section FILE I/O lists pend<strong>in</strong>g file i/o requests. A large number of these <strong>in</strong>dicates that the<br />
workload is disk i/o-bound.<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 29 de 45<br />
• Section BUFFER POOL AND MEMORY gives you statistics on pages read and written. You<br />
can calculate from these numbers how many data file i/o's your queries are currently do<strong>in</strong>g.<br />
10 Implementation of multiversion<strong>in</strong>g<br />
S<strong>in</strong>ce <strong>InnoDB</strong> is a multiversioned database, it must keep <strong>in</strong>formation of old versions of rows <strong>in</strong> the<br />
tablespace. This <strong>in</strong>formation is stored <strong>in</strong> a data structure we call a rollback segment after an<br />
analogous data structure <strong>in</strong> Oracle.<br />
<strong>InnoDB</strong> <strong>in</strong>ternally adds two fields to each row stored <strong>in</strong> the database. A 6-byte field tells the<br />
transaction identifier for the last transaction which <strong>in</strong>serted or updated the row. Also a deletion is<br />
<strong>in</strong>ternally treated as an update where a special bit <strong>in</strong> the row is set to mark it as deleted. Each row<br />
also conta<strong>in</strong>s a 7-byte field called the roll po<strong>in</strong>ter. The roll po<strong>in</strong>ter po<strong>in</strong>ts to an undo log record<br />
written to the rollback segment. If the row was updated, then the undo log record conta<strong>in</strong>s the<br />
<strong>in</strong>formation necessary to rebuild the content of the row before it was updated.<br />
<strong>InnoDB</strong> uses the <strong>in</strong>formation <strong>in</strong> the rollback segment to perform the undo operations needed <strong>in</strong> a<br />
transaction rollback. It also uses the <strong>in</strong>formation to build earlier versions of a row for a consistent<br />
read.<br />
Undo logs <strong>in</strong> the rollback segment are divided <strong>in</strong>to <strong>in</strong>sert and update undo logs. Insert undo logs are<br />
only needed <strong>in</strong> transaction rollback and can be discarded as soon as the transaction commits. Update<br />
undo logs are used also <strong>in</strong> consistent reads, and they can be discarded only after there is no<br />
transaction present for which <strong>InnoDB</strong> has assigned a snapshot that <strong>in</strong> a consistent read could need the<br />
<strong>in</strong>formation <strong>in</strong> the update undo log to build an earlier version of a database row.<br />
You must remember to commit your transactions regularly, also those transactions which only issue<br />
consistent reads. Otherwise <strong>InnoDB</strong> cannot discard data from the update undo logs, and the rollback<br />
segment may grow too big, fill<strong>in</strong>g up your tablespace.<br />
The physical size of an undo log record <strong>in</strong> the rollback segment is typically smaller than the<br />
correspond<strong>in</strong>g <strong>in</strong>serted or updated row. You can use this <strong>in</strong>formation to calculate the space need for<br />
your rollback segment.<br />
In our multiversion<strong>in</strong>g scheme a row is not physically removed from the database immediately when<br />
you delete it with an SQL statement. Only when <strong>InnoDB</strong> can discard the update undo log record<br />
written for the deletion, it can also physically remove the correspond<strong>in</strong>g row and its <strong>in</strong>dex records<br />
from the database. This removal operation is called a purge, and it is quite fast, usually tak<strong>in</strong>g the<br />
same order of time as the SQL statement which did the deletion.<br />
11 Table and <strong>in</strong>dex structures<br />
<strong>MySQL</strong> stores its data dictionary <strong>in</strong>formation of tables <strong>in</strong> .frm files <strong>in</strong> database directories. But<br />
every <strong>InnoDB</strong> type table also has its own entry <strong>in</strong> <strong>InnoDB</strong> <strong>in</strong>ternal data dictionaries <strong>in</strong>side the<br />
tablespace. When <strong>MySQL</strong> drops a table or a database, it has to delete both a .frm file or files, and<br />
the correspond<strong>in</strong>g entries <strong>in</strong>side the <strong>InnoDB</strong> data dictionary. This is the reason why you cannot move<br />
<strong>InnoDB</strong> tables between databases simply by mov<strong>in</strong>g the .frm files, and why DROP DATABASE did not<br />
work for <strong>InnoDB</strong> type tables <strong>in</strong> <strong>MySQL</strong> versions
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 30 de 45<br />
If you do not def<strong>in</strong>e a primary key for your table, <strong>InnoDB</strong> will <strong>in</strong>ternally generate a clustered <strong>in</strong>dex<br />
where the rows are ordered by the row id <strong>InnoDB</strong> assigns to the rows <strong>in</strong> such a table. The row id is a<br />
6-byte field which monotonically <strong>in</strong>creases as new rows are <strong>in</strong>serted. Thus the rows ordered by the<br />
row id will be physically <strong>in</strong> the <strong>in</strong>sertion order.<br />
Access<strong>in</strong>g a row through the clustered <strong>in</strong>dex is fast, because the row data will be on the same page<br />
where the <strong>in</strong>dex search leads us. In many databases the data is traditionally stored on a different page<br />
from the <strong>in</strong>dex record. If a table is large, the clustered <strong>in</strong>dex architecture often saves a disk i/o when<br />
compared to the traditional solution.<br />
The records <strong>in</strong> non-clustered <strong>in</strong>dexes (we also call them secondary <strong>in</strong>dexes), <strong>in</strong> <strong>InnoDB</strong> conta<strong>in</strong> the<br />
primary key value for the row. <strong>InnoDB</strong> uses this primary key value to search for the row from the<br />
clustered <strong>in</strong>dex. Note that if the primary key is long, the secondary <strong>in</strong>dexes will use more space.<br />
<strong>InnoDB</strong> compares CHAR and VARCHAR str<strong>in</strong>gs of different length so that the rema<strong>in</strong><strong>in</strong>g length <strong>in</strong> the<br />
shorter str<strong>in</strong>g is thought of as padded with spaces.<br />
11.1 Physical structure of an <strong>in</strong>dex<br />
All <strong>in</strong>dexes <strong>in</strong> <strong>InnoDB</strong> are B-trees where the <strong>in</strong>dex records are stored <strong>in</strong> the leaf pages of the tree.<br />
The default size of an <strong>in</strong>dex page is 16 kB. When new records are <strong>in</strong>serted, <strong>InnoDB</strong> tries to leave 1 /<br />
16 of the page free for future <strong>in</strong>sertions and updates of the <strong>in</strong>dex records.<br />
If <strong>in</strong>dex records are <strong>in</strong>serted <strong>in</strong> a sequential (ascend<strong>in</strong>g or descend<strong>in</strong>g) order, the result<strong>in</strong>g <strong>in</strong>dex<br />
pages will be about 15/16 full. If records are <strong>in</strong>serted <strong>in</strong> a random order, then the pages will be 1/2 -<br />
15/16 full. If the fillfactor of an <strong>in</strong>dex page drops below 1/2, <strong>InnoDB</strong> will try to contract the <strong>in</strong>dex<br />
tree to free the page.<br />
11.2 Insert buffer<strong>in</strong>g<br />
It is a common situation <strong>in</strong> a database application that the primary key is a unique identifier and new<br />
rows are <strong>in</strong>serted <strong>in</strong> the ascend<strong>in</strong>g order of the primary key. Thus the <strong>in</strong>sertions to the clustered <strong>in</strong>dex<br />
do not require random reads from a disk.<br />
On the other hand, secondary <strong>in</strong>dexes are usually non-unique and <strong>in</strong>sertions happen <strong>in</strong> a relatively<br />
random order <strong>in</strong>to secondary <strong>in</strong>dexes. This would cause a lot of random disk i/o's without a special<br />
mechanism used <strong>in</strong> <strong>InnoDB</strong>.<br />
If an <strong>in</strong>dex record should be <strong>in</strong>serted to a non-unique secondary <strong>in</strong>dex, <strong>InnoDB</strong> checks if the<br />
secondary <strong>in</strong>dex page is already <strong>in</strong> the buffer pool. If that is the case, <strong>InnoDB</strong> will do the <strong>in</strong>sertion<br />
directly to the <strong>in</strong>dex page. But, if the <strong>in</strong>dex page is not found from the buffer pool, <strong>InnoDB</strong> <strong>in</strong>serts<br />
the record to a special <strong>in</strong>sert buffer structure. The <strong>in</strong>sert buffer is kept so small that it entirely fits <strong>in</strong><br />
the buffer pool, and <strong>in</strong>sertions can be made to it very fast.<br />
The <strong>in</strong>sert buffer is periodically merged to the secondary <strong>in</strong>dex trees <strong>in</strong> the database. Often we can<br />
merge several <strong>in</strong>sertions on the same page <strong>in</strong> of the <strong>in</strong>dex tree, and hence save disk i/o's. It has been<br />
measured that the <strong>in</strong>sert buffer can speed up <strong>in</strong>sertions to a table up to 15 times.<br />
11.3 Adaptive hash <strong>in</strong>dexes<br />
If a database fits almost entirely <strong>in</strong> ma<strong>in</strong> memory, then the fastest way to perform queries on it is to<br />
use hash <strong>in</strong>dexes. <strong>InnoDB</strong> has an automatic mechanism which monitors <strong>in</strong>dex searches made to the<br />
<strong>in</strong>dexes def<strong>in</strong>ed for a table, and if <strong>InnoDB</strong> notices that queries could benefit from build<strong>in</strong>g of a hash<br />
<strong>in</strong>dex, such an <strong>in</strong>dex is automatically built.<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 31 de 45<br />
But note that the hash <strong>in</strong>dex is always built based on an exist<strong>in</strong>g B-tree <strong>in</strong>dex on the table. <strong>InnoDB</strong><br />
can build a hash <strong>in</strong>dex on a prefix of any length of the key def<strong>in</strong>ed for the B-tree, depend<strong>in</strong>g on what<br />
search pattern <strong>InnoDB</strong> observes on the B-tree <strong>in</strong>dex. A hash <strong>in</strong>dex can be partial: it is not required<br />
that the whole B-tree <strong>in</strong>dex is cached <strong>in</strong> the buffer pool. <strong>InnoDB</strong> will build hash <strong>in</strong>dexes on demand<br />
to those pages of the <strong>in</strong>dex which are often accessed.<br />
In a sense, through the adaptive hash <strong>in</strong>dex mechanism <strong>InnoDB</strong> adapts itself to ample ma<strong>in</strong> memory,<br />
com<strong>in</strong>g closer to the architecture of ma<strong>in</strong> memory databases.<br />
11.4 Physical record structure<br />
• Each <strong>in</strong>dex record <strong>in</strong> <strong>InnoDB</strong> conta<strong>in</strong>s a header of 6 bytes. The header is used to l<strong>in</strong>k<br />
consecutive records together, and also <strong>in</strong> the row level lock<strong>in</strong>g.<br />
• Records <strong>in</strong> the clustered <strong>in</strong>dex conta<strong>in</strong> fields for all user-def<strong>in</strong>ed columns. In addition, there is<br />
a 6-byte field for the transaction id and a 7-byte field for the roll po<strong>in</strong>ter.<br />
• If the user has not def<strong>in</strong>ed a primary key for a table, then each clustered <strong>in</strong>dex record conta<strong>in</strong>s<br />
also a 6-byte row id field.<br />
• Each secondary <strong>in</strong>dex record conta<strong>in</strong>s also all the fields def<strong>in</strong>ed for the clustered <strong>in</strong>dex key.<br />
• A record conta<strong>in</strong>s also a po<strong>in</strong>ter to each field of the record. If the total length of the fields <strong>in</strong> a<br />
record is < 128 bytes, then the po<strong>in</strong>ter is 1 byte, else 2 bytes.<br />
• <strong>InnoDB</strong> stores fixed length character columns, like CHAR(10), <strong>in</strong> a fixed length format also<br />
<strong>in</strong>ternally. From VARCHAR columns <strong>InnoDB</strong> truncates trail<strong>in</strong>g spaces. Note that <strong>MySQL</strong> may<br />
<strong>in</strong>ternally convert CHAR columns to VARCHAR. See the <strong>MySQL</strong> manual about 'Silent column<br />
specification changes'.<br />
• An SQL NULL reserves 0 bytes if stored <strong>in</strong> a variable length column, but <strong>in</strong> a fixed length<br />
column it reserves the fixed length. The motivation beh<strong>in</strong>d reserv<strong>in</strong>g the fixed space also for<br />
NULLs is that then an update of a column from NULL to a non-NULL value can be done <strong>in</strong>place<br />
and does not cause fragmentation of the <strong>in</strong>dex page.<br />
12 File space management and disk i/o<br />
12.1 Disk i/o and raw devices<br />
<strong>InnoDB</strong> uses simulated asynchronous disk i/o built <strong>in</strong>to <strong>InnoDB</strong>: <strong>InnoDB</strong> creates a number of i/o<br />
threads to take care of i/o operations, such as read-ahead.<br />
Start<strong>in</strong>g from 3.23.40b <strong>InnoDB</strong> uses a novel file flush technique called 'doublewrite'. It adds safety to<br />
crash recovery after an operat<strong>in</strong>g system crash or a power outage, and improves performance on<br />
most Unix flavors by reduc<strong>in</strong>g the need for fsync operations.<br />
Doublewrite means that <strong>InnoDB</strong> before writ<strong>in</strong>g pages to a data file first writes them to a contiguous<br />
tablespace area called the doublewrite buffer. Only after the write and the flush to the doublewrite<br />
buffer has completed, <strong>InnoDB</strong> writes the pages to their proper positions <strong>in</strong> the data file. If the<br />
operat<strong>in</strong>g system crashes <strong>in</strong> the middle of a page write, <strong>InnoDB</strong> will <strong>in</strong> recovery f<strong>in</strong>d a good copy of<br />
the page from the doublewrite buffer.<br />
Start<strong>in</strong>g from 3.23.41 you can also use a raw disk partition (a raw device) as a data file. When you<br />
create a new data file you have to put the keyword newraw immediately after the data file size <strong>in</strong><br />
<strong>in</strong>nodb_data_file_path. The partition must be >= than you specify as the size. Note that 1M <strong>in</strong><br />
<strong>InnoDB</strong> is 1024 x 1024 bytes, while <strong>in</strong> disk specifications 1 MB usually means 1000 000 bytes.<br />
<strong>in</strong>nodb_data_home_dir=<br />
<strong>in</strong>nodb_data_file_path=/dev/hdd1:3Gnewraw;/dev/hdd2:2Gnewraw<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 32 de 45<br />
When you start the database aga<strong>in</strong> you MUST change the keyword to raw. Otherwise <strong>InnoDB</strong> will<br />
write over your partition! Start<strong>in</strong>g from 3.23.44, as a safety measure <strong>InnoDB</strong> prevents a user from<br />
modify<strong>in</strong>g data when any partition with newraw is specified. After you have added a new partition,<br />
shut down the database, edit my.cnf replac<strong>in</strong>g newraw with raw, and restart.<br />
<strong>in</strong>nodb_data_home_dir=<br />
<strong>in</strong>nodb_data_file_path=/dev/hdd1:3Graw;/dev/hdd2:2Graw<br />
By us<strong>in</strong>g a raw disk you can on W<strong>in</strong>dows and on some Unixes perform non-buffered i/o.<br />
There are two read-ahead heuristics <strong>in</strong> <strong>InnoDB</strong>: sequential read-ahead and random read-ahead. In<br />
sequential read-ahead <strong>InnoDB</strong> notices that the access pattern to a segment <strong>in</strong> the tablespace is<br />
sequential. Then <strong>InnoDB</strong> will post <strong>in</strong> advance a batch of reads of database pages to the i/o system. In<br />
random read-ahead <strong>InnoDB</strong> notices that some area <strong>in</strong> a tablespace seems to be <strong>in</strong> the process of<br />
be<strong>in</strong>g fully read <strong>in</strong>to the buffer pool. Then <strong>InnoDB</strong> posts the rema<strong>in</strong><strong>in</strong>g reads to the i/o system.<br />
12.2 File space management<br />
The data files you def<strong>in</strong>e <strong>in</strong> the configuration file form the tablespace of <strong>InnoDB</strong>. The files are<br />
simply catenated to form the tablespace, there is no strip<strong>in</strong>g <strong>in</strong> use. Currently you cannot directly<br />
<strong>in</strong>struct where the space is allocated for your tables, except by us<strong>in</strong>g the follow<strong>in</strong>g fact: from a newly<br />
created tablespace <strong>InnoDB</strong> will allocate space start<strong>in</strong>g from the low end.<br />
The tablespace consists of database pages whose default size is 16 kB. The pages are grouped <strong>in</strong>to<br />
extents of 64 consecutive pages. The 'files' <strong>in</strong>side a tablespace are called segments <strong>in</strong> <strong>InnoDB</strong>. The<br />
name of the rollback segment is somewhat mislead<strong>in</strong>g because it actually conta<strong>in</strong>s many segments <strong>in</strong><br />
the tablespace.<br />
For each <strong>in</strong>dex <strong>in</strong> <strong>InnoDB</strong> we allocate two segments: one is for non-leaf nodes of the B-tree, the<br />
other is for the leaf nodes. The idea here is to achieve better sequentiality for the leaf nodes, which<br />
conta<strong>in</strong> the data.<br />
When a segment grows <strong>in</strong>side the tablespace, <strong>InnoDB</strong> allocates the first 32 pages to it <strong>in</strong>dividually.<br />
After that <strong>InnoDB</strong> starts to allocate whole extents to the segment. <strong>InnoDB</strong> can add to a large segment<br />
up to 4 extents at a time to ensure good sequentiality of data.<br />
Some pages <strong>in</strong> the tablespace conta<strong>in</strong> bitmaps of other pages, and therefore a few extents <strong>in</strong> an<br />
<strong>InnoDB</strong> tablespace cannot be allocated to segments as a whole, but only as <strong>in</strong>dividual pages.<br />
When you issue a query SHOW TABLE STATUS FROM ... LIKE ... to ask for available free space <strong>in</strong><br />
the tablespace, <strong>InnoDB</strong> will report you the space which is certa<strong>in</strong>ly usable <strong>in</strong> totally free extents of<br />
the tablespace. <strong>InnoDB</strong> always reserves some extents for clean-up and other <strong>in</strong>ternal purposes; these<br />
reserved extents are not <strong>in</strong>cluded <strong>in</strong> the free space.<br />
When you delete data from a table, <strong>InnoDB</strong> will contract the correspond<strong>in</strong>g B-tree <strong>in</strong>dexes. It<br />
depends on the pattern of deletes if that frees <strong>in</strong>dividual pages or extents to the tablespace, so that the<br />
freed space is available for other users. Dropp<strong>in</strong>g a table or delet<strong>in</strong>g all rows from it is guaranteed to<br />
release the space to other users, but remember that deleted rows can be physically removed only <strong>in</strong> a<br />
purge operation after they are no longer needed <strong>in</strong> transaction rollback or consistent read.<br />
12.3 Defragment<strong>in</strong>g a table<br />
If there are random <strong>in</strong>sertions or deletions <strong>in</strong> the <strong>in</strong>dexes of a table, the <strong>in</strong>dexes may become<br />
fragmented. By fragmentation we mean that the physical order<strong>in</strong>g of the <strong>in</strong>dex pages on the disk is<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 33 de 45<br />
not close to the alphabetical order<strong>in</strong>g of the records on the pages, or that there are many unused<br />
pages <strong>in</strong> the 64-page blocks which were allocated to the <strong>in</strong>dex. It can speed up <strong>in</strong>dex scans if you<br />
periodically use mysqldump to dump the table to a text file, drop the table, and reload it from the<br />
dump. Another way to do the defragment<strong>in</strong>g is to alter the table type to MyISAM and back to <strong>InnoDB</strong><br />
aga<strong>in</strong>. Note that a MyISAM table must fit <strong>in</strong> a s<strong>in</strong>gle file on your operat<strong>in</strong>g system.<br />
If the <strong>in</strong>sertions to and <strong>in</strong>dex are always ascend<strong>in</strong>g and records are deleted only from the end, then<br />
the the file space management algorithm of <strong>InnoDB</strong> guarantees that fragmentation <strong>in</strong> the <strong>in</strong>dex will<br />
not occur.<br />
13 Error handl<strong>in</strong>g<br />
The error handl<strong>in</strong>g <strong>in</strong> <strong>InnoDB</strong> is not always the same as specified <strong>in</strong> the ANSI SQL standards.<br />
Accord<strong>in</strong>g to the ANSI standard, any error dur<strong>in</strong>g an SQL statement should cause the rollback of that<br />
statement. <strong>InnoDB</strong> sometimes rolls back only part of the statement, and <strong>in</strong> some cases the whole<br />
transaction. The follow<strong>in</strong>g list specifies the error handl<strong>in</strong>g of <strong>InnoDB</strong>.<br />
• If you run out of file space <strong>in</strong> the tablespace, you will get the <strong>MySQL</strong> 'Table is full' error<br />
and <strong>InnoDB</strong> rolls back the SQL statement.<br />
• A transaction deadlock or a timeout <strong>in</strong> a lock wait make <strong>InnoDB</strong> to roll back the whole<br />
transaction.<br />
• A duplicate key error only rolls back the <strong>in</strong>sert of that particular row, even <strong>in</strong> a statement like<br />
INSERT INTO ... SELECT .... This will probably change so that the SQL statement will be<br />
rolled back if you have not specified the IGNORE option <strong>in</strong> your statement.<br />
• A 'row too long' error rolls back the SQL statement.<br />
• Other errors are mostly detected by the <strong>MySQL</strong> layer of code, and they roll back the<br />
correspond<strong>in</strong>g SQL statement.<br />
13.1 Some error codes <strong>MySQL</strong> returns<br />
• 1005 ER_CANT_CREATE_TABLE Cannot create table. If the error message str<strong>in</strong>g refers to<br />
errno 150, then table creation fails because a foreign key constra<strong>in</strong>t is not correctly formed.<br />
• 1016 ER_CANT_OPEN_FILE Cannot f<strong>in</strong>d the <strong>InnoDB</strong> table from the <strong>InnoDB</strong> data files<br />
though the .frm file for the table exists. See the section 'Troubleshoot<strong>in</strong>g data dictionary<br />
operations' below about what to do.<br />
• 1114 ER_RECORD_FILE_FULL <strong>InnoDB</strong> has run out of free space <strong>in</strong> the tablespace. You<br />
should add a new data file.<br />
• 1205 ER_LOCK_WAIT_TIMEOUT Lock wait timeout expired. Transaction was rolled back.<br />
• 1213 ER_LOCK_DEADLOCK Transaction deadlock. You should rerun the transaction.<br />
• 1216 ER_NO_REFERENCED_ROW You are try<strong>in</strong>g to add a row but there is no parent row,<br />
and a foreign key constra<strong>in</strong>t fails. You should add the parent row first.<br />
• 1217 ER_ROW_IS_REFERENCED You are try<strong>in</strong>g to delete a parent row which has children,<br />
and a foreign key constra<strong>in</strong>t fails. You should delete the children first.<br />
13.2 Some operat<strong>in</strong>g system error numbers<br />
In Unix, to pr<strong>in</strong>t the mean<strong>in</strong>g of an operat<strong>in</strong>g system error number, use the perror program which<br />
comes with the <strong>MySQL</strong> distribution.<br />
The follow<strong>in</strong>g table provides a list of some common L<strong>in</strong>ux system error codes.<br />
• 1 EPERM Operation not permitted<br />
• 2 ENOENT No such file or directory<br />
• 3 ESRCH No such process<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 34 de 45<br />
• 4 EINTR Interrupted system call<br />
• 5 EIO I/O error<br />
• 6 ENXIO No such device or address<br />
• 7 E2BIG Arg list too long<br />
• 8 ENOEXEC Exec format error<br />
• 9 EBADF Bad file number<br />
• 10 ECHILD No child processes<br />
• 11 EAGAIN Try aga<strong>in</strong><br />
• 12 ENOMEM Out of memory<br />
• 13 EACCES Permission denied<br />
• 14 EFAULT Bad address<br />
• 15 ENOTBLK Block device required<br />
• 16 EBUSY Device or resource busy<br />
• 17 EEXIST File exists<br />
• 18 EXDEV Cross-device l<strong>in</strong>k<br />
• 19 ENODEV No such device<br />
• 20 ENOTDIR Not a directory<br />
• 21 EISDIR Is a directory<br />
• 22 EINVAL Invalid argument<br />
• 23 ENFILE File table overflow<br />
• 24 EMFILE Too many open files<br />
• 25 ENOTTY Inappropriate ioctl for device<br />
• 26 ETXTBSY Text file busy<br />
• 27 EFBIG File too large<br />
• 28 ENOSPC No space left on device<br />
• 29 ESPIPE Illegal seek<br />
• 30 EROFS Read-only file system<br />
• 31 EMLINK Too many l<strong>in</strong>ks<br />
The follow<strong>in</strong>g table provides a list of some common W<strong>in</strong>dows system error codes.<br />
• 1 Incorrect function. ERROR_INVALID_FUNCTION<br />
• 2 The system cannot f<strong>in</strong>d the file specified. ERROR_FILE_NOT_FOUND<br />
• 3 The system cannot f<strong>in</strong>d the path specified. ERROR_PATH_NOT_FOUND<br />
• 4 The system cannot open the file. ERROR_TOO_MANY_OPEN_FILES<br />
• 5 Access is denied. ERROR_ACCESS_DENIED<br />
• 6 The handle is <strong>in</strong>valid. ERROR_INVALID_HANDLE<br />
• 7 The storage control blocks were destroyed. ERROR_ARENA_TRASHED<br />
• 8 Not enough storage is available to process this command.<br />
ERROR_NOT_ENOUGH_MEMORY<br />
• 9 The storage control block address is <strong>in</strong>valid. ERROR_INVALID_BLOCK<br />
• 10 The environment is <strong>in</strong>correct. ERROR_BAD_ENVIRONMENT<br />
• 11 An attempt was made to load a program with an <strong>in</strong>correct format.<br />
ERROR_BAD_FORMAT<br />
• 12 The access code is <strong>in</strong>valid. ERROR_INVALID_ACCESS<br />
• 13 The data is <strong>in</strong>valid. ERROR_INVALID_DATA<br />
• 14 Not enough storage is available to complete this operation. ERROR_OUTOFMEMORY<br />
• 15 The system cannot f<strong>in</strong>d the drive specified. ERROR_INVALID_DRIVE<br />
• 16 The directory cannot be removed. ERROR_CURRENT_DIRECTORY<br />
• 17 The system cannot move the file to a different disk drive. ERROR_NOT_SAME_DEVICE<br />
• 18 There are no more files. ERROR_NO_MORE_FILES<br />
• 19 The media is write protected. ERROR_WRITE_PROTECT<br />
• 20 The system cannot f<strong>in</strong>d the device specified. ERROR_BAD_UNIT<br />
• 21 The device is not ready. ERROR_NOT_READY<br />
• 22 The device does not recognize the command. ERROR_BAD_COMMAND<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 35 de 45<br />
• 23 Data error (cyclic redundancy check). ERROR_CRC<br />
• 24 The program issued a command but the command length is <strong>in</strong>correct.<br />
ERROR_BAD_LENGTH<br />
• 25 The drive cannot locate a specific area or track on the disk. ERROR_SEEK<br />
• 26 The specified disk or diskette cannot be accessed. ERROR_NOT_DOS_DISK<br />
• 27 The drive cannot f<strong>in</strong>d the sector requested. ERROR_SECTOR_NOT_FOUND<br />
• 28 The pr<strong>in</strong>ter is out of paper. ERROR_OUT_OF_PAPER<br />
• 29 The system cannot write to the specified device. ERROR_WRITE_FAULT<br />
• 30 The system cannot read from the specified device. ERROR_READ_FAULT<br />
• 31 A device attached to the system is not function<strong>in</strong>g. ERROR_GEN_FAILURE<br />
• 32 The process cannot access the file because it is be<strong>in</strong>g used by another process.<br />
ERROR_SHARING_VIOLATION<br />
• 33 The process cannot access the file because another process has locked a portion of the file.<br />
ERROR_LOCK_VIOLATION<br />
• 34 The wrong diskette is <strong>in</strong> the drive. Insert %2 (Volume Serial Number: %3) <strong>in</strong>to drive %1.<br />
ERROR_WRONG_DISK<br />
• 36 Too many files opened for shar<strong>in</strong>g. ERROR_SHARING_BUFFER_EXCEEDED<br />
• 38 Reached the end of the file. ERROR_HANDLE_EOF<br />
• 39 The disk is full. ERROR_HANDLE_DISK_FULL<br />
• 112 The disk is full. ERROR_DISK_FULL<br />
• 123 The filename, directory name, or volume label syntax is <strong>in</strong>correct.<br />
ERROR_INVALID_NAME<br />
14 Restrictions on <strong>InnoDB</strong> tables<br />
• In <strong>InnoDB</strong> versions < 3.23.50 you should not use ALTER TABLE or CREATE INDEX to modify<br />
tables which have foreign key constra<strong>in</strong>ts or which are referenced by foreign key constra<strong>in</strong>ts.<br />
Use DROP TABLE and CREATE TABLE <strong>in</strong>stead.<br />
• You should not convert <strong>MySQL</strong> system tables like 'user' or 'host' to the <strong>InnoDB</strong> type. The<br />
system tables must always be of the MyISAM type.<br />
• <strong>InnoDB</strong> tables do not support fulltext search.<br />
• <strong>MySQL</strong> runs replication <strong>in</strong> the autocommit mode. Therefore consistent reads <strong>in</strong> the slave may<br />
see also partially processed transactions, and thus the read is not really consistent <strong>in</strong> the slave.<br />
This restriction is removed <strong>in</strong> 3.23.52.<br />
• <strong>InnoDB</strong> does not keep <strong>in</strong>ternally a count of rows <strong>in</strong> a table, which would actually be somewhat<br />
complicated because of multiversion<strong>in</strong>g. To answer a query SELECT COUNT(*) FROM T<br />
<strong>InnoDB</strong> has to scan one <strong>in</strong>dex of the table, which will take some time if the table is not entirely<br />
<strong>in</strong> the buffer pool. To get a fast count you have to use a counter table you create yourself, and<br />
let your application update it accord<strong>in</strong>g to the <strong>in</strong>serts and deletes it does. A way to elim<strong>in</strong>ate<br />
the bottleneck posed by lock waits for the counter is to create a whole set of counters. The<br />
application can choose one at random each time. To get the count, just sum the counters:<br />
SELECT SUM(counter_column) FROM your_counter_table.<br />
• For an auto-<strong>in</strong>crement column one must always def<strong>in</strong>e a key to the table, and that key must<br />
conta<strong>in</strong> just the auto-<strong>in</strong>crement column. <strong>InnoDB</strong> does not support AUTO_INCREMENT=... <strong>in</strong> a<br />
CREATE TABLE statement. This clause is used to set the first value for an auto-<strong>in</strong>crement<br />
column (the default first value is 1). Workaround: <strong>in</strong>sert the first row with the auto-<strong>in</strong>c column<br />
value explicitly specified. After that <strong>InnoDB</strong> starts <strong>in</strong>crement<strong>in</strong>g from that value.<br />
• SHOW TABLE STATUS does not give accurate statistics on <strong>InnoDB</strong> tables, except for the<br />
physical size reserved by the table. The row count is only a rough estimate used <strong>in</strong> SQL<br />
optimization.<br />
• In the <strong>MySQL</strong> replication load table from master does not work yet for <strong>InnoDB</strong> tables. A<br />
workaround is to alter the table to MyISAM <strong>in</strong> the master, do then the load, and after that alter<br />
back to <strong>InnoDB</strong> <strong>in</strong> the master.<br />
• If you create an <strong>in</strong>dex on a prefix of a column:<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 36 de 45<br />
CREATE TABLE T (A CHAR(20), B INT, INDEX T_IND (A(5))) TYPE = <strong>InnoDB</strong>;<br />
<strong>InnoDB</strong> will <strong>in</strong>ternally create an <strong>in</strong>dex on the whole column, not just the prefix.<br />
• INSERT DELAYED is not supported for <strong>InnoDB</strong> tables.<br />
• The <strong>MySQL</strong> LOCK TABLES operation does not know of <strong>InnoDB</strong> row level locks set <strong>in</strong> already<br />
completed SQL statements: this means that you can get a table lock on a table even if there<br />
still exist transactions of other users which have row level locks on the same table. Thus your<br />
operations on the table may have to wait if they collide with these locks of other users. Also a<br />
deadlock is possible. However, this does not endanger transaction <strong>in</strong>tegrity, because the row<br />
level locks set by <strong>InnoDB</strong> will always take care of the <strong>in</strong>tegrity. Also, a table lock prevents<br />
other transactions from acquir<strong>in</strong>g more row level locks (<strong>in</strong> a conflict<strong>in</strong>g lock mode) on the<br />
table.<br />
• You cannot have a key on a BLOB or TEXT column.<br />
• A table cannot conta<strong>in</strong> more than 1000 columns.<br />
• DELETE FROM TABLE does not regenerate the table but <strong>in</strong>stead deletes all rows, one by one,<br />
which is not that fast. In future versions of <strong>MySQL</strong> you can use TRUNCATE which is fast.<br />
• In <strong>InnoDB</strong> versions = 3.23.44.<br />
• The default database page size <strong>in</strong> <strong>InnoDB</strong> is 16 kB. By recompil<strong>in</strong>g the code one can set it<br />
from 8 kB to 64 kB. You have to update UNIV_PAGE_SIZE and UNIV_PAGE_SIZE_SHIFT <strong>in</strong><br />
univ.i. The maximun row length is slightly less than half of a database page <strong>in</strong> versions
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 37 de 45<br />
data dictionary <strong>in</strong>side the data files. If you move .frm files around, or use DROP DATABASE <strong>in</strong><br />
<strong>MySQL</strong> versions < 3.23.44, or the server crashes <strong>in</strong> the middle of a data dictionary operation, then<br />
the .frm files may end up to be out-of-sync with the <strong>InnoDB</strong> <strong>in</strong>ternal data dictionary.<br />
A symptom of an out-of-sync data dictionary is that a CREATE TABLE statement fails. Then you<br />
should look <strong>in</strong>to the error log. If it says that the table already exist <strong>in</strong>side the <strong>InnoDB</strong> <strong>in</strong>ternal data<br />
dictionary, then you have an orphaned table <strong>in</strong>side <strong>InnoDB</strong> data files, without a correspond<strong>in</strong>g .frm<br />
file.<br />
<strong>InnoDB</strong>: Error: table test/parent already exists <strong>in</strong> <strong>InnoDB</strong> <strong>in</strong>ternal<br />
<strong>InnoDB</strong>: data dictionary. Have you deleted the .frm file<br />
<strong>InnoDB</strong>: and not used DROP TABLE? Have you used DROP DATABASE<br />
<strong>InnoDB</strong>: for <strong>InnoDB</strong> tables <strong>in</strong> <strong>MySQL</strong> version
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 38 de 45<br />
• Fixed a bug: the <strong>InnoDB</strong> range estimator greatly exaggerated the size of a short <strong>in</strong>dex range if<br />
the paths to the endpo<strong>in</strong>ts of the range <strong>in</strong> the <strong>in</strong>dex tree happened to branch already <strong>in</strong> the root.<br />
This could cause unnecessary table scans <strong>in</strong> SQL queries. The fix will also be backported to<br />
3.23.54.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-<strong>3.23.53</strong>, October 14, 2002<br />
• We aga<strong>in</strong> use unbuffered disk i/o to data files <strong>in</strong> W<strong>in</strong>dows. W<strong>in</strong> XP and W<strong>in</strong> 2000 read<br />
performance seems to be very poor with normal i/o.<br />
• Tuned range estimator so that <strong>in</strong>dex range scans are preferred over full <strong>in</strong>dex scans.<br />
• Allow dropp<strong>in</strong>g and creat<strong>in</strong>g a table even if <strong>in</strong>nodb_force_recovery is set. One can use this to<br />
drop a table which would cause a crash <strong>in</strong> rollback or purge, or if a failed table import causes a<br />
runaway rollback <strong>in</strong> recovery.<br />
• Fixed a bug present <strong>in</strong> 3.23.52, 4.0.3, <strong>4.0.4</strong>: <strong>InnoDB</strong> startup could take very long or even crash<br />
on some W<strong>in</strong> 95/98/ME computers.<br />
• Fixed a bug: fast shutdown (which is the default) sometimes was slowed down by purge and<br />
<strong>in</strong>sert buffer merge.<br />
• Fixed a bug: do<strong>in</strong>g a big SELECT from a table where no rows were visible <strong>in</strong> a consistent read<br />
could cause a very long (> 600 seconds) semaphore wait <strong>in</strong> btr0cur.c l<strong>in</strong>e 310.<br />
• Fixed a bug: the AUTO-INC lock was held to the end of the transaction if it was granted after<br />
a lock wait. This could cause unnecessary deadlocks.<br />
• Fixed a bug: if you created a temporary table <strong>in</strong>side LOCK TABLES, and used that temporary<br />
table, that caused an assertion failure <strong>in</strong> ha_<strong>in</strong>nobase.cc.<br />
• Fixed a bug: if SHOW INNODB STATUS, <strong>in</strong>nodb_monitor, or <strong>in</strong>nodb_lock_monitor had to<br />
pr<strong>in</strong>t several hundred transactions <strong>in</strong> one report, and the output became truncated, <strong>InnoDB</strong><br />
would hang, pr<strong>in</strong>t<strong>in</strong>g to the error log many waits for a mutex created at srv0srv.c, l<strong>in</strong>e 1621.<br />
• Fixed a bug: SHOW INNODB STATUS on Unix always reported average file read size as 0<br />
bytes.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-<strong>4.0.4</strong>, October 2, 2002<br />
• We aga<strong>in</strong> use unbuffered disk i/o to data files <strong>in</strong> W<strong>in</strong>dows. W<strong>in</strong> XP and W<strong>in</strong> 2000 read<br />
performance seems to be very poor with normal i/o.<br />
• Increased the max key length of <strong>InnoDB</strong> tables from 500 to 1024 bytes.<br />
• Increased the table comment field <strong>in</strong> SHOW TABLE STATUS so that up to 16000 characters<br />
of foreign key def<strong>in</strong>itions can be pr<strong>in</strong>ted there.<br />
• The auto-<strong>in</strong>crement counter is no longer <strong>in</strong>cremented if an <strong>in</strong>sert of a row immediately fails <strong>in</strong><br />
an error.<br />
• Allow dropp<strong>in</strong>g and creat<strong>in</strong>g a table even if <strong>in</strong>nodb_force_recovery is set. One can use this to<br />
drop a table which would cause a crash <strong>in</strong> rollback or purge, or if a failed table import causes a<br />
runaway rollback <strong>in</strong> recovery.<br />
• Fixed a bug: Us<strong>in</strong>g ORDER BY primarykey DESC <strong>in</strong> 4.0.3 causes an assertion failure <strong>in</strong><br />
btr0pcur.c, l<strong>in</strong>e 203.<br />
• Fixed a bug: fast shutdown (which is the default) sometimes was slowed down by purge and<br />
<strong>in</strong>sert buffer merge.<br />
• Fixed a bug: do<strong>in</strong>g a big SELECT from a table where no rows were visible <strong>in</strong> a consistent read<br />
could cause a very long (> 600 seconds) semaphore wait <strong>in</strong> btr0cur.c l<strong>in</strong>e 310.<br />
• Fixed a bug: if the <strong>MySQL</strong> query cache was used, it did not get <strong>in</strong>validated by a modification<br />
done by ON DELETE CASCADE or ...SET NULL.<br />
• Fixed a bug: if you created a temporary table <strong>in</strong>side LOCK TABLES, and used that temporary<br />
table, that caused an assertion failure <strong>in</strong> ha_<strong>in</strong>nodb.cc.<br />
• Fixed a bug: if you set <strong>in</strong>nodb_flush_log_at_trx_commit to 1, SHOW VARIABLES would<br />
show its value as 16 million.<br />
• An outstand<strong>in</strong>g bug: queries of type "WHERE <strong>in</strong>dexedcolumn LIKE 'abc%' ORDER BY<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 39 de 45<br />
<strong>in</strong>dexedcolumn DESC" may return only rows where <strong>in</strong>dexedcolumn='abc'. Will be fixed <strong>in</strong><br />
4.0.5.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-4.0.3, August 28, 2002<br />
• Removed unnecessary deadlocks when <strong>in</strong>serts have to wait for a lock<strong>in</strong>g read, update, or delete<br />
to release its next-key lock.<br />
• The <strong>MySQL</strong> HANDLER SQL commands now work also for <strong>InnoDB</strong> type tables. <strong>InnoDB</strong><br />
does the HANDLER reads always as consistent reads. HANDLER is a direct access path to<br />
read <strong>in</strong>dividual <strong>in</strong>dexes of tables. In some cases HANDLER can be used as a substitute of<br />
server-side cursors.<br />
• Fixed a bug <strong>in</strong> 4.0.2: even a simple <strong>in</strong>sert could crash the AIX version.<br />
• Fixed a bug: if you used <strong>in</strong> a table name characters whose code is > 127, <strong>in</strong> DROP TABLE<br />
<strong>InnoDB</strong> could assert on l<strong>in</strong>e 155 of pars0sym.c.<br />
• Compilation from source now provides a work<strong>in</strong>g version both on HP-UX-11 and HP-UX-<br />
10.20. The source of 4.0.2 worked only on 11, and the source of 3.23.52 only on 10.20.<br />
• Fixed a bug: if compiled on 64-bit Solaris, <strong>InnoDB</strong> produced a bus error at startup.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-3.23.52, August 16, 2002<br />
• The feature set of 3.23 will be frozen from this version on. New features will go the the 4.0<br />
branch, and only bug fixes will be made to the 3.23 branch.<br />
• Many CPU-bound jo<strong>in</strong> queries now run faster. On W<strong>in</strong>dows also many other CPU-bound<br />
queries run faster.<br />
• A new SQL command SHOW INNODB STATUS returns the output of the <strong>InnoDB</strong> Monitor<br />
to the client. The <strong>InnoDB</strong> Monitor now pr<strong>in</strong>ts detailed <strong>in</strong>fo on the latest detected deadlock.<br />
• <strong>InnoDB</strong> made the SQL query optimizer to avoid too much <strong>in</strong>dex-only range scans and choose<br />
full table scans <strong>in</strong>stead. This is now fixed.<br />
• "BEGIN" and "COMMIT" are now added <strong>in</strong> the b<strong>in</strong>log around transactions. The <strong>MySQL</strong><br />
replication now respects transaction borders: a user will no longer see half transactions <strong>in</strong><br />
replication slaves.<br />
• A replication slave now pr<strong>in</strong>ts <strong>in</strong> crash recovery the last master b<strong>in</strong>log position it was able to<br />
recover to.<br />
• A new sett<strong>in</strong>g <strong>in</strong>nodb_flush_log_at_trx_commit=2 makes <strong>InnoDB</strong> to write the log to the<br />
operat<strong>in</strong>g system file cache at each commit. This is almost as fast as the sett<strong>in</strong>g<br />
<strong>in</strong>nodb_flush_log_at_trx_commit=0, and the sett<strong>in</strong>g 2 also has the nice feature that <strong>in</strong> a crash<br />
where the operat<strong>in</strong>g system does not crash, no committed transaction is lost. If the operat<strong>in</strong>g<br />
system crashes or there is a power outage, then the sett<strong>in</strong>g 2 is no safer than the sett<strong>in</strong>g 0.<br />
• Added checksum fields to log blocks.<br />
• SET FOREIGN_KEY_CHECKS=0 helps <strong>in</strong> import<strong>in</strong>g tables <strong>in</strong> an arbitrary order which does<br />
not respect the foreign key rules.<br />
• SET UNIQUE_CHECKS=0 speeds up table imports <strong>in</strong>to <strong>InnoDB</strong> if you have UNIQUE<br />
constra<strong>in</strong>ts on secondary <strong>in</strong>dexes.<br />
• SHOW TABLE STATUS now lists also possible ON DELETE CASCADE or ON DELETE<br />
SET NULL <strong>in</strong> the comment field of the table.<br />
• When CHECK TABLE is run on any <strong>InnoDB</strong> type table, it now checks also the adaptive hash<br />
<strong>in</strong>dex for all tables.<br />
• If you def<strong>in</strong>ed ON DELETE CASCADE or SET NULL and updated the referenced key <strong>in</strong> the<br />
parent row, <strong>InnoDB</strong> deleted or updated the child row. This is now changed to conform to SQL-<br />
92: you get the error 'Cannot delete parent row'.<br />
• Improved the auto-<strong>in</strong>crement algorithm: now the first <strong>in</strong>sert or SHOW TABLE STATUS<br />
<strong>in</strong>itializes the auto-<strong>in</strong>c counter for the table. This removes almost all surpris<strong>in</strong>g deadlocks<br />
caused by SHOW TABLE STATUS.<br />
• Aligned some buffers used <strong>in</strong> read<strong>in</strong>g and writ<strong>in</strong>g to data files. This allows us<strong>in</strong>g unbuffered<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 40 de 45<br />
raw devices as data files <strong>in</strong> L<strong>in</strong>ux.<br />
• Fixed a bug: If you updated the primary key of a table so that only the case of characters<br />
changed, that could cause assertion failures, mostly <strong>in</strong> page0page.ic l<strong>in</strong>e 515.<br />
• Fixed a bug: If you delete or update a row referenced <strong>in</strong> a foreign key constra<strong>in</strong>t and the<br />
foreign key check has to wait for a lock, then the check may report an erroneous result. This<br />
affects also the ON DELETE... operation.<br />
• Fixed a bug: A deadlock or a lock wait timeout error <strong>in</strong> <strong>InnoDB</strong> causes <strong>InnoDB</strong> to roll back<br />
the whole transaction, but <strong>MySQL</strong> could still write the earlier SQL statements to the b<strong>in</strong>log,<br />
even though <strong>InnoDB</strong> rolled them back. This could, for example, cause replicated databases to<br />
get out-of-sync.<br />
• Fixed a bug: If the database happened to crash <strong>in</strong> the middle of a commit, then the recovery<br />
might leak tablespace pages.<br />
• Fixed a bug: If you specified a non-lat<strong>in</strong>1 character set <strong>in</strong> my.cnf, then, <strong>in</strong> contrary to what is<br />
stated <strong>in</strong> the manual, <strong>in</strong> a foreign key constra<strong>in</strong>t a str<strong>in</strong>g type column had to have the same<br />
length specification <strong>in</strong> the referenc<strong>in</strong>g table and the referenced table.<br />
• Fixed a bug: DROP TABLE or DROP DATABASE could fail if there simultaneously was a<br />
CREATE TABLE runn<strong>in</strong>g.<br />
• Fixed a bug: If you configured the buffer pool bigger than 2 GB <strong>in</strong> a 32-bit computer, <strong>InnoDB</strong><br />
would assert <strong>in</strong> buf0buf.ic l<strong>in</strong>e 214.<br />
• Fixed a bug: on 64-bit computers updat<strong>in</strong>g rows which conta<strong>in</strong>ed the SQL NULL <strong>in</strong> some<br />
column could cause the undo log and the ord<strong>in</strong>ary log to become corrupt.<br />
• Fixed a bug: <strong>in</strong>nodb_log_monitor caused a hang if it suppressed lock pr<strong>in</strong>ts for a page.<br />
• Fixed a bug: <strong>in</strong> the HP-UX-10.20 version mutexes would leak and cause race conditions and<br />
crashes <strong>in</strong> any part of <strong>InnoDB</strong> code.<br />
• Fixed a bug: if you ran <strong>in</strong> the AUTOCOMMIT mode, executed a SELECT, and immediately<br />
after that a RENAME TABLE, then RENAME would fail and <strong>MySQL</strong> would compla<strong>in</strong> about<br />
error 1192.<br />
• Fixed a bug: if compiled on 64-bit Solaris, <strong>InnoDB</strong> produced a bus error at startup.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-4.0.2, July 10, 2002<br />
• <strong>InnoDB</strong> is essentially the same as <strong>InnoDB</strong>-3.23.51.<br />
• If no <strong>in</strong>nodb_data_file_path is specified, <strong>InnoDB</strong> at the database creation now creates a 10 MB<br />
auto-extend<strong>in</strong>g data file ibdata1 to the datadir of <strong>MySQL</strong>. In 4.0.1 the file was 64 MB and not<br />
auto-extend<strong>in</strong>g.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-3.23.51, June 12, 2002<br />
• Fixed a bug: a jo<strong>in</strong> could result <strong>in</strong> a seg fault <strong>in</strong> copy<strong>in</strong>g of a BLOB or TEXT column if some<br />
of the BLOB or TEXT columns <strong>in</strong> the table conta<strong>in</strong>ed SQL NULL values.<br />
• Fixed a bug: if you added self-referential foreign key constra<strong>in</strong>ts with ON DELETE<br />
CASCADE to tables and a row deletion caused <strong>InnoDB</strong> to attempt the deletion of the same<br />
row twice because of a cascad<strong>in</strong>g delete, then you got an assertion failure.<br />
• Fixed a bug: if you use <strong>MySQL</strong> 'user level locks' and close a connection, then <strong>InnoDB</strong> may<br />
assert <strong>in</strong> ha_<strong>in</strong>nobase.cc, l<strong>in</strong>e 302.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-3.23.50, April 23, 2002<br />
• <strong>InnoDB</strong> now supports an auto-extend<strong>in</strong>g last data file. You do not need to preallocate the<br />
whole data file at the database startup.<br />
• Made several changes to facilitate the use of the <strong>InnoDB</strong> Hot Backup tool. It is a separate nonfree<br />
tool you can use to take onl<strong>in</strong>e backups of your database without shutt<strong>in</strong>g down the server<br />
or sett<strong>in</strong>g any locks.<br />
• If you want to run the <strong>InnoDB</strong> Hot Backup tool on an auto-extend<strong>in</strong>g data file you have to<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 41 de 45<br />
upgrade it to version ibbackup-0.35.<br />
• The log scan phase <strong>in</strong> crash recovery will now run much faster.<br />
• Start<strong>in</strong>g from this server version, the hot backup tool truncates unused ends <strong>in</strong> the backup<br />
<strong>InnoDB</strong> data files.<br />
• To allow the hot backup tool to work, on W<strong>in</strong>dows we no longer use unbuffered i/o or native<br />
async i/o; <strong>in</strong>stead we use the same simulated async i/o as on Unix.<br />
• You can now def<strong>in</strong>e the ON DELETE CASCADE or ON DELETE SET NULL clause on<br />
foreign keys.<br />
• FOREIGN KEY constra<strong>in</strong>ts now survive ALTER TABLE and CREATE INDEX.<br />
• We suppress the FOREIGN KEY check if any of the column values <strong>in</strong> the foreign key or<br />
referenced key to be checked is the SQL NULL. This is compatible with Oracle, for example.<br />
• SHOW CREATE TABLE now lists also foreign key constra<strong>in</strong>ts. Also mysqldump no longer<br />
forgets about foreign keys <strong>in</strong> table def<strong>in</strong>itions.<br />
• You can now add a new foreign key constra<strong>in</strong>t with ALTER TABLE ... ADD CONSTRAINT<br />
FOREIGN KEY (...) REFERENCES ... (...).<br />
• FOREIGN KEY def<strong>in</strong>itions now allow backquotes around table and column names.<br />
• <strong>MySQL</strong> command SET TRANSACTION ISOLATION LEVEL ... has now the follow<strong>in</strong>g<br />
effect on <strong>InnoDB</strong> tables: if a transaction is def<strong>in</strong>ed as SERIALIZABLE then <strong>InnoDB</strong><br />
conceptually adds LOCK IN SHARE MODE to all consistent reads. If a transaction is def<strong>in</strong>ed<br />
to have any other isolation level, then <strong>InnoDB</strong> obeys its default lock<strong>in</strong>g strategy which is<br />
REPEATABLE READ.<br />
• SHOW TABLE STATUS no longer sets an x-lock at the end of an auto-<strong>in</strong>crement <strong>in</strong>dex if the<br />
auto-<strong>in</strong>crement counter has already been <strong>in</strong>itialized. This removes <strong>in</strong> almost all cases the<br />
surpris<strong>in</strong>g deadlocks caused by SHOW TABLE STATUS.<br />
• Fixed a bug: <strong>in</strong> a CREATE TABLE statement the str<strong>in</strong>g 'foreign' followed by a non-space<br />
character confused the FOREIGN KEY parser and caused table creation to fail with errno 150.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-3.23.49, February 17, 2002<br />
• Fixed a bug: if you called DROP DATABASE for a database on which there simultaneously<br />
were runn<strong>in</strong>g queries, the <strong>MySQL</strong> server could crash or hang. Crashes fixed, but a full fix has<br />
to wait some changes <strong>in</strong> the <strong>MySQL</strong> layer of code.<br />
• Fixed a bug: on W<strong>in</strong>dows one had to put the database name <strong>in</strong> lower case for DROP<br />
DATABASE to work. Fixed <strong>in</strong> 3.23.49: case no longer matters on W<strong>in</strong>dows. On Unix the<br />
database name rema<strong>in</strong>s case-sensitive.<br />
• Fixed a bug: if one def<strong>in</strong>ed a non-lat<strong>in</strong>1 character set as the default character set, then<br />
def<strong>in</strong>ition of foreign key constra<strong>in</strong>ts could fail <strong>in</strong> an assertion failure <strong>in</strong> dict0crea.c, report<strong>in</strong>g<br />
an <strong>in</strong>ternal error 17.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-3.23.48, February 9, 2002<br />
• Tuned the SQL optimizer to favor more often <strong>in</strong>dex searches over table scans.<br />
• Fixed a performance problem when several large SELECT queries are run concurrently on a<br />
multiprocessor L<strong>in</strong>ux computer. Large CPU-bound SELECT queries will now also generally<br />
run faster on all platforms.<br />
• If <strong>MySQL</strong> b<strong>in</strong>logg<strong>in</strong>g is used, <strong>InnoDB</strong> now pr<strong>in</strong>ts after crash recovery the latest <strong>MySQL</strong><br />
b<strong>in</strong>log file name and the position <strong>in</strong> that file (= byte offset) <strong>InnoDB</strong> was able to recover to.<br />
This is useful, for example, when resynchroniz<strong>in</strong>g a master and a slave database <strong>in</strong> replication.<br />
• Added better error messages to help <strong>in</strong> <strong>in</strong>stallation problems.<br />
• One can now recover also <strong>MySQL</strong> temporary tables which have become orphaned <strong>in</strong>side the<br />
<strong>InnoDB</strong> tablespace.<br />
• <strong>InnoDB</strong> now prevents a FOREIGN KEY declaration where the signedness is not the same <strong>in</strong><br />
the referenc<strong>in</strong>g and referenced <strong>in</strong>teger columns.<br />
• Fixed a bug: call<strong>in</strong>g SHOW CREATE TABLE or SHOW TABLE STATUS could cause<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 42 de 45<br />
memory corruption and make mysqld to crash. Especially at risk was mysqldump, because it<br />
calls frequently SHOW CREATE TABLE.<br />
• Fixed a bug: if on Unix you did an ALTER TABLE to an <strong>InnoDB</strong> table and simultaneously<br />
did queries to it, mysqld could crash with an assertion failure <strong>in</strong> row0row.c, l<strong>in</strong>e 474.<br />
• Fixed a bug: if <strong>in</strong>serts to several tables conta<strong>in</strong><strong>in</strong>g an auto-<strong>in</strong>c column were wrapped <strong>in</strong>side one<br />
LOCK TABLES, <strong>InnoDB</strong> asserted <strong>in</strong> lock0lock.c.<br />
• In 3.23.47 we allowed several NULLS <strong>in</strong> a UNIQUE secondary <strong>in</strong>dex. But CHECK TABLE<br />
was not relaxed: it reports the table as corrupt. CHECK TABLE no longer compla<strong>in</strong>s <strong>in</strong> this<br />
situation.<br />
• Fixed a bug: on Sparc and other high-endian processors SHOW VARIABLES showed<br />
<strong>in</strong>nodb_flush_log_at_trx_commit and other boolean-valued startup parameters always OFF<br />
even if they were switched on.<br />
• Fixed a bug: if you ran mysqld-max-nt as a service on W<strong>in</strong>dows NT/2000, the service<br />
shutdown did not always wait long enough for the <strong>InnoDB</strong> shutdown to f<strong>in</strong>ish.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-3.23.47, December 28, 2001<br />
• Recovery happens now faster, especially <strong>in</strong> a lightly loaded system, because background<br />
checkpo<strong>in</strong>t<strong>in</strong>g has been made more frequent.<br />
• <strong>InnoDB</strong> allows now several similar key values <strong>in</strong> a UNIQUE secondary <strong>in</strong>dex if those values<br />
conta<strong>in</strong> SQL NULLs. Thus the convention is now the same as <strong>in</strong> MyISAM tables.<br />
• <strong>InnoDB</strong> gives a better row count estimate for a table which conta<strong>in</strong>s BLOBs.<br />
• In a FOREIGN KEY constra<strong>in</strong>t <strong>InnoDB</strong> is now case-<strong>in</strong>sensitive to column names, and <strong>in</strong><br />
W<strong>in</strong>dows also to table names.<br />
• <strong>InnoDB</strong> allows a FOREIGN KEY column of CHAR type to refer to a column of VARCHAR<br />
type, and vice versa. <strong>MySQL</strong> silently changes the type of some columns between CHAR and<br />
VARCHAR, and these silent changes do not h<strong>in</strong>der FOREIGN KEY declaration any more.<br />
• Recovery has been made more resilient to corruption of log files.<br />
• Unnecessary statistics calculation has been removed from queries which generate a temporary<br />
table. Some ORDER BY and DISTINCT queries will now run much faster.<br />
• <strong>MySQL</strong> now knows that the table scan of an <strong>InnoDB</strong> table is done through the primary key.<br />
This will save a sort <strong>in</strong> some ORDER BY queries.<br />
• The maximum key length of <strong>InnoDB</strong> tables is aga<strong>in</strong> restricted to 500 bytes. The <strong>MySQL</strong><br />
<strong>in</strong>terpreter is not able to handle longer keys.<br />
• The default value of <strong>in</strong>nodb_lock_wait_timeout was changed from <strong>in</strong>f<strong>in</strong>ite to 50 seconds, the<br />
default value of <strong>in</strong>nodb_file_io_threads from 9 to 4.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-4.0.1, December 23, 2001<br />
• <strong>InnoDB</strong> is the same as <strong>in</strong> 3.23.47.<br />
• In 4.0.0 the <strong>MySQL</strong> <strong>in</strong>terpreter did not know the syntax LOCK IN SHARE MODE. This has<br />
been fixed.<br />
• In 4.0.0 multi-table delete did not work for transactional tables. This has been fixed.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-3.23.46, November 30, 2001<br />
• This is the same as 3.23.45.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-3.23.45, November 23, 2001<br />
• This is a bugfix release.<br />
• In versions 3.23.42-.44 when creat<strong>in</strong>g a table on W<strong>in</strong>dows you have to use lower case letters <strong>in</strong><br />
the database name to be able to access the table. Fixed <strong>in</strong> 3.23.45.<br />
• <strong>InnoDB</strong> now flushes stdout and stderr every 10 seconds: if these are redirected to files, the file<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 43 de 45<br />
contents can be better viewed with an editor.<br />
• Fixed an assertion failure <strong>in</strong> .44, <strong>in</strong> trx0trx.c, l<strong>in</strong>e 178 when you drop a table which has<br />
the .frm file but does not exist <strong>in</strong>side <strong>InnoDB</strong>.<br />
• Fixed a bug <strong>in</strong> the <strong>in</strong>sert buffer. The <strong>in</strong>sert buffer tree could get <strong>in</strong>to an <strong>in</strong>consistent state,<br />
caus<strong>in</strong>g a crash, and also crash<strong>in</strong>g the recovery. This bug could appear especially <strong>in</strong> large table<br />
imports or alterations.<br />
• Fixed a bug <strong>in</strong> recovery: <strong>InnoDB</strong> could go <strong>in</strong>to an <strong>in</strong>f<strong>in</strong>ite loop constantly pr<strong>in</strong>t<strong>in</strong>g a warn<strong>in</strong>g<br />
message that it cannot f<strong>in</strong>d free blocks from the buffer pool.<br />
• Fixed a bug: when you created a temporary table of the <strong>InnoDB</strong> type, and then used ALTER<br />
TABLE to it, the <strong>MySQL</strong> server could crash.<br />
• Prevented creation of <strong>MySQL</strong> system tables 'mysql.user', 'mysql.host', or 'mysql.db', <strong>in</strong> the<br />
<strong>InnoDB</strong> type.<br />
• Fixed a bug which can cause an assertion failure <strong>in</strong> 3.23.44 <strong>in</strong> srv0srv.c, l<strong>in</strong>e 1728.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-3.23.44, November 2, 2001<br />
• You can def<strong>in</strong>e foreign key constra<strong>in</strong>ts on <strong>InnoDB</strong> tables. An example: FOREIGN KEY (col1)<br />
REFERENCES table2(col2).<br />
• You can create > 4 GB data files <strong>in</strong> those file systems that allow it.<br />
• Improved <strong>InnoDB</strong> monitors, <strong>in</strong>clud<strong>in</strong>g a new <strong>in</strong>nodb_table_monitor which allows you to pr<strong>in</strong>t<br />
the contents of the <strong>InnoDB</strong> <strong>in</strong>ternal data dictionary.<br />
• DROP DATABASE will now work also for <strong>InnoDB</strong> tables.<br />
• Accent characters <strong>in</strong> the default character set lat<strong>in</strong>1 will be ordered accord<strong>in</strong>g to the <strong>MySQL</strong><br />
order<strong>in</strong>g.<br />
NOTE: if you are us<strong>in</strong>g lat<strong>in</strong>1 and have <strong>in</strong>serted characters whose code is > 127 to an <strong>in</strong>dexed<br />
CHAR column, you should run CHECK TABLE on your table when you upgrade to 3.23.43,<br />
and drop and reimport the table if CHECK TABLE reports an error!<br />
• <strong>InnoDB</strong> will calculate better table card<strong>in</strong>ality estimates.<br />
• Change <strong>in</strong> deadlock resolution: <strong>in</strong> .43 a deadlock rolls back only the SQL statement, <strong>in</strong> .44 it<br />
will roll back the whole transaction.<br />
• Deadlock, lock wait timeout, and foreign key constra<strong>in</strong>t violations (no parent row, child rows<br />
exist) now return native <strong>MySQL</strong> error codes 1213, 1205, 1216, 1217, respectively.<br />
• A new my.cnf parameter <strong>in</strong>nodb_thread_concurrency helps <strong>in</strong> performance tun<strong>in</strong>g <strong>in</strong> high<br />
concurrency environments.<br />
• A new my.cnf option <strong>in</strong>nodb_force_recovery will help you <strong>in</strong> dump<strong>in</strong>g tables from a corrupted<br />
database.<br />
• A new my.cnf option <strong>in</strong>nodb_fast_shutdown will speed up shutdown. Normally <strong>InnoDB</strong> does<br />
a full purge and an <strong>in</strong>sert buffer merge at shutdown.<br />
• Raised maximum key length to 7000 bytes from a previous limit of 500 bytes.<br />
• Fixed a bug <strong>in</strong> replication of auto-<strong>in</strong>c columns with multil<strong>in</strong>e <strong>in</strong>serts.<br />
• Fixed a bug when the case of letters changes <strong>in</strong> an update of an <strong>in</strong>dexed secondary column.<br />
• Fixed a hang when there are > 24 data files.<br />
• Fixed a crash when MAX(col) is selected from an empty table, and col is a not the first column<br />
<strong>in</strong> a multi-column <strong>in</strong>dex.<br />
• Fixed a bug <strong>in</strong> purge which could cause crashes.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-3.23.43, October 4, 2001<br />
• This is essentially the same as <strong>InnoDB</strong>-3.23.42.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-3.23.42, September 9, 2001<br />
• Fixed a bug which corrupted the table if the primary key of a > 8000-byte row was updated.<br />
• There are now 3 types of <strong>InnoDB</strong> Monitors: <strong>in</strong>nodb_monitor, <strong>in</strong>nodb_lock_monitor, and<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 44 de 45<br />
<strong>in</strong>nodb_tablespace_monitor. <strong>in</strong>nodb_monitor now pr<strong>in</strong>ts also buffer pool hit rate and the total<br />
number of rows <strong>in</strong>serted, updated, deleted, read.<br />
• Fixed a bug <strong>in</strong> RENAME TABLE.<br />
• Fixed a bug <strong>in</strong> replication with an auto-<strong>in</strong>crement column.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-3.23.41, August 13, 2001:<br />
• Support for < 4 GB rows. The previous limit was 8000 bytes.<br />
• Use the doublewrite file flush method.<br />
• Raw disk partitions supported as data files.<br />
• <strong>InnoDB</strong> Monitor.<br />
• Several hang bugs fixed and an ORDER BY bug ('Sort aborted') fixed.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-3.23.40, July 16, 2001:<br />
• Only a few rare bugs fixed.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-3.23.39, June 13, 2001:<br />
• CHECK TABLE now works for <strong>InnoDB</strong> tables.<br />
• A new my.cnf parameter <strong>in</strong>nodb_unix_file_flush_method <strong>in</strong>troduced. It can be used to tune<br />
disk write performance.<br />
• An auto-<strong>in</strong>crement column now gets new values past the transaction mechanism. This saves<br />
CPU time and elim<strong>in</strong>ates transaction deadlocks <strong>in</strong> new value assignment.<br />
• Several bug fixes, most notably the rollback bug <strong>in</strong> 3.23.38.<br />
<strong>MySQL</strong>/<strong>InnoDB</strong>-3.23.38, May 12, 2001:<br />
• The new syntax SELECT ... LOCK IN SHARE MODE is <strong>in</strong>troduced.<br />
• <strong>InnoDB</strong> now calls fsync after every disk write and calculates a checksum for every database<br />
page it writes or reads, which will reveal disk defects.<br />
• Several bug fixes.<br />
17 <strong>InnoDB</strong> contact <strong>in</strong>formation<br />
Contact <strong>in</strong>formation of Innobase Oy, producer of the <strong>InnoDB</strong> eng<strong>in</strong>e:<br />
Website: www.<strong>in</strong>nodb.com<br />
Heikki.Tuuri@<strong>in</strong>nodb.com<br />
phone: 358-9-6969 3250 (office) 358-40-5617367 (mobile)<br />
Innobase Oy Inc.<br />
World Trade Center Hels<strong>in</strong>ki<br />
Aleksanter<strong>in</strong>katu 17<br />
P.O.Box 800<br />
00101 Hels<strong>in</strong>ki<br />
F<strong>in</strong>land<br />
18 The GNU GPL License Version 2<br />
The GPL license text.<br />
19 Known bugs and their fixes <strong>in</strong> old versions of <strong>InnoDB</strong><br />
See a separate web page.<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002
<strong>InnoDB</strong> <strong>Eng<strong>in</strong>e</strong> <strong>in</strong> <strong>MySQL</strong>: Reference Manual<br />
Pág<strong>in</strong>a 45 de 45<br />
20 The TODO list of new features to <strong>InnoDB</strong><br />
See a separate web page.<br />
21 Some books and articles on <strong>MySQL</strong>/<strong>InnoDB</strong><br />
See a separate web page.<br />
http://www.<strong>in</strong>nodb.com/ibman.html<br />
17/10/2002