25.11.2014 Views

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

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!