插入缓冲是InnoDB存储引擎关键特性中最令人激动的。不过,这个名字可能会让人认为插入缓冲是缓冲池中的一个部分。其实不然,InnoDB缓冲池中有Insert Buffer信息固然不错,但是Insert Buffer和数据页一样,也是物理页的一个组成部分。
我们知道,主键是行唯一的标识符,在应用程序中行记录的插入顺序是按照主键递增的顺序进行插入的。因此,插入聚集索引一般是顺序的,不需要磁盘的随机读取。比如说我们按下列SQL定义的表。
mysql> create table t ( id int auto_increment, name varchar(30),primary key (id));
Query OK, 0 rows affected (0.14 sec)
id列是自增长的,这意味着当执行插入操作时,id列会自动增长,页中的行记录按id执行顺序存放。一般情况下,不需要随机读取另一页执行记录的存放。因此,在这样的情况下,插入操作一般很快就能完成。但是,不可能每张表上只有一个聚集索引,在更多的情况下,一张表上有多个非聚集的辅助索引(secondary index)。比如,我们还需要按照name这个字段进行查找,并且name这个字段不是唯一的。即,表是按如下的SQL语句定义的:
mysql> create table t ( id int auto_increment, name varchar(30),primary key (id),key(name));
Query OK, 0 rows affected (0.21 sec)
这样的情况下产生了一个非聚集的并且不是唯一的索引。在进行插入操作时,数据页的存放还是按主键id的执行顺序存放,但是对于非聚集索引,叶子节点的插入不再是顺序的了。这时就需要离散地访问非聚集索引页,插入性能在这里变低了。然而这并不是这个name字段上索引的错误,因为B+树的特性决定了非聚集索引插入的离散性。
InnoDB存储引擎开创性地设计了插入缓冲,对于非聚集索引的插入或更新操作,不是每一次直接插入索引页中。而是先判断插入的非聚集索引页是否在缓冲池中。如果在,则直接插入;如果不在,则先放入一个插入缓冲区中,好似欺骗数据库这个非聚集的索引已经插到叶子节点了,然后再以一定的频率执行插入缓冲和非聚集索引页子节点的合并操作,这时通常能将多个插入合并到一个操作中(因为在一个索引页中),这就大大提高了对非聚集索引执行插入和修改操作的性能。
插入缓冲的使用需要满足以下两个条件:
索引是辅助索引。
索引不是唯一的。
当满足以上两个条件时,InnoDB存储引擎会使用插入缓冲,这样就能提高性能了。不过考虑一种情况,应用程序执行大量的插入和更新操作,这些操作都涉及了不唯一的非聚集索引,如果在这个过程中数据库发生了宕机,这时候会有大量的插入缓冲并没有合并到实际的非聚集索引中。如果是这样,恢复可能需要很长的时间,极端情况下甚至需要几个小时来执行合并恢复操作。
辅助索引不能是唯一的,因为在把它插入到插入缓冲时,我们并不去查找索引页的情况。如果去查找肯定又会出现离散读的情况,插入缓冲就失去了意义。
可以通过命令SHOW ENGINE INNODB STATUS来查看插入缓冲的信息:
mysql> show engine innodb status\G;
*************************** 1. row ***************************
Type: InnoDB
Name:
Status:
=====================================
100727 22:21:48 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 44 seconds
......
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 7545, free list len 3790, seg size 11336,
8075308 inserts, 7540969 merged recs, 2246304 merges
......
----------------------------
END OF INNODB MONITOR OUTPUT
============================
1 row in set (0.00 sec)
seg size显示了当前插入缓冲的大小为11 336*16KB,大约为177MB,free list len代表了空闲列表的长度,size代表了已经合并记录页的数量。下面一行可能是我们真正关心的,因为它显示了提高性能了。Inserts代表插入的记录数,merged recs代表合并的页的数量,merges代表合并的次数。merges∶merged recs大约为3∶1,代表插入缓冲将对于非聚集索引页的IO请求大约降低了3倍。
目前插入缓冲存在一个问题是,在写密集的情况下,插入缓冲会占用过多的缓冲池内存,默认情况下最大可以占用1/2的缓冲池内存。以下是InnoDB存储引擎源代码中对insert buffer的初始化操作:
/** Buffer pool size per the maximum insert buffer size */
#define IBUF_POOL_SIZE_PER_MAX_SIZE 2
ibuf->max_size = buf_pool_get_curr_size() / UNIV_PAGE_SIZE
/ IBUF_POOL_SIZE_PER_MAX_SIZE;
这对其他的操作可能会带来一定的影响。Percona已发布一些patch来修正插入缓冲占用太多缓冲池内存的问题,具体的可以到http://www.percona.com/percona-lab.html查找。简单来说,修改IBUF_POOL_SIZE_PER_MAX_SIZE就可以对插入缓冲的大小进行控制,例如,将IBUF_POOL_SIZE_PER_MAX_SIZE改为3,则最大只能使用1/3的缓冲池内存。
- 浏览: 246093 次
-
文章分类
最新评论
发表评论
-
RAID write back write through
2014-07-09 13:44 960RAID write back指的是raid控制器能够将写 ... -
druid PreparedStatementCache设置
2014-07-08 14:34 3628druid的连接池配置中有PreparedStatement ... -
Innodb配置,将数据与日志放在不同磁盘可以加快性能
2012-12-06 19:23 753An advanced my.cnf example ... -
character_set_client character_set_connection character_set_results
2012-11-19 20:21 3257之前一直纠结各种编码的却别:character_set_c ... -
amoeba-mysql的安装使用和读写分离(转)
2012-11-16 16:11 1044http://blog.csdn.net/chen861201 ... -
mysqlcheck myisamchk
2012-11-07 17:45 768mysqlcheck的功能类似myisamchk,但其工作不同 ... -
mysqlbinlog乱码
2012-11-06 19:49 5458使用mysqlbinlog查看二进制文件发现 /*!40019 ... -
auto-rehash
2012-11-05 19:20 4148mysql auto-rehash:读取表信息和列信 ... -
MySQL主从复制(Master-Slave)与读写分离(MySQL-Proxy)实践
2012-09-19 20:21 781MySQL主从复制(Master-Slave)与读写分离(My ... -
mysql显示见表语句
2012-09-03 19:13 1192show create table mysql.slow_l ... -
mysql主从同步延迟问题
2012-08-30 14:18 865见http://www.ixpub.net/thread-13 ... -
二进制日志文件
2012-08-29 19:33 1162mysqld在每个二进制日志 ... -
备份恢复数据库
2012-08-28 20:18 838全备份 mysqldump -utest -ptest -- ... -
mysql用户修改密码
2012-08-28 19:37 774mysqladmin -utest -ptest passwo ... -
set session sql_log_bin=0
2012-08-21 15:22 4048引自http://blog.sina.com.cn/s/blo ... -
字符串转换成date
2012-08-15 20:00 934SELECT STR_TO_DATE('Tue 05 June ... -
selecting top N records per group
2012-08-15 18:56 925http://code.openark.org/blog/my ... -
MySQL DELAY_KEY_WRITE
2012-08-02 20:03 1145MySQL DELAY_KEY_WRITE 引自http:// ... -
Mysql Merge表的优点
2012-07-09 13:52 965在Mysql数据库中,Mysql Me ... -
MySQL线程共享内存参数
2012-07-03 16:48 898MySQL线程共享内存参数 引用 http://mxohy. ...
相关推荐
- **InnoDB Insert Buffer**:监控InnoDB插入缓冲区的状态,包括其使用情况和效果。 - **InnoDB Insert Buffer Usage**:具体展示InnoDB插入缓冲区的利用率。 - **InnoDB Internal Hash Memory Usage**:监控InnoDB...
8. **InnoDB Insert Buffer**:监测InnoDB插入缓冲区的使用情况,包括使用率等信息。 9. **InnoDB Insert Buffer Usage**:进一步提供插入缓冲区的具体使用细节。 10. **InnoDB Internal Hash Memory Usage**:...
使用`SHOW INNODB STATUS`命令可以查看InnoDB引擎的状态,包括缓冲池、事务、锁等信息,这对于诊断性能问题非常有用。同时,InnoDB Monitor也提供了详细的内部活动报告。 2. **调整缓冲池大小**: 缓冲池(Buffer...
【MySQL】InnoDB存储引擎的关键特性之一是插入缓冲(Insert Buffer),它对于提高数据库的插入性能至关重要,尤其是在处理大量辅助索引插入时。在深入理解插入缓冲之前,我们需要先了解InnoDB中的两种索引类型:聚集...
在实际应用中,开发者还可以通过调整数据库参数,如缓冲池大小、索引缓存等,进一步优化这两种引擎的性能。 总的来说,MyISAM和InnoDB引擎各有优劣,选择哪种引擎取决于你的应用场景和性能需求。如果你的工作负载...
- **插入缓冲的改进**:InnoDB 插入缓冲机制进行了优化,提高了插入性能。 ##### 2.2 性能和优化 - **分区表支持**:MySQL 5.5 支持对 InnoDB 表进行分区,这有助于提高大规模数据集的管理效率。 - **内存优化**:...
当需要修改的二级索引页不在缓冲池中,InnoDB会将修改记录到插入缓冲区(Insert Buffer),然后在合适的时候合并到磁盘上的B树中,降低了随机IO的次数,从而提高性能。在大量插入时,插入缓冲能显著提升效率,但异常...
「来道题」服务端面试真题全解析 互联网大厂的资深工程师,带您开启技术成长之路~ 多年大规模在线服务实战经验,近百场校招、社招面试经历,告诉您最...InnoDB的特性:自适应哈希索引、插入缓冲、刷新邻接表、二次写
对于非聚集索引的插入,InnoDB会使用插入缓冲,以减少对非主键索引页的直接修改,提高插入性能。 10. **多版本并发控制(MVCC)** MVCC是InnoDB实现高并发的基础,允许不同事务看到不同的数据视图,避免了锁竞争...
InnoDB Plugin是InnoDB的一个增强版本,引入了许多新的特性和改进,如更高的并发性能、更快的插入速度和更灵活的内存管理。 总结,《InnoDB官方文档中文翻译版》详尽地阐述了InnoDB的各个方面,包括其核心功能、...
- **插入缓冲空闲列表页** (Insert Buffer Free List Page):用于管理插入缓冲中的空闲页。 #### 创建新表的过程 当创建新表时,InnoDB初始分配32页的碎片页用于存放数据。这些页被称为“预分配”页。一旦这32页被...
同时使用一种 -- next-key locking 的锁策略来避免幻读现象的产生,还提供了插入缓冲(insert buffer) 二次写(double write) 自适应哈希索引,预读(read ahead)等高性能和高可用的功能。对于表中的数据innodb...
在解析过程中,Innodb文件格式分析器会识别出各种页类型,如系统页、分配地图页、B树页、插入缓冲头页等。对于B树页,它会显示页的层级、左邻右舍页的信息,以及B树节点中的键值顺序,这对于理解索引结构及其查找...
- **缓冲池大小**:增大InnoDB的缓冲池大小可以显著提升插入性能,尤其是在大量数据插入时效果更加明显。 - **自动提交**:关闭自动提交模式可以进一步提升InnoDB的插入性能,这是因为每执行一次INSERT操作时不需要...
- 插入一条记录时,InnoDB通常会首先将新数据放入缓冲池(Buffer Pool),然后再异步刷新到磁盘,因此在大多数情况下不会立即产生物理I/O读操作。 - 更新操作同样会尽可能利用缓冲池来减少物理I/O操作。 5. **Merge...