组成:
- 连接池组件
- 管理服务和工具组件
- SQL接口组件
- 查询分析器组件
- 优化器组件
- 缓冲(Cache)组件
- 插件式存储引擎
- 物理文件
InnoDB存储引擎
行锁设计,支持MVCC、支持外键、提供一致性非锁定读、
InnoDB体系结构
一、后台线程
1、Master线程
将缓冲池中的数据异步刷到磁盘,保证数据一致性,包括脏页刷新、合并插入缓冲、UNDO页回收;
2、IO线程
将IO请求回调 处理;
参数innodb_read_io_threads/innodb_write_io_threads
3、Purge Thread
回收使用并分配的undo页;
参数:innodb_purge_threads
4、Page cleaner Thread
脏页的刷新操作
二、内存
1、缓冲池
将页读入缓冲,修改后通过checkpoint机制写回磁盘
参数:innodb_buffer_pool_size
缓冲池中的数据页类型有:索引页、数据页、UNDO页、插入缓冲(insertbuffer)、自适应哈希、锁信息、数据字典等
可配置多个缓冲实例,参数: innodb_buffer_pool_instances=1
2 、LRU List , Free List:
缓冲池管理算法:LRU
LRU:频繁使用的页在前端,少使用的页在后端;
最新访问的不是放到LRU列表的最前面,而是有midpoint,约5/8处,由参数innodb_old_blocks_pct控制,默认37;
innodb_old_blocks_time,页读取midpoint后多久才会加入到LRU列表的热端;
数据库启动时,LRU List为空,页存放在Free List里面;
3、重做日志缓冲(redo log buffer):
不需要很大,保证每秒产生和事务量在缓冲大小之内即可;
参数:innodb_log_buffer_size=8M
重做日志缓冲在以下情况刷到磁盘的重做日志中:
• Master Thread每秒刷;
• 每个事务提交时;
• 重做日志缓冲空间小于1/2时
4、额外的内存池:
记录LRU、锁、等待等信息
三、Checkpoint技术
解决以下问题:
• 缩短数据库恢复时间 ;
• 缓冲池不够时,把脏页刷到磁盘;
• 重做日志不可用时,刷新脏页
checkpoint的时机?
参数:innodb_max_dirty_pages_pct=75,当脏页达到75%时,强制进行checkpoint;
四、Master Thread工作方式
1、1.0.x版本之前
master线程内部由多个循环组成:主循环loop,后台循环backgroup loop,刷新循环flush loop和暂停循环suspend loop;
主循环包括两个操作:每秒操作和每10秒操作;
每秒操作包括:
• 日志缓冲刷新到磁盘,即使事务没有提交(总是);
• 合并插入缓冲(可能);
• 至少刷新100个innodb缓冲中的脏页到硬盘(可能);
• 如果当前用户没有活动,切换到backgroup loop(可能);
每10秒的操作:
• 刷新100个innodb缓冲中的脏页到硬盘(可能的情况下);
• 合并至少5个插入缓冲(总是);
• 将日志缓冲刷新到磁盘(总是);
• 删除无用的Undo页(总是);
• 刷新100个或10个脏页到磁盘(总是);
backgroup loop:
• 删除无用的Undo页(总是);
• 合并20个插入缓冲(总是);
• 跳回主循环(总是);
• 不断刷新100个页直到符合条件(总是,可跳转到flush loop中完成);
2、1.2x版本之前
增加innodb_io_capacity的百分比来控制脏页数量和插入缓冲数量;
合并插入缓冲时,数量为innodb_io_capacity的5%;
刷新脏页的数量是innodb_io_capacity
show engine innodb status
3、1.2.x版本
刷新脏页的操作,分离出一个新的Page Cleaner Thread来进行;
五、innodb的关键特征
• 插入缓冲(insert buffer)
• 两次写(double write)
• 自适应哈希索引(Adaptive Hash Index)
• 异步IO(Async IO)
• 刷新邻接页(Flush Neighbor Page)
1、插入缓冲(insert buffer):
insert buffer和数据页一样,是物理页的组成部分;
对于非聚集索引的插入或更新操作,不是每一次都插入索引页中,而是判断插入的非聚集索引页是否在缓冲池,如果在,则直接插入;若不在,则放在一个Insert Buffer对象中;
需要满足下列条件才能使用:
• 索引是辅助索引(Secondary Index);
• 索引不是唯一的;
1.2.x版本后:
Change buffer:包括Insert buffer,delete buffer,purge buffer
对应插入更新删除操作;
参数:innodb_change_buffering
取值为:inserts deletes purges change all none,默认为all
参数:innodb_change_buffer_max_size
change buffer的最大内存数
2、两次写
doublewrite
由两部分组成:内存中2MB的doublewrite buffer,k另一部分是物理磁盘共享表空间中的连续128个页,即2个区(EXTEND)
过程:在对缓冲池中的脏页刷新时,先通过memcpy函数把脏页先复制到内存中的doublewrite buffer,之后通过doublewrite buffer再分两次,每次1MB写入到共享表空间中,接上马上调用fsync函数同步磁盘,避免写缓冲带来的问题;
观察命令:
show global status like ‘innodb_dlwr%’
3、自适应哈希索引
innodb会监控对表上各索引页的查询,如果观察到建立自适应哈希索引可以带来速度的提升,则建立哈希索引,称为自适应哈希索引;
结构:B+树
AHI的要求:对这个页的访问必须是连续的,如对于(a,b)这样的联合索引,其访问形式可以是以下情况:
• WHERE a=xxx
• WHERE a=xxx AND b=xxx
访问形式是指查询的条件一样,若交替进行上面的查询,不会建立AHI,另外,还有以下要求:
• 以该模式访问了100次;
• 页通过该模式访问了N次,N=页中的记录*1/16;
show engine innodb status进行观察
控制参数:innodb_adaptive_hash_index
4、刷新邻接页
当刷新脏页时,会检查该页所在区(EXTEND)的所有页,如果有脏页,就一起刷新;
控制参数:innodb_flush_neighbors
参考《MySQL技术内幕 -InnoDB存储引擎》整理,如侵权请联系vinin@163.com。