InnoDB存储引擎
最近在找工作,复习到MySQL这块知识记录一下。目前面临问题是对这块知识理解割裂,不能将所有知识点进行有效串联,希望通过此次整理,以后复习能够快速回忆,此次主要是记录对存储引擎InnoDB的理解。
这里有一张mysql的整体结构图。
InnoDB体系架构
上面这张图简单的显示了InnoDB的存储引擎体系架构。
后台线程
后台线程分为了Master线程、IO线程、Purge线程
master线程:主要负责将**缓冲池中数据异步刷新到磁盘,保证数据一致性,包括脏页刷新、合并插入缓存、Undo页的回收**等
IO线程:InooDB引擎大量使用AIO处理IO请求,IO线程主要是负责这些IO的回调处理,1.0之前主要有4个IO线程,write、read、insert buffer、log IO Thread
Purge线程:事务被提交后,其所使用的undolog可能不再需要,因此需要PurgeThread来**回收已经使用并分配的undo页**
疑问:不是Master线程也有Undo页的回收吗,为啥purge线程也是对undo页的回收?
答:purge线程是为了减轻Master线程的压力,在1.1版本独立到单独线程执行的
内存
内存分为缓存池、redo log buffer、额外的内存池
缓冲池:一块内存区域,通过内存的速度来弥补磁盘速度较慢对数据库性能的影响。
问题:
-
如果数据更新,缓冲页中数据如何更新?
答:数据更新会先写入到redo log,然后再更新缓冲池里数据,最后再以一定的频率刷新到磁盘上
2.什么时机触发缓冲刷新到磁盘?
答:并不是页发生更新就触发刷新到磁盘,而是**采用了一种checkPoint的机制**,目的是为了提高整体性能
3.查询缓存和缓冲池是一个东西吗?
答:不是,查询缓存是对查询语句的结果集进行缓存,缓冲池是一个重要组件,主要是对存储数据页的数据进行缓存
4.缓存池缓存主要数据页类型?
答:索引页、数据页、undo页、插入缓冲、自适应哈希索引、InnoDB存储的锁信息、数据字典信息等。
5.InnoDB如何对缓冲池进行管理
答:使用LRU List、Free List、Flush List。LRU列表用来管理已经读取的页。但数据库刚启动时,LRU列表是空的,所有的页都存放在Free列表中。当LRU列表中的页被修改后,**该页称为脏页,使用Flush列表管理。**脏页既可以存在于LRU列表,也可以存在于Flush列表,相互之间没有关联。
redo log buffer:先将重做日志信息先放入到这个缓冲区,然后按一定频率将其刷新到重做日志文件,可以通过参数配置,默认8M
问题:
1.什么时机触发缓冲刷新到磁盘?
答:1.Master 线程每秒都会将redo log buffer刷新到重做日志文件
2.每个事务提交时会将重做日志刷新到重做日志文件
3.重做日志缓冲池剩余空间小于1/2时,会进行刷新
额外的内存池:在对一些数据结构本身的内存进行分配时,需要从额外的内存池中进行申请,当该区域的内存不够时,会从缓冲池中进行申请
Checkpoint技术
解决什么问题的:
- 缩短数据库的恢复时间
- 缓冲池不够用时,将脏页刷新到磁盘
- 重做日志不可用时,刷新脏页
问题:
-
checkpoint为啥能缩短数据库恢复的时间?
答:当数据库宕机后,只需要将checkpoint后的重做日志进行恢复即可
-
如何理解重做日志不可用,刷新脏页?
答:当前数据库对重做日志都是设计的循环使用,当数据库宕机时,某部分重做日志是不需要的,既为可覆盖,该部分重做日志不可用,若重做日志还需要使用,那么必须强制产生checkpoint,缓冲池的数据至少刷新到当前重做日志的位置。
InnoDB关键特性
插入缓冲(Insert Buffer)、两次写(Double Write)、自适应哈希索引(Adaptive Hash Index)、异步IO(Async IO)、刷新邻接页(Flush Neighbor Page)
插入缓冲
问题:
-
刚刚上面了解了缓冲池,那么插入缓冲和缓冲池有啥关系吗?
答:是两个不同的概念。
-
什么是插入缓冲?
答:插入缓冲是为了提高非聚簇索引插入性能的。对于非聚簇索引的插入和更新,不是每次都直接插入到索引页中,会先判断是否在于缓冲池中,若在,直接插入;不在则先放进Insert Buffer对象中。看似非聚簇索引已经插入到叶子节点,实际上没有。以一定频率和情况进行Insert Buffer和非聚簇索引叶子节点的合并操作,这时通常能将多个插入合并到一个操作中。
-
如果插入缓冲还没合并到索引页发生了宕机,怎么办?
答:这时恢复数据是需要很长时间,极端情况要几个小时。
两次写
两次写保证的是数据页的可靠性
问题:
-
没有两次写会有什么问题?
答:当InnoDB正在写入某页到表中,刚写道一半,发生了宕机,这种情况称为部分写失效,没有两次写时,会导致数据丢失
-
问题1的情况不能使用redo log进行恢复吗?
答:重做日志记录的是对页的物理操作,如偏移量800,写‘aaa’记录。但是这个页本身已经损坏了,对其重做意义不大。因此需要在重做日志恢复前将页还原,这就需要一个之前页的副本。
-
两次写实现原理
答:两次写由两部分组成,内存中的doublewrite buffer、磁盘上共享表空间中连续的128个页(两个区),两部分大小都是2M。缓冲池的脏页刷新时,并不直接写磁盘,先复制到内存中doublewrite buffer,然后通过将doublewrite buffer分两次写入共享表空间的物理磁盘,然后同步磁盘,避免缓冲写带来的问题。在完成doublewrite 页的写入后,再将doublewrite buffer中的也写入各个表空间文件中
自适应哈希索引
自适应哈希索引是InnoDB自动创建的,InnoDB会监控表的各索引页的查询,如果发现建立哈希索引可以带来性能上的提示,则建立哈希索引
异步IO
为了提高磁盘操作性能,采用异步IO(Asynchronous IO,AIO)的方式来处理磁盘操作
刷新邻接页
当刷新一个脏页时,InnoDB存储引擎会检测该页所在区(extent)的所有页,如果是脏页,那么一起进行刷新