
innodb
InnoDB,是MySQL的资料库引擎之一,为MySQL AB发布binary的标準之一。InnoDB由Innobase Oy公司所开发,2006年五月时由甲骨文公司併购。与传统的ISAM与MyISAM相比,InnoDB的最大特色就是支持了ACID兼容的事务(Transaction)功能,类似于PostgreSQL。
目前InnoDB採用双轨制授权,一是GPL授权,另一是专有软体授权。
基本介绍
- 中文名:innodb
- 外文名:innodb
- 类型:mysql资料库引擎
- 开发公司:Innobase Oy公司
- 特色:支持了ACID兼容的事务
- 授权:GPL授权,专有软体授权
简介
事务型资料库的首选引擎,支持ACID事务,支持行级锁定。InnoDB是为处理巨大数据量时的最大性能设计。InnoDB存储引擎完全与MySQL伺服器整合,InnoDB存储引擎为在主记忆体中快取数据和索引而维持它自己的缓冲池。InnoDB存储它的表&索引在一个表空间中,表空间可以包含数个档案(或原始磁碟分区)。这与MyISAM表不同,比如在MyISAM表中每个表被存在分离的档案中。InnoDB 表可以是任何尺寸,即使在档案尺寸被限制为2GB的作业系统上。InnoDB默认地被包含在MySQL二进制分发中。Windows Essentials installer使InnoDB成为Windows上MySQL的默认表。
InnoDB 给 MySQL 提供了具有事务(transaction)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)、多版本并发控制(multi-versioned concurrency control)的事务安全(transaction-safe (ACID compliant))型表。InnoDB 提供了行级锁(locking on row level),提供与 Oracle 类似的不加锁读取(non-locking read in SELECTs)。InnoDB锁定在行级并且也在SELECT语句提供一个Oracle风格一致的非锁定读。这些特色增加了多用户部署和性能。没有在InnoDB中扩大锁定的需要,因为在InnoDB中行级锁定适合非常小的空间。InnoDB也支持FOREIGN KEY强制。在SQL查询中,你可以自由地将InnoDB类型的表与其它MySQL的表的类型混合起来,甚至在同一个查询中也可以混合。这些特性均提高了多用户并发操作的性能表现。在InnoDB表中不需要扩大锁定(lock escalation),因为 InnoDB 的行级锁定(row level locks)适宜非常小的空间。InnoDB 是 MySQL 上第一个提供外键约束(FOREIGN KEY constraints)的表引擎。
在技术上,InnoDB 是一套放在 MySQL后台的完整资料库系统,InnoDB 在主记忆体中建立其专用的缓冲池用于高速缓冲数据和索引。InnoDB 把数据和索引存放在表空间里,可能包含多个档案,这与其它的不一样,举例来说,在 MyISAM 中,表被存放在单独的档案中。InnoDB 表的大小只受限于作业系统的档案大小,可也可以每个表使用各自独立的表空间,只需要启用选项 innodb_file_per_table。
MySQL

在 MySQL 的原始码中,从 3.23.34a 开始包含 InnoDB 表引擎,并在 MySQL -Max 的二进制版本中激活。
性能技巧
1.如果 Unixtop或 Windows任务管理器(Task Manager)显示服务的 CPU 占用率小于 70%,(shows that the CPU usage percentage with your workload is less than 70 %,)你的系统瓶颈可能在磁碟读写上。或许你提交了大量的事务,或者是缓冲池(buffer pool)太小了。将缓冲池设大点会有所帮助,但一定要注意不能大于物理记忆体的 80%。
2.在一个事务中包含几个修改。如果事务对资料库进行了修改,那幺在这个事务提交时 InnoDB 必须刷新日誌到磁碟上。因为硬碟的旋转速度通常至多为 167 转/秒,那幺只要磁碟不欺骗作业系统,提交的事务数目限止也同样为 167 次/秒·用户。
3.如果掉失最近的几个事务无所谓的话,可以在my.cnf档案中将参数innodb_flush_log_at_trx_commit设定为 0。InnoDB 无论如何总是尝试一秒刷新(flush)一次日誌,儘管刷新并不能得到保证。
4.将日誌档案(log files)设大一点,使日誌档案的总和正好与缓冲池(buffer pool)一样大。当 InnoDB 用光日誌档案的空间时,它不得不在一个时间点上将缓冲池内修改过的内容写到磁碟上。 小的日誌档案可能引起不必要的磁碟写操作。但是大的日誌档案的缺点就是在数据恢复时将占用较长的时间。
5.同样 log buffer 儘量设大点,比如说 8 MB。
6.如果要存储变长的字元串或栏位可能会包含大量的 NULLs,请使用VARCHAR型栏位代替CHAR。一个CHAR(n)栏位总是使用 n bytes 来存储数据,即使这个字元串很短或是一个 NULL 值。较小的表更加适合缓冲池同时能够减少磁碟 I/O 。
7.(适合从 3.23.41 以上版本) 在某些版本的 Linux 和 Unixes 中,使用 Unixfsync或其它类似的方法将档案刷新到磁碟是异常地慢的。InnoDB 默认的方法就是fsync。如果你对资料库系统的磁碟写性能不能感到满意,你可以尝试在my.cnf中将innodb_flush_method设定为O_DSYNC,儘管O_DSYNC选项在多数的系统上看起来比较慢。
8.在向 InnoDB 导入数据时,请确认 MySQL 没有打开autocommit=1。否则每个插入语句都要将 log 刷新到磁碟。在你的 SQL 导入档案的第一行加入
set autocommit=0;并在最后一行加入commit;
如果使用mysqldump选项--opt,你将会得到一个快速导入 InnoDB 表的转储(dump)档案,甚至可以不再使用上面所提的set autocommit=0; ... commit;。
9.小心 insert 集全的大回滚(roolback):在插入时 InnoDB 使用插入缓冲来减少磁碟 I/O,但在相应的回滚中却没有使用这样的机制。一个 disk-bound rollback 可能会花费相应插入时间的 30 倍。如果发生一个失控的回滚,你可以查看第 6.1 章节的技巧来停止它。
10.同样也要小心一个大的 disk-bound 的操作。使用DROP TABLE或TRUNCATE(从 MySQL-4.0 以上) 来清空一个表,而不要使用DELETE FROM yourtable。
11.如果需要插入大量记录行可以使用多行(multi-line)的INSERT来减少客户端与伺服器端的通信开销:
INSERT INTO yourtable VALUES (1, 2), (5, 5);
这个技巧对插入任何表均有效,而不仅仅是 InnoDB。
12.如果在辅键上有UNIQUE约束,从 3.23.52 和 4.0.3 开始,可以通过在一个导入会话中将唯一键检查(uniqueness check)关闭来提高数据导入速度:
SET UNIQUE_CHECKS=0;一个大的表导入这将减少大量的磁碟 I/O,因为这时 InnoDB 可能使用自身的插入缓冲来分批地记录辅助索引。
13.如果在表中有一个子FOREIGN KEY约束,从 3.23.52 和 4.0.3 开始,可以通过在一个导入会话中将外键检查(foreign key check)关闭来提高数据导入速度:
SET FOREIGN_KEY_CHECKS=0;
对一个大的表导入这将减少大量的磁碟 I/O。
注意事项
输出信息的某些注意点:
- 如果 TRANSACTIONS 部分报告锁定等待(lock waits),那幺你的应用程式可能有锁争用(lock contention)。输出信息可以帮助跟蹤事务死锁的原因。
- SEMAPHORES 部分报告执行绪等待信号量以及统计出执行绪需要旋转(spin)或等待(wait)一个互斥(mutex)或 rw-lock 信号量的次数。一个较大的执行绪等待信号量的次数可能是由于磁碟 I/O 引起,或 InnoDB 内部的争用问题(contention problems)。争用(Contention)可能是由于比较繁重的并发性查询,或作业系统的执行绪调度的问题。 在这种情形下,可将innodb_thread_concurrency设定地小于默认的 8 。
- FILE I/O 部分列出了档案 I/O 的等待请求。过大的值就意味着磁碟 I/O 瓶颈。
- BUFFER POOL AND MEMORY 部分给出了页面读写的统计。通过这些值可以计算出你的查询通常所需的数据档案 I/O 量。