InnoDB Insert抖动问题及其改进

简介:

背景

日志型应用的一个典型操作,是周期性地有大量的insert操作。这类操作需要对扩展表空间。

分析

InnoDB里,扩展表空间的操作是在语句执行过程中,由执行线程直接调用的。

尤其是对于一些表每行比较大,则会出现每插入几条记录就需要扩展表空间。

虽然有insert buffer和write ahead logging策略保证在执行线程中不直接操作表数据文件,但扩展表空间的操作会导致更新的tps出现瞬间低点。现象如下图。实际上整体TPS也受此影响。

改进方案及可行性

可以在这类大操作之前预分配表空间来优化这个问题。我们的业务上线之前都有容量预估,每天也有监控。因此接下来一段时间表空间增长到多少,是能够预估得到。

在实际更新开始之前,在低峰期甚至是提供服务之前就将表空间预分配好,能够避免这种抖动和提高TPS

工具验证

InnoDB的表空间结构上,空间头部有4byte的数字N表示这个表空间的大小(page数目),文件的实际大小是N*Page_SIZE.

实现了一个工具extend_space,修改4byte并将文件append到指定的大小。测试发现insert性能提升10%。由这个原因引起的抖动消除。

后续

目前还只是用工具实现。工具使用起来比较麻烦,主要是更新过程中的锁表操作就需要外部脚本,而且以后应用的新版本中page_size可变,因此比较优美的方案是将这个功能加入到MySQL支持的命令中。

补充更新

新增MySQL命令支持预扩展

http://bugs.mysql.com/bug.php?id=63858

效果如图

目录
相关文章
|
关系型数据库 MySQL 索引
MySQL InnoDB中的锁-插入意向锁(Insert Intention Lock)
MySQL InnoDB 插入意向锁 Insert Intention Lock
3084 0
MySQL InnoDB中的锁-插入意向锁(Insert Intention Lock)
|
存储 关系型数据库 MySQL
MySQL InnoDB的插入缓冲Insert Buffer
MySQL InnoDB的插入缓冲Insert Buffer
134 0
MySQL InnoDB的插入缓冲Insert Buffer
|
索引 关系型数据库 存储
InnoDB,select为啥会阻塞insert?
MySQL的InnoDB的细粒度行锁,是它最吸引人的特性之一。
673 0
|
存储 关系型数据库 索引
select,InnoDB为啥会阻塞insert?
MySQL的InnoDB的细粒度行锁,是它最吸引人的特性之一。
1450 0
|
1月前
|
存储 关系型数据库 MySQL
MySQL InnoDB数据存储结构
MySQL InnoDB数据存储结构
|
1月前
|
存储 缓存 关系型数据库
MySQL的varchar水真的太深了——InnoDB记录存储结构
varchar(M) 能存多少个字符,为什么提示最大16383?innodb怎么知道varchar真正有多长?记录为NULL,innodb如何处理?某个列数据占用的字节数非常多怎么办?影响每行实际可用空间的因素有哪些?本篇围绕innodb默认行格式dynamic来说说原理。
832 6
MySQL的varchar水真的太深了——InnoDB记录存储结构
|
3月前
|
存储 SQL 关系型数据库
系统设计场景题—MySQL使用InnoDB,通过二级索引查第K大的数,时间复杂度是多少?
系统设计场景题—MySQL使用InnoDB,通过二级索引查第K大的数,时间复杂度是多少?
46 1
系统设计场景题—MySQL使用InnoDB,通过二级索引查第K大的数,时间复杂度是多少?