15.2.1 . InnoDB概述
InnoDB给MySQL提供 了具有提交,回滚和崩溃恢复能力的事务安全(ACID兼容)存储引擎。InnoDB锁定在行级并且也在SELECT语句提供一个Oracle风格一致的非锁定读。这些特色增加 了多用户部署和性能。没有在InnoDB中扩大锁定的需要,因为在InnoDB中行级锁定适合非常小的空间。InnoDB也支持FOREIGN KEY强制。在SQL查询中,你可以自由地将InnoDB类型的表与其它MySQL的表的类型混合起来,甚至在同一个查询中也可以混合。
InnoDB是为处理巨大数据量时的最大性能设计。它的CPU效率可能是任何其它基于磁盘的关系数据库引擎所不能匹敌的。
InnoDB存储引擎被完全与MySQL服务器整合,InnoDB存储引擎为在主内存中缓存数据和索引而维持它自己的缓冲池。InnoDB存储它的表&索引在一个表空间中,表空间可以包含数个文件(或原始磁盘分区)。这与MyISAM表不同,比如在MyISAM表中每个表被存在分离的文件中。InnoDB 表可以是任何尺寸,即使在文件尺寸被限制为2GB的操作系统上。
InnoDB默认地被包含在MySQL二进制分发中。Windows Essentials installer使InnoDB成为Windows上MySQL的 默认表。
InnoDB被用来在众多需要高性能的大型数据库站点上产生。著名的Internet新闻站点Slashdot.org运行在InnoDB上。Mytrix, Inc.在InnoDB上存储超过1TB的数据,还有一些其它站点在InnoDB上处理平均每秒800次插入/更新的负荷。
InnoDB在和MySQL一样在同一个GNU GPL证书,第2版(1991年6月版)下发行。更多有关MySQL证书的信息,请参阅http://www.mysql.com/company/legal/licensing/。
关于InnoDB存储引擎,在http://forums.mysql.com/list.php?22有一个详细的论坛。
InnoDB引擎的厂家的联系信息,Innobase Oy的联系方式如下:
Web site: http://www.innodb.com/
Email: <[email protected]>
Phone: +358-9-6969 3250 (office)
+358-40-5617367 (mobile)
Innobase Oy Inc.
World Trade Center Helsinki
Aleksanterinkatu 17
P.O.Box 800
00101 Helsinki
Finland
InnoDB存储引擎是默认地被允许的。如果你不想用InnoDB表,你可以添加skip-innodb选项到MySQL选项文件。
被InnoDB存储引擎管理的两个重要的基于磁盘的资源是InnoDB表空间数据文件和它的日志文件。
如果你指定无InnoDB配置选项,MySQL将在MySQL数据目录下创建一个名为ibdata1的10MB大小的自动扩展数据文件,以及两个名为ib_logfile0和ib_logfile 1的5MB大小的日志文件。
注释:InnoDB给MySQL提供具有提交, 回滚和崩溃恢复能力的事务安全(ACID兼容)存储引擎。如果拟运行的操作系统和硬件不能如广告说的那样运行,InnoDB就不能实现如上能力。许多操作系统或磁盘子系统可能为改善性能而延迟或记录写操作。在一些操作系统上,就是系统调用(fsync()) 也要等着,直到所有未写入已被刷新文件的数据在被刷新到稳定内存之前可以确实返回了。因为这个,操作系统崩溃或掉电可能损坏当前提交的数据,或者在最坏的 情况,因为写操作已被记录了,甚至破坏了数据库。如果数据完整性对你很重要,你应该在用任何程序于生产中之前做一些“pull-the-plug”测试。Mac OS X 10.3 及以后版本,InnoDB使用一个特别的fcntl()文件 刷新方法。在Linux下,建议禁止回写缓存。
在ATAPI硬盘上,一个类似hdparm -W0 /dev/hda命令可能起作用。小心某些驱动器或者磁盘控制器可能不能禁止回写缓存。
注释:要获得好的性能,你应该如下面例子所讨论那样,明确提供InnoDB参数。自然地,你应该编辑设置来适合你的硬件和要求。
要建立InnoDB表空间文件,在my.cnf选项文件里的[mysqld]节里使用innodb_data_file_path选项。在Windows上,你可以替代地使用my.ini文件。innodb_data_file_path的值应该为一个或多个 数据文件规格的列表。如果你命名一个以上的数据文件,用 分号(‘;’)分隔它们:
innodb_data_file_path=datafile_spec1[;datafile_spec2]...
例如:把明确创建的具有相同特征的表空间作为默认设置的设置操作如下:
[mysqld]
innodb_data_file_path=ibdata1: 10M :autoextend
这个设置配置一个可扩展大小的尺寸为10MB的单独文件,名为ibdata1。没有给出文件的位置,所以默认的是在MySQL的数据目录内。
尺寸大小用M或者G后缀来指定说明单位是MB或者GB。
一个表空间,它在数据目录里包含一个名为ibdata1的固定尺寸50MB的数据文件和一个名为ibdata 2大小为50MB的自动扩展文件,其可以 像这样被配置:
[mysqld]
innodb_data_file_path=ibdata1: 50M ;ibdata2: 50M :autoextend
一个指定数据文件的完全后缀包括文件名,它的尺寸和数个可选属性:
file_name:file_size[:autoextend[:max:max_file_size]]
autoextend属性和后面跟着的属性只可被用来对innodb_data_file_path行里最后一个数据文件。
如果你对最后的数据文件指定autoextend选项。如果数据文件耗尽了表空间中的自由空间,InnoDB就扩展数据文件。扩展的幅度是每次8MB。
如果磁盘已满,你可能想要把其它数据添加到另一个硬盘上。重新配置一个已存在表空间的指令见15.2.7节,“添加和删除InnoDB数据和日志文件”。
InnoDB并不感知最大文件尺寸,所以要小心文件系统,在那上面最大的文件尺寸是2GB。要为一个自动扩展数据文件指定最大尺寸,请使用max属性。下列配置允许ibdata1涨到极限的500MB:
[mysqld]
innodb_data_file_path=ibdata1: 10M :autoextend:max: 500M
InnoDB默认地在MySQL数据目录创建表空间文件。要明确指定一个位置,请使用innodb_data_home_dir选项。比如,要使用两个名为ibdata1和ibdata2的文件,但是要把他们创建到/ibdata, 像如下一样配置InnoDB:
[mysqld]
innodb_data_home_dir = /ibdata
innodb_data_file_path=ibdata1: 50M ;ibdata2: 50M :autoextend
注释:InnoDB不创建目录,所以在启动服务器之前请确认/ibdata目录的确存在。这对你配置的任何日志文件目录来说也是真实的。使用Unix或DOS的mkdir命令来创建任何必需的目录。
通过把innodb_data_home_dir的值原原本本地部署到数据文件名,并在需要的地方添加斜杠或反斜杠,InnoDB为每个数据文件形成目录路径。如果innodb_data_home_dir选项根本没有在my.cnf中提到, 默认值是“dot”目录 ./,这意思是MySQL数据目录。
如果你指定innodb_data_home_dir为一个空字符串,你可以为列在innodb_data_file_path值里的数据文件指定绝对路径。下面的例子等价于前面那个例子:
[mysqld]
innodb_data_home_dir =
innodb_data_file_path=/ibdata/ibdata1: 50M ;/ibdata/ibdata2: 50M :autoextend
一个简单的my.cnf例子。假设你有一台配备128MB内存和一个硬盘的计算机。下面的例子显示在my.cnf或my.ini里对InnoDB可能的配置参数,包括autoextend属性。
这个例子适合大多数在Unix和Windows上,不想分配InnoDB数据文件和日志文件到数个磁盘上的用户。它在MySQL数据目录创建一个自动扩展数据文件ibdata1和两个日志文件ib_logfile0及ib_logfile 1。同样,InnoD在数据目录里自动创建的小型档案InnoDB日志文件ib_arch_log_0000000000也结束。
[mysqld]
# You can write your other MySQL server options here
# ...
# Data files must be able to hold your data and indexes.
# Make sure that you have enough free disk space.
innodb_data_file_path = ibdata1: 10M :autoextend
#
# Set buffer pool size to 50-80% of your computer's memory
set-variable = innodb_buffer_pool_size= 70M
set-variable = innodb_additional_mem_pool_size= 10M
#
# Set the log file size to about 25% of the buffer pool size
set-variable = innodb_log_file_size= 20M
set-variable = innodb_log_buffer_size= 8M
#
innodb_flush_log_at_trx_commit=1
请确认MySQL服务器有适当的权限在数据目录里创建文件。更一般地,服务器必须对任何它需要创建数据文件或日志文件的目录有访问权限。
注意,在一些文件系统上,数据文件必需小于2GB。数据文件的合并尺寸必须至少10MB。
当你第一次创建一个InnoDB表空间,最好从命令行来启动MySQL服务器。InnoDB然后把数据库创建的信息打印到屏幕,所以你可以看见正在发生什么。比如,在Windows上,如果mysqld-max位于C:\mysql\bin,你可以如下来启动它:
C:\> C:\mysql\bin\mysqld-max --console
如果你不发送服务器输出到屏幕上,请检查服务器的错误日志来看在启动过程中InnoDB打印了什么。
请参阅15.2.5节,“创建InnoDB表空间”,以获得InnoDB显示的信息看起来应该 像什么的例子。
Windows上如何指定选项? 在Windows上选项文件的规则如下:
· 只应该创建一个my.cnf或文件。
· my.cnf文件应该被放在C盘根目录。
· my.ini文件应该被放置在WINDIR目录;例如C:\WINDOWS或C:\WINNT。你可以在Windows控制台的命令提示符使用SET命令来打印WINDIR的值:
· C:\> SET WINDIR
· windir=C:\WINNT
· 如果你的PC在C盘不是启动盘的地方使用启动装载机,你唯一的选择是使用my.ini文件。
· 如果你使用安装和配置向导安装的MySQL,my.ini文件被放在MySQL的安装目录。请参阅2.3.5.14节,“my.ini文件的位置”。
Unix上在哪里指定选项? 在Unix上,mysqld从下列文件,如果它们存在的话。以下列的顺序读取选项:
· /etc/my.cnf
全局选项。
· $MYSQL_HOME/my.cnf
服务器专用选项。
· defaults-extra-file
--defaults-extra-file选项指定的文件。
· ~/.my.cnf
用户专用选项。
MYSQL_HOME代表环境变量,它内含着到包含服务器专用my.cnf文件的目录的路径。
如果你确信mysqld只从指定文件读取选项,你可以在启动服务器之时在命令行使用--defaults-option作为第一个选项:
mysqld --defaults-file=your_path_to_my_cnf
一个高级的my.cnf例子。假设你有一台Linux计算机,有2GB内存和三个60GB硬盘(在目录路径/, /dr2和/dr3)。下列例子显示 了在my.cnf里对InnoDB可能的配置参数。
[mysqld]
# You can write your other MySQL server options here
# ...
innodb_data_home_dir =
#
# Data files must be able to hold your data and indexes
innodb_data_file_path = /ibdata/ibdata1: 2000M ;/dr2/ibdata/ibdata2: 2000M :autoextend
#
# Set buffer pool size to 50-80% of your computer's memory,
# but make sure on Linux x86 total memory usage is < 2GB
innodb_buffer_pool_size= 1G
innodb_additional_mem_pool_size= 20M
innodb_log_group_home_dir = /dr3/iblogs
#
innodb_log_files_in_group = 2
#
# Set the log file size to about 25% of the buffer pool size
innodb_log_file_size= 250M
innodb_log_buffer_size= 8M
#
innodb_flush_log_at_trx_commit=1
innodb_lock_wait_timeout=50
#
# Uncomment the next lines if you want to use them
#innodb_thread_concurrency=5
注意,该例子把两个数据文件放在不同磁盘上。InnoDB开始用第一个数据文件填充表空间。在一些情况下,如果所有数据不被放置在同一物理磁盘上,这样将改善数据库的性能。把日志文件放在与数据文件不同的磁盘上对性能是经常很有好处的。你也可以使用原始磁盘分区(原始设备)作为InnoDB数据文件,这样可以加速I/O。请参阅15.2.14.2节,“为表空间使用原始设备”。
警告:在32位GNU/Linux x86上,你必须要小心不要设置过高的内存用量。glibc可能允许进程堆积在线程堆栈上发展,它会造成你的服务器崩溃。如果下列表达式的值接近或者超过2GB,系统会面临危机:
innodb_buffer_pool_size
+ key_buffer_size
+ max_connections*(sort_buffer_size+read_buffer_size+binlog_cache_size)
+ max_connections*2MB
每个线程使用一个堆栈(通常是2MB,但在MySQL AB二进制 分发版里只有256KB)并且在最坏的情况下也使用sort_buffer_size + read_buffer_size附加内存。
你可以自己编译MySQL,在32位Windows上使用高达64GB物理内存。请参阅15.2.4节,“InnoDB启动选项”里对innodb_buffer_pool_awe_mem_mb的描述。
如何调整其它mysqld服务器参数?下列值是典型的,且适用于多数用户:
[mysqld]
skip-external-locking
max_connections=200
read_buffer_size= 1M
sort_buffer_size= 1M
#
# Set key_buffer to 5 - 50% of your RAM depending on how much
# you use MyISAM tables, but keep key_buffer_size + InnoDB
# buffer pool size < 80% of your RAM
key_buffer_size=value
这一节叙述InnoDB相关的服务器选项,所有这些选项可以以--opt_name=value的形式在命令行或在选项文件里被指定。
· innodb_additional_mem_pool_size
InnoDB用来存储数据目录信息&其它内部数据结构的内存池的大小。你应用程序里的表越多,你需要在这里分配越多的内存。如果InnoDB用光了这个池内的内存,InnoDB开始从操作系统分配内存,并且往MySQL错误日志写警告信息。 默认值是1MB。
· innodb_autoextend_increment
当自动扩展表空间被填满之时,为扩展而增加的尺寸(MB为单位)。 默认值是8。这个选项可以在运行时作为全局系统变量而改变。
· innodb_buffer_pool_awe_mem_mb
如果缓冲池被放在32位Windows的AWE内存里,这个参数就是缓冲池的大小(MB为单位)。(仅在32位Windows上相关)如果你的32位Windows操作系统使用所谓的“地址窗口扩展(AWE)”支持超过4GB内存,你可以用这个参数把InnoDB缓冲池分配进AWE物理内存。这个参数最大的可能值是64000。如果这个参数被指定了,innodb_buffer_pool_size是在32位地址空间的mysqld内的窗口,InnoDB把那个AWE内存映射上去。对innodb_buffer_pool_size参数,一个比较好的值是500MB。
· innodb_buffer_pool_size
InnoDB用来缓存它的数据和索引的内存缓冲区的大小。你把这个值设得越高,访问表中数据需要得磁盘I/O越少。在一个专用的数据库服务器上,你可以设置这个参数达机器物理内存大小的80%。尽管如此,还是不要把它设置得太大,因为对物理内存的竞争可能在操作系统上导致内存调度。
· innodb_checksums
InnoDB在所有对磁盘的页面读取上使用校验和验证以确保额外容错防止硬件损坏或数据文件。尽管如此,在一些少见的情况下(比如运行标准检查之时)这个额外的安全特征是不必要的。在这些情况下,这个选项( 默认是允许的)可以用--skip-innodb-checksums来关闭。
· innodb_data_file_path
到单独数据文件和它们尺寸的路径。通过把innodb_data_home_dir连接到这里指定的每个路径,到每个数据文件的完整目录路径可被获得。文件大小通过给尺寸值尾加M或G以MB或者GB(1024MB)为单位被指定。文件尺寸的和至少是10MB。在一些操作系统上,文件必须小于2GB。如果你没有指定innodb_data_file_path,开始的默认行为是创建一个单独的大小10MB名为ibdata1的自扩展数据文件。在那些支持大文件的操作系统上,你可以设置文件大小超过4GB。你也可以使用原始磁盘分区作为数据文件,请参阅15.2.14.2节,“为表空间使用原始设备”。
· innodb_data_home_dir
目录路径对所有InnoDB数据文件的共同部分。如果你不设置这个值, 默认是MySQL数据目录。你也可以指定这个值为一个空字符串,在这种情况下,你可以在innodb_data_file_path中使用绝对文件路径。
· innodb_doublewrite
默认地,InnoDB存储所有数据两次,第一次存储到doublewrite缓冲,然后存储到确实的数据文件。这个选项可以被用来禁止这个功能。类似于innodb_checksums,这个选项 默认是允许的;因为标准检查或在对顶级性能的需要超过对数据完整性或可能故障的关注之时,这个选项用--skip-innodb-doublewrite来关闭。
· innodb_fast_shutdown
如果你把这个参数设置为0,InnoDB在关闭之前做一个完全净化和一个插入缓冲合并。这些操作要花几分钟时间,设置在极端情况下要几个小时。如果你设置这个参数为1,InnoDB在关闭之时跳过这些操作。 默认值为1。如果你设置这个值为2 (在Netware无此值), InnoDB将刷新它的日志然后冷关机,仿佛MySQL崩溃一样。已提交的事务不会被丢失,但在下一次启动之时会做一个崩溃恢复。
· innodb_file_io_threads
InnoDB中文件I/O线程的数量。正常地,这个参数是用 默认的,默认值是4,但是大数值对Windows磁盘I/O有益。在Unix上,增加这个数没有效果,InnoDB总是使用默认值。
· innodb_file_per_table
这个选项致使InnoDB用自己的.ibd文件为存储数据和索引创建每一个新表,而不是在共享表空间中创建。请参阅15.2.6.6节,“使用Per-Table表空间”。
· innodb_flush_log_at_trx_commit
当innodb_flush_log_at_trx_commit被 设置为0,日志缓冲每秒一次地被写到日志文件,并且对日志文件做到磁盘操作的刷新,但是在一个事务提交不做任何操作。当这个值为1(默认值)之时,在每个事务提交时,日志缓冲被写到日志文件,对日志文件做到磁盘操作的 刷新。当设置为2之时,在每个提交,日志缓冲被写到文件,但不对日志文件做到磁盘操作的刷新。尽管如此,在对日志文件的刷新在值为2的情况也每秒发生一次。我们必须注意到,因为进程安排问题,每秒一次的 刷新不是100%保证每秒都发生。你可以通过设置这个值不为1来获得较好的性能,但随之你会在一次崩溃中损失二分之一价值的事务。如果你设置这个值为0,那么任何mysqld进程的崩溃会删除崩溃前最后一秒的事务,如果你设置这个值为2,那么只有操作系统崩溃或掉电才会删除最后一秒的事务。尽管如此,InnoDB的崩溃恢复不受影响,而且因为这样崩溃恢复开始作用而不考虑这个值。注意,许多操作系统和一些磁盘硬件会欺骗 刷新到磁盘操作。尽管刷新没有进行,你可以告诉mysqld刷新已经进行。即使设置这个值为1,事务的持久程度不被保证,且在最坏情况下掉电甚至会破坏InnoDB数据库。在SCSI磁盘控制器中,或在磁盘自身中,使用有后备电池的磁盘缓存会加速文件 刷新并且使得操作更安全。你也可以试着使用Unix命令hdparm来在硬件缓存中禁止磁盘写缓存,或使用其它一些对硬件提供商专用的命令。这个选项的 默认值是1。
· innodb_flush_method
这个选项只在Unix系统上有效。如果这个选项被设置为fdatasync (默认值),InnoDB使用fsync()来刷新数据和日志文件。如果被设置为O_DSYNC,InnoDB使用O_SYNC来打开并刷新日志文件,但使用fsync()来 刷新数据文件。如果O_DIRECT被指定了(在一些GNU/Linux版本商可用),InnoDB使用O_DIRECT来打开数据文件,并使用fsync()来刷新数据和日志文件。注意,InnoDB使用fsync()来替代fdatasync(),并且它 默认不使用O_DSYNC,因为这个值在许多Unix变种上已经发生问题。
· innodb_force_recovery
警告:这个选项仅在一个紧急情况下被定义,当时你想要从损坏的数据库转储表。可能的值为从1到6。这些值的意思在15.2.8.1节,“强制恢复”中叙述。作为一个安全措施,当这个选项值大于零之时,InnoDB阻止用户修改数据。
· innodb_lock_wait_timeout
InnoDB事务在被回滚之前可以等待一个锁定的超时秒数。InnoDB在它自己的 锁定表中自动检测事务死锁并且回滚事务。InnoDB用LOCK TABLES语句注意到锁定设置。默认值是50秒。
为在一个复制建立中最大可能的持久程度和连贯性,你应该在主服务器上的my.cnf文件里使用innodb_flush_log_at_trx_commit=1和sync-binlog= 1。
· innodb_locks_unsafe_for_binlog
这个选项在InnoDB搜索和索引扫描中关闭下一键锁定。这个选项的 默认值是假(false)。
正常地,InnoDB使用一个被称为next-key locking的算法。当搜索或扫描一个表索引之时,InnoDB以这样一种方式实行行级锁定,它对任何遇到的索引记录设置共享的或独占的锁定。因此,行级锁定实际是索引记录锁定。InnoDB对索引记录设置的锁定也影响被锁定索引记录之前的“gap”。如果一个用户对某一索引内的记录R又共享的或独占的锁定,另一个用户不能立即在R之前以索引的顺序插入一个新的索引记录。这个选项导致InnoDB不在搜索或索引扫描中使用下一 键锁定。下一键锁定仍然被用来确保外键强制及重复键核查。注意,使用这个选项可能会导致一些诡异的问题:假设你想要用值大于100的标识符从子表里读取并锁定所有的子记录,同时 向随后在选定的行更新一些列:
SELECT * FROM child WHERE id > 100 FOR UPDATE;
假设在id列有一个索引。查询从id大于100的第一个记录开始扫描索引。如果在索引记录上的锁定不把在间隙处生成的插入排除锁定,同时一个新行被插进表中。如果你在同一个事务之内执行同样的SELECT,你会在查询返回的结果包里看到一个新行。这也意味着,如果新条目被加进数据库,InnoDB不保证连续性;尽管如此, 对应连续性仍被保证。因此,如果这个选项被使用,InnoDB在大多数孤立级别保证READ COMMITTED。
这个选项甚至更不安全。InnoDB在一个UPDATE或DELETE中只锁定它更新或删除的行。这大大减少了死锁的可能性,但是可以发生死锁。注意,即使在当类似的操作影响不同行时的情况下,这个选项仍然不允许诸如UPDATE这样的操作压倒相似选项(比如另一个UPDATE)。考虑下列例子:
CREATE TABLE A(A INT NOT NULL, B INT);
INSERT INTO A VALUES (1,2),(2,3),(3,2),(4,3),(5,2);
COMMIT;
如果一个连接执行一个查询:
SET AUTOCOMMIT = 0;
UPDATE A SET B = 5 WHERE B = 3;
并且其它连接跟着第一个连接执行其它查询:
SET AUTOCOMMIT = 0;
UPDATE A SET B = 4 WHERE B = 2;
接着查询2要等查询1的提交或回滚,因为查询1对行(2,3)有一个独占的锁定,并且查询2在扫描行的同时也试着对它不能锁定的同一个行(2,3)采取一个独占的锁定。这是因为当innodb_locks_unsafe_for_binlog选项被使用之时,查询2首先对一个行采取一个独占的锁定,然后确定是否这个行属于结果包,并且如果不属于,就释放不必要的锁定。
因此,查询1按如下执行:
x-lock(1,2)
unlock(1,2)
x-lock(2,3)
update(2,3) to (2,5)
x-lock(3,2)
unlock(3,2)
x-lock(4,3)
update(4,3) to (4,5)
x-lock(5,2)
unlock(5,2)
并且查询2按如下执行:
x-lock(1,2)
update(1,2) to (1,4)
x-lock(2,3) - 等待查询1提交或回滚
· innodb_log_arch_dir
如果我们使用日志档案,被完整写入的日志文件所在的目录也被归档。这个参数值如果被使用了,应该被设置得与innodb_log_group_home_dir一样。尽管如此,它不是必需的。
· innodb_log_archive
这个值当前被设为0。因为MySQL使用它自己的日志文件从备份来恢复,所以当前没有必要来归档InnoDB日志文件。这个选项的 默认值是0。
· innodb_log_buffer_size
InnoDB用来往磁盘上的日志文件写操作的缓冲区的大小。明智的值是从1MB到8MB。 默认的是1MB。一个大的日志缓冲允许大型事务运行而不需要在事务提交之前往磁盘写日志。因此,如果你有大型事务,使日志缓冲区更大以节约磁盘I/O。
· innodb_log_file_size
在日志组里每个日志文件的大小。在32位计算机上日志文件的合并大小必须少于4GB。 默认是5MB。明智的值从1MB到N分之一缓冲池大小,其中N是组里日志文件的数目。值越大,在缓冲池越少需要检查点刷新行为,以节约磁盘I/O。但更大的日志文件也意味这在崩溃时恢复得更慢。
· innodb_log_files_in_group
在日志组里日志文件的数目。InnoDB以循环方式写进文件。默认是2(推荐)。
· innodb_log_group_home_dir
到InnoDB日志文件的目录路径。它必须有和innodb_log_arch_dir一样的值。如果你不指定任何InnoDB日志参数, 默认的是在MySQL数据目录里创建两个5MB大小名为ib_logfile0和ib_logfile 1的文件。
· innodb_max_dirty_pages_pct
这是一个范围从0到100的整数。默认是90。InnoDB中的主线程试着从缓冲池写页面,使得脏页(没有被写的页面)的百分比不超过这个值。如果你有SUPER权限,这个百分比可以在服务器运行时按下面来改变:
SET GLOBAL innodb_max_dirty_pages_pct = value;
· innodb_max_purge_lag
这个选项控制在净化操作被滞后之时,如何延迟INSERT, UPDATE和DELETE操作。(请参阅15.2.12节,“多版本的实施”)。这个参数的 默认值是零,意为无延迟。这个选项可以在运行时作为全局系统变量而被改变。
InnoDB事务系统维持一个事务列表,该列表有被UPDATE或DELETE操作标志为删除的索引记录。让这个列表的长度为purge_lag。当purge_lag超过innodb_max_purge_lag之时,每个INSERT, UPDATE和DELETE操作延迟 ((purge_lag/innodb_max_purge_lag)*10)-5毫秒。在净化批处理的开始,延迟每隔10秒计算。如果因为一个旧的可以看到行被净化的一致的读查看, 删除操作不被延迟。
对有问题的工作量,典型设置可能是1百万,假设我们的事务很小,只有100字节大小,我们就可以允许在我们的表之中有100MB未净化的行。
· innodb_mirrored_log_groups
我们为数据库保持的日志组内同样拷贝的数量。当前这个值应该被设为1。
· innodb_open_files
在InnoDB中,这个选项仅与你使用多表空间时有关。它指定InnoDB一次可以保持打开的.ibd文件的最大数目。最小值是10。 默认值300。
对.ibd文件的文件描述符是仅对InnoDB的。它们独立于那些由--open-files-limit服务器选项指定的描述符,且不影响表缓存的操作。
· innodb_status_file
这个选项让InnoDB为周期的SHOW INNODB STATUS输出创建一个文件<datadir>/innodb_status.<pid>。
· innodb_support_xa
当被设置为ON或者1(默认地),这个变量允许InnoDB支持在XA事务中的 双向提交。允许innodb_support_xa导致一个额外的对事务准备的磁盘刷新。如果你对使用XA并不关心,你可以通过设置这个选项为OFF或0来禁止这个变量,以减少磁盘 刷新的次数并获得更好的InnoDB性能。
· innodb_table_locks
InnoDB重视LOCK TABLES,直到所有其它线程已经释放他们所有对表的锁定,MySQL才从LOCK TABLE .. WRITE返回。默认值是1,这意为LOCK TABLES让InnoDB内部锁定一个表。在使用AUTOCOMMIT=1的应用里,InnoDB的内部表锁定会导致死锁。你可以在my.cnf文件(Windows上是my.ini文件)里设置innodb_table_locks= 0 来 消除这个问题。
· innodb_thread_concurrency
InnoDB试着在InnoDB内保持操作系统线程的数量少于或等于这个参数给出的限制。如果有性能问题,并且SHOW INNODB STATUS显示许多线程在等待信号,可以让线程“thrashing” ,并且设置这个参数更小或更大。如果你的计算机有多个处理器和磁盘,你可以试着这个值更大以更好地利用计算机的资源。一个推荐的值是系统上处理器和磁盘的个数之和。值为500或比500大会禁止 调用并发检查。默认值是20,并且如果设置大于或等于20,并发检查将被禁止。
· innodb_status_file
这个选项让InnoDB为周期的SHOW INNODB STATUS输出创建一个文件<datadir>/innodb_status.<pid>。
15.2.5.1. 处理InnoDB初始化问题
假设你已经安装了MySQL,并且已经编辑了选项文件,使得它包含必要的InnoDB配置参数。在启动MySQL之前,你应该验证你为InnoDB数据文件和日志文件指定的目录是否存在,并且MySQL有访问这些目录的权限。InnoDB不能创建目录,只能创建文件。也检查你有足够的空间来放数据和日志文件。
当创建InnoDB数据库时,最好从命令提示符运行MySQL服务器mysqld, 而不要从mysqld_safe包装或作为Windows的服务来运行。当你从命令提示符运行,你可看见mysqld打印什么以及发生了什么。在Unix上,只需要调用mysqld。在Windows上,使用--console选项。
当在选项文件里初始地配置InnoDB后,开始启动MySQL服务器之时,InnoDB创建一个数据文件和日志文件。InnoDB打印如下一些东西:
InnoDB: The first specified datafile /home/heikki/data/ibdata1
did not exist:
InnoDB: a new database to be created!
InnoDB: Setting file /home/heikki/data/ibdata1 size to 134217728
InnoDB: Database physically writes the file full: wait...
InnoDB: datafile /home/heikki/data/ibdata2 did not exist:
new to be created
InnoDB: Setting file /home/heikki/data/ibdata2 size to 262144000
InnoDB: Database physically writes the file full: wait...
InnoDB: Log file /home/heikki/data/logs/ib_logfile0 did not exist:
new to be created
InnoDB: Setting log file /home/heikki/data/logs/ib_logfile0 size
to 5242880
InnoDB: Log file /home/heikki/data/logs/ib_logfile1 did not exist:
new to be created
InnoDB: Setting log file /home/heikki/data/logs/ib_logfile1 size
to 5242880
InnoDB: Doublewrite buffer not found: creating new
InnoDB: Doublewrite buffer created
InnoDB: Creating foreign key constraint system tables
InnoDB: Foreign key constraint system tables created
InnoDB: Started
mysqld: ready for connections
一个新的InnoDB数据库被创建了。你可以用mysql这样通常的MySQL客户端程序连接到MySQL服务器。当你用mysqladmin shutdown关闭MySQL服务器之时,输出类似如下:
010321 18:33:34 mysqld: Normal shutdown
010321 18:33:34 mysqld: Shutdown Complete
InnoDB: Starting shutdown...
InnoDB: Shutdown completed
你可以看数据文件和日志文件,并且你可以看见文件被创建。日志目录也包含一个名为ib_arch_log_0000000000的小文件。这个文件是数据库被创建的结果,数据库被创建之后InnoDB切断日志归档。当MySQL再次启动之时,数据文件&日志文件已经被创建,所以输出更简洁:
InnoDB: Started
mysqld: ready for connections
你可以添加innodb_file_per_table选项到my.cnf文件,并且让InnoDB存储每一个表到MySQL数据库目录里自己的.ibd文件。请参阅15.2.6.6节,“使用Per-Table表空间”。
如果InnoDB在一个文件操作中打印一个操作系统错误,通常问题是如下中的一个:
· 你没有创建一个InnoDB数据文件目录或InnoDB日志目录。
· mysqld没有访问这些目录的权限 以创建文件。
· mysqld不能恰当地读取my.cnf或my.ini选项文件,因此不能看到你指定的选项。
· 磁盘已满,或者超出磁盘配额。
· 你已经创建一个子目录,它的名字与你指定的数据文件相同。
· 在innodb_data_home_dir或innodb_data_file_path有一个语法错误。
当InnoDB试着初始化它的表空间或日志文件之时,如果出错了,你应该删除InnoDB创建的所有文件。这意味着是所有ibdata文件和所有ib_logfiles文件。万一你创建了一些InnoDB表,为这些表也从MySQL数据库目录删除相应的.frm文件(如果你使用多重表空间的话,也删除任何.ibd文件)。然后你可以试着再次创建InnoDB数据库。最好是从命令提示符启动MySQL服务器 ,以便你可以查看发生了什么。
15.2.6.1. 如何在InnoDB用不同API来使用事务
15.2.6.2. 转换MyISAM表到InnoDB
15.2.6.3. AUTO_INCREMENT列如何在InnoDB中工作
15.2.6.4.外键约束
15.2.6.5. InnoDB和MySQL复制
15.2.6.6. 使用Per-Table表空间
假如你用mysql test命令启动MySQL客户端。要创建一个InnoDB表,你必须在表创建SQL语句中指定ENGINE = InnoDB或者TYPE = InnoDB选项:
CREATE TABLE customers (a INT, b CHAR (20), INDEX (a)) ENGINE=InnoDB;
CREATE TABLE customers (a INT, b CHAR (20), INDEX (a)) TYPE=InnoDB;
SQL语句在表空间的列上创建一个表和索引,表空间包含你在my.cnf指定的数据文件。此外,MySQL在MySQL数据库目录下的test目录里创建一个名为customers.frm的文件。内部地,InnoDB为'test/customers'表往自己的数据目录添加一个条目。这意味这你可以在其它数据库创建一个具有相同名字customers的表,表的名字不会与InnoDB内的冲突。
你可以对任何InnoDB表,通过使用SHOW TABLE STATUS语句,查询在InnoDB表空间内空闲空间的数量。表空间内空闲空间的数量出现在SHOW TABLE STATUS的输出结果内的Comment节里。例如:
SHOW TABLE STATUS FROM test LIKE 'customers'
注意,统计的SHOW只给出关于InnoDB表的大概情况。它们被用于SQL优化。可是,表和索引保留的大小,以字节为单位是准确的。