2.3 InnoDB体系结构
2.31 后台线程
1.Master thread
2.IO thread
3.Purge thread
4.Page Cleaner Thread
2.32内存
1.缓冲池
2.LRU List,Free List 和Flush List
1.LRU算法的作用?
通常来说,数据库中的缓冲池是通过LRU算法来进行管理的,LRU算法即为Latest Recent Used,最近最少使用算法。我们通常的做法是将最频繁使用的页放在LRU列表的前端,最少使用的页放在LRU列表尾端。
2.InnoDB存储引擎的LRU算法与普通LRU算法的区别?
在InnoDB的存储引擎中,新访问的页将会放到"midpoint"位置中而不是传统的LRU尾部。这个midpoint位置在LRU列表长度的5/8处,midpoint之前的列表称为new列表,之后的称为old列表。
3.为什么要采用这个midpoint的算法?
因为若直接将读取到的页放入到LRU的首部,那么某些SQL操作可能会使缓冲池中的页被刷新出,从而影响缓冲池的效率,常见的有作为索引或数据的扫描操作。
简单来说,就是如果你把这个页放在LRU的首部,这个时候你查询了一下这个页,那么这个页就被放回磁盘中了,如果下一步你要做一些添删改查的操作时就会非常耗费时间。
4.那么什么时候把页放入到new列表
有个参数innodb_old_blocks_time,用于表示页读取到mid位置后需要等待多久才会被加入到LRU列表的new列表。
5.脏页
3.重做日志缓冲
4.额外的内存池
2.4 checkpoint 技术
1.checkpoint技术的作用?
将脏页从缓冲池刷新到磁盘
2.checkpoint的分类?
innodb引擎内部,有两种checkpoint
sharp Checkpoint--发生在数据库关闭时将所有的脏页都刷新回磁盘。
Fuzzy Checkpoint--在数据库运行时进行页的刷新
其中Fuzzy Checkpoint又分为4种情况的Fuzzy Checkpoint
- Master Thread Checkpoint--以每秒或每十秒的速度从缓冲池的脏页列表中刷新一定比例的页回磁盘
- Flush_LRU_LIST Checkpoint--innodb引擎检查是否有足够的空闲页供用户使用,若没有足够的空闲页,则innodb会把LRU列表尾端的页移除。如果这些移除的页有脏页,那么进行这个Checkpoint
- Async/Sync Flush Checkpoint--当重做日志文件不可用,这时会强制将一些页刷新回磁盘,而此时脏页是从脏页列表中选取的
- Dirtty Page too much Checkpoint--脏页数量太多,innodb引擎强制进行checkpoint
2.5 Master Thread工作方式
2.5.1 innodb 1.0.x 版本之前的Master Thread
Master Thread 具有最高的线程优先级别,其内部由多个loop组成:
1.主循环 loop
2.后台循环 backgroup loop
3.刷新循环 flush loop
4.暂停循环 suspend loop
下面分别介绍这4个循环
1.主循环 loop
主循环loop有两大部分的操作:
1.每秒钟的操作,操作包括
①日志缓冲刷新到磁盘,即使这个事务还没有提交(总是)
②合并插入缓冲(可能)
③至多刷新100个InnoDB的缓冲池中的脏页到磁盘(可能)
④如果当前没有用户活动,则切换到backgroud loop(可能)
2.每十秒的操作,操作包括:
①刷新100个脏页到磁盘(可能)
②合并至多5个插入缓冲(总是)
③将日志缓冲刷新到磁盘(总是)
④删除无用的undo页(总是)
⑤刷新100个或者10个脏页到磁盘(总是)
2.后台循环 backgroud loop
若当前没有用户活动(数据库空闲时),或者数据库关闭时,就会切换到这个循环
backgroudloop的操作有:
①删除无用的undo页(总是)
②合并20个插入缓冲(总是)
③跳回到主循环(总是)
④不断刷新100个页直到符合条件(可能,跳转到flush loop完成)
若flush loop中也没有什么事情可以做了,innoDB存储引擎会切换到suspend_loop,将Master Thread挂起,等待事件的发生。
2.5.2 InnoDB1.2.x版本之前的Master Thread
这个版本的InnoDB存储引擎相比起1.0x版本之前的,有以下变化:
①在合并插入缓冲时,合并插入缓冲的数量为innodb_io_capacity值的5%
②在从缓冲区刷新脏页时,刷新脏页的数量为innodb_io_capacity
③之前每次进行full merge操作时,最多回收20个undo页,现在可以通过innodb_purge_batch_size对数量进行动态的修改(默认还是20)
2.5.3InnoDB 1.2.x版本的Master Thread
再次对Master Thread进行优化.
对于刷新脏页的操作,从Master Thread线程分离到一个单独的Page Cleaner Thread,从而减轻Master Thread的工作,同时进一步提高了系统的并发性
2.6 InnoDB关键特性
1.插入缓冲
2.二次写
3.自适应哈希索引
4.异步IO
5.刷新邻接页
1.插入缓冲 insert buffer
1.什么是插入缓冲?
插入缓冲:对于非聚集索引(聚集索引-primary key)的插入或更新操作,不是每一次直接插入到索引页中,而是先判断插入的非聚集索引页是否在缓冲池中,若在,则直接插入;若不在,则先放入到一个insert buffer对象中,然后再以一定的频率和情况进行insert buffer和辅助索引页子节点的merge操作,这时通常能将多个插入合并到一个操作中(因为在一个索引页中),这就大大提高了对于非聚聚索引插入的性能
2.插入缓冲满足的条件?
1.索引是辅助索引(secondary index)
2.索引不是唯一的
举例来说,这个例子中的b就满足了这两个条件:
参考以下SQL语句:
create table(
a int auto_increment,
b varchar(30),
primary key(a),
key(b)
);
2.Change Buffer--insert buffer的升级版
change buffer可以对DML操作-insert,delete,update都进行缓冲,他们分别是:insert buffer,delete buffer,purge buffer
和insert buffer一样,change buffer适用的对象依然是非唯一的辅助索引
对一条记录进行update操作可能分为两个过程:
1.将记录标记为删除--delete buffer做的
2.真正将记录删除--purge buffer做的
3.insert buffer的内部实现
1.insert buffer的内部实现
insert buffer的数据结构是一棵B+树,且在全局中只有一棵insert buffer B+树。
而这棵B+树放在共享表空间中,默认也就是ibdatal中。
insert buffer是一棵B+树,由叶子结点和非叶子结点组成,如下图:
1.其中,space,marker,offset称为查询的search key(键值)。
space占用4字节。在innodb存储引擎中,每个表有一个唯一的space id,可以通过space id查询得知是哪张表。
maker占用1字节,用来兼容老版本的insert buffer
offset占用4字节,表示页所在的偏移量
2.前4个构成了B+树的非叶子结点(13字节,metadata占4字节),后面的才是记录了实际插入记录的各个字段。
2.insert buffer bitmap
insert buffer bitmap用来标记每个辅助索引页的可用空间
4.merge insert buffer
1.insert buffer中的记录何时合并到真正的辅助索引中呢?
1.辅助索引页被读取到缓冲池时
2.insert buffer bitmap 页追踪到该辅助索引页已无可用空间时;
3.Master Thread的每秒或每十秒的操作
2.6.2 两次写
如果说insert buffer给innodb引擎带来的是性能上的提升,那么两次写带给innodb引擎的则是数据页的可靠性
1.在对缓冲池中的脏页进行刷新时,先通过memcpy函数(对应图中copy)将脏页先复制到内存中的doublewrite buffer
2.doublewrite buffer分两次,每次1MB顺序地写入共享表空间的物理磁盘上,然后马上调用fsync函数,同步磁盘
3.在完成doublewrite页的写入后,再将doublewrite buffer中的页写入各个表空间文件中。
2.6.3 自适应哈希索引
1.什么是自适应哈希索引?
innodb存储引擎会监控对表上各索引页的查询,如果观察到建立哈希索引可以带来速度提升,则自动建立哈希索引。
2.自动自适应哈希索引的条件?
1.对这个页的连续访问模式相同
2.以该模式访问了100次
3.页通过该模式访问了N次,其中N=页中记录 * 1/16