InnoDB数据结构

InnoDB数据结构


1.底层结构

底层结构主要由内存结构磁盘结构组成。

1.1 内存结构

1.1.1 Buffer Pool(缓冲池)

缓冲池是主内存中的一块区域,InnoDB在访问表和索引数据时候会在其中进行缓存。缓冲池允许直接从内存中处理经常使用的数据。
缓存的单位是页,使用**LRU算法**的变体会将很少使用的数据从缓存中老化掉。
缓冲池使用最近最少使用LRU算法的变体对缓冲数据的列表进行管理,安装**5:3**的比例将缓冲池空间划分为年轻代和老年代。
年轻代的头部是经常被访问的数据,老年代尾部是很少被访问的数据。

缓冲池缓存表数据和索引数据,把磁盘中的数据加载到缓冲池中,避免每次都进行磁盘IO,起到加快访问的作用。
1.缓冲池是一种常见的降低磁盘访问的机制
2.缓冲池通常以页为单位缓存数据,缓存最热的数据页和索引页
3.缓冲池的常见管理算法是LRU,并且InnoDB对普通LRU进行了优化


1.1.2 Change Buffer(写缓冲)
MySQL5.5之前本身叫插入缓冲,只对insert做了优化,而现在对delete和update都有效,因而叫写缓冲。

Change Buffer写缓冲是缓存那些不在Buffer pool里的辅助索引的变化的特殊数据结构。
负责索引发生改变时,如果辅助索引在Buffer pool中就会直接修改;如果不在则由Change Buffer先缓存这些辅助索引的变更动作,等未来辅助索引被读取时,再将数据合并恢复到缓冲池中的技术。
在内存中,Change Buffer是缓冲池的一个组成部分,在磁盘上,Change Buffer是system tablespace(系统表空间)的一部分,当数据库宕机时,索引的变更会被缓冲到磁盘的Change Buffer区域。

写缓冲的目的是降低写操作的磁盘IO,提升数据库性能
1.写缓冲只有在要修改的辅助索引页不在buffer pool内时,才会将写入操作缓存在Change Buffer
2.定期对写辅助索引页的changes buffer进行合并,写入到Buffer pool中
3.Change Buffer既包含内存结构,也包含磁盘结构,
内存中的Change Buffer主要是缓冲辅助索引的变更操作,以便对变更操作进行合并,提高对辅助索引的修改效率;
磁盘中的Change Buffer主要是数据库宕机时,将辅助索引的变更操作缓冲到磁盘的Change Buffer区域


> 为什么Change buffer只对辅助索引生效? 以插入为例,插入顺序一般是按照主键递增的顺序插入的,**插入聚集索引(主键索引)一般是顺序的,不需要磁盘的随机读取**。这种情况下对聚集索引的修改速度是非常快的,所以不需要进行写缓冲。 而对于辅助索引的插入或者更新操作,由于B+树的索引结构特性决定了辅助索引插入的离散型,所以辅助索引的插入或者更新操作,InnoDB中不是每次都直接插入索引页,而是先判断插入的辅助索引是否在缓冲池中,在就直接插入,不在则先放在change buffer中,然后以一定的频率和情况下进行change buffer和辅助索引页子节点的merge操作,这时候能将多个插入合并到一个操作中(因为在同一个索引页),就能够大大提高了辅助索引插入性能。

1.1.3 Adaptive Hash Index(自适应哈希索引)

InnoDB存储引擎会监控对表上各索引页的查询,如果观察到建立hash索引可以提高查询速度,则自动建立哈希索引,这就是自适应哈希索引(AHI)
AHI是通过缓冲池的B+树页构造而来的,因此建立速度很快,而且不需要对整张表构建hash索引
InnoDB存储引擎会自动根据访问的频率和模式来自动的为某些热点也建立hash索引
InnoDB的自适应哈希索引,就像"索引的索引",目的是为了加速索引寻路
哈希索引只能用来搜索等值的查询


1.1.4 Log Buffer(日志缓冲区)
日志缓冲区是用于保存要写入磁盘上的日志文件数据的内存区域,
其大小由innodb_log_buffer_size变量定义,默认大小16MB,
innodb_flush_log_at_trx_commit变量控制如何将日志缓冲区的内容写入并刷新到磁盘
innodb_flush_log_at_timeout变量控制日志刷新频率

日志缓冲区的内容定期刷新到磁盘,较大的日志缓冲区使大型事务可以运行,而无需在事务提交之前将redo日志数据写入磁盘。所以当有更新、插入或者删除许多行的事务,增加日志缓冲区的大小可以节约磁盘I/O。

为什么要有Log Buffer?
事务提交之后,必须将事务对数据页的修改刷(fsync)到磁盘上,才能保证事务的ACID特性
这个刷盘,是一个随机写,随机写性能较低,每次事务都提交刷盘会极大影响数据库的性能
日志缓冲区使大型事务可以运行,无需在事务提交之前将redo日志写入磁盘,节省了磁盘I/O

Log Buffer刷写的三种策略:



MySQL事务提交刷redo log有三种策略:innodb_flush_log_at_trx_commit
(1)0:每秒写入一次日志并将其刷新到磁盘。尚未刷新的事务可能会在奔溃中丢失。
(2)1:要完全符合ACID,必须使用默认设置1。日志在每次事务提交时写入并刷新到磁盘。
(3)2:日志在每次事务后写入,并每秒刷新一次到磁盘。尚未刷新日志的事务可能在崩溃中丢失

高并发业务,行业最佳实践是使用第三张折中配置(=2),这是因为:
(1)配置为2和配置为0,性能差异不大,因为将数据从Log Buffer拷贝到OS cache,虽然跨越用户态和内核态,但毕竟是内存的数据拷贝,速度很快
(2)配置为2和配置为0,安全性差异巨大,操作系统崩溃的概率相比MySQL应用程序崩溃的概率小很多,设置为2,操作系统不奔溃就绝对不会丢数据
innodb_flush_log_at_trx_commit=2


总结 InnoDB引擎的结构

1.InnoDB引擎的结构分为内存结构和磁盘结构
2.内存结构由缓冲池(Buffer Pool)、写缓冲(Change Buffer)、自适应哈希索引(Adaptive Hash Index)、日志缓冲(Log Buffer)组成
3.缓冲池(Buffer Pool)主要是缓存表数据和索引数据,加快访问速度。内部基于LRU算法来管理缓存对象
4.写缓冲(Change Buffer)主要是缓存辅助索引的变更操作,加快辅助索引的更新速度
5.日志缓冲(Log Buffer)使得大型事务可以允许,无需在事务提交之前将redo日志数据写入磁盘,节省磁盘I/O。注意事务提交时有三种redo策略

posted @ 2024-03-05 20:08  Kris_Chen  阅读(278)  评论(0)    收藏  举报