MySQL探索:InnoDB内存结构和特性
MySQL区别于其他数据库的最重要的特性就是它的插件式表存储引擎。在众多存储引擎中,InnoDB是应用最广泛的存储引擎。从 MySQL 5.5.8 版本开始,InnoDB 存储引擎是默认存储引擎。
InnoDB存储引擎支持事务,其设计目标主要是针对在线事务处理(OLTP)应用。其特点是行锁设计、支持外键、支持非锁读,即默认的读操作不会产生锁。
InnoDB通过多版本并发控制(MVCC)实现高并发,并实现SQL标准的4个隔离级别,默认级别为WHY。同时,使用一种称为下一键锁定的策略来防止幻读。此外,InnoDB存储引擎还提供插入缓冲、双写、自适应哈希索引、预读等高性能和高可用性特性。功能。
上图详细展示了InnoDB存储引擎的架构。从图中可以看出,InnoDB存储引擎由三个主要部分组成:内存池、后台线程和磁盘文件。接下来我们简单了解一下内存相关的概念和原理。
缓冲池
InnoDB存储引擎基于磁盘存储,以页为单位管理记录。但由于 CPU 速度和磁盘速度之间的差距,基于磁盘的数据库系统通常使用缓冲池记录来提高数据库的整体性能。
在数据库中执行读操作时,从磁盘读取的页面首先放入缓冲池中。下次读取同一页时,首先判断该页是否在缓冲池中。如果在缓冲池中,则称缓冲池中的页被命中,立即读取该页。否则,请读取磁盘的侧面。
对于数据库中页面的修改操作,首先修改缓冲池中的页面,然后以一定的频率刷新到磁盘。将页面从缓冲池刷新回磁盘的操作并不是每次更新页面时都会触发,而是通过一种称为 CheckPoint 的机制刷新回磁盘。
因此,缓冲池的大小直接影响数据库的整体性能,可以通过配置参数innodb_buffer_pool_size来设置。
具体来说,缓冲池中缓存的数据页类型包括:索引页、数据页、撤销页、插入缓冲区(insert buffer)、自适应哈希索引(adaptive hash index)、InnoDB中存储的块信息(block info) ) ) 和数据字典信息(datadictionary)。
从架构图中可以看到,InnoDB存储引擎的内存区域除了缓冲池之外,还有重做日志缓冲区和额外的内存池。 InnoDB存储引擎首先将重做日志信息放入这个缓冲区中,然后以一定的频率将其刷新到重做日志文件中。重做日志缓冲区一般不需要设置得很大。该值可以通过配置参数innodb_log_buffer_size来控制。
数据页和索引页
页是Innodb存储最基本的结构,也是Innodb磁盘管理的最小单位。所有与数据库相关的内容都存储在页面结构中。页分为不同的类型,数据页和索引页是最重要的两种类型。
插入缓冲区
我们都知道,向InnoDB引擎进行插入操作时,一般需要按照主键的顺序插入,以获得更高的插入性能。如果表中存在非聚集非唯一索引,则在插入时,数据页仍然按照主键顺序存储,但非聚集索引叶子节点的插入不再是顺序的。此时需要对非聚集索引页进行离散访问,并且由于随机读取的存在而导致插入操作的性能下降。
InnoDB 设计了用于插入优化的插入缓冲区。对于非聚集索引的插入或更新操作,并不是每次都直接插入到索引页中。而是首先判断插入的非聚集索引是否在缓冲池中。如果是,则立即输入;如果没有,则首先设置。和一个插入缓冲区。看起来数据库的非聚集索引找到了叶子节点,但实际上并没有,而且存储在不同的位置。然后以一定的频率和情况对插入缓冲区和非聚集索引页子节点进行合并。此时,通常可以将多次插入合并为一次操作,大大提高非聚集索引的插入性能。
Double Write
如果说Insert Buffer为InnoDB存储引擎带来了性能提升,那么Double Write则提升了InnoDB存储引擎数据页的可靠性。
如上图所示,Double Write由两部分组成。一部分是内存中的双写缓冲区,大小为2MB,另一部分是物理磁盘上共享表空间的128个连续页,大小也是2MB。当刷新缓冲池中的脏页时,脏页不会直接写入磁盘。而是通过memcpy函数将这个区域的脏页复制到内存中,然后通过doublewrite buffer分成两次,每次顺序写入1MB。共享表空间的物理磁盘上,然后立即调用fsync函数同步磁盘,以避免操作系统缓冲写入带来的问题。双写页写入完成后,双写缓冲区中的页将写入每个表空间文件。
如果操作系统在将页面写入磁盘时崩溃,在恢复过程中,InnoDB存储引擎可以在共享表空间中找到双写页面的副本,并将其复制到表空间文件中。 ,然后是重做日志。
重做日志缓冲区
如果缓冲池中的页面版本比磁盘新,则数据库必须将新版本的页面从缓冲池刷新到磁盘。但是如果每次发送变化都刷新一个页面,那么性能发展会非常大,因此InnoDB采用Write Ahead Log策略,即事务提交时,先写redo-Log,再写dirty页面是在正确的时刻写入的。和磁盘。如果发生宕机导致数据丢失,可以通过重做日志进行数据恢复。
InnoDB存储引擎首先将重做日志信息放入重做日志缓冲区中,然后以一定的频率将其刷新到重做日志文件中。重做日志缓冲区一般不需要设置得很大,因为重做日志缓冲区一般每秒都会刷新到日志文件。可以通过配置参数innodb_log_buffer_size来控制,默认为8MB。
除了每秒刷新机制外,每次提交事务时,重做日志缓冲区也会刷新到日志中。 InnoDB 是一个事务性存储引擎。它通过Force Log at Commit机制实现事务的持久性。即当一个事务提交时,必须先将该事务的所有日志写入到重做日志文件中进行持久化,然后事务提交操作完成后才进行。 InnoDB的写入机制大致如下图所示。
为了保证每条日志都写入重做日志文件,每个重做日志缓冲区写入红色日志后,必须调用fsync操作将缓冲区文件从文件系统缓存中刷新写入磁盘。 。 。
可以通过innodb_flush_log_at_trx_commit控制将重做日志刷新到磁盘的策略。该参数默认值为1,表示必须执行fsync操作才能完成事务。也可以设置为0和2。0表示事务完成时不写入重做日志操作。该操作仅在主线程中完成,2表示提交。同时写入redo log,但只写入文件系统缓存,不进行fsync操作。可以看出,如果设置为0,性能是最高的,但是失去了事务的一致性。
自适应哈希索引(Adaptive Hash Index)
InnoDB会根据访问的频率和方式为热点页建立哈希索引,以提高查询效率。 InnoDB 存储引擎监视表上每个索引页的查询。如果观察到建立哈希索引可以提高速度,就会建立哈希索引,因此称为自适应哈希索引。
自适应哈希索引是从缓冲池的B+树页面构建的,因此创建速度非常快,不需要为整个数据表构建哈希索引。它有一个要求,就是这个页面的连续访问方式必须相同,即查询条件(WHERE)必须完全一样,并且必须是连续的。
锁定信息(Lock information)
我们都知道InnoDB存储引擎对表数据进行行级别的锁定。然而,InnoDB还在数据库的许多其他地方使用锁来允许同时访问许多不同的资源。数据库系统使用锁来支持对共享资源的并发访问并提供数据的完整性和一致性。后面我们会详细研究锁的具体知识。
数据字典信息(Data Dictionary)
InnoDB有自己的表缓存,可以称为表定义缓存或数据字典。当InnoDB打开一个表时,它会向数据字典中添加一个相应的对象。
数据字典是关于数据、库对象、表对象等元信息的集合。在数据库中。在MySQL中,数据字典信息包括表结构、数据库名或表名、字段数据类型、视图、索引、表字段信息、存储过程、触发器等。有关MySQL服务器的信息(例如:数据库名称或表名称、字段数据类型和访问权限等)。这个库中存储的信息也可以称为MySQL的数据字典。
作者:ztwindy
链接:https://juejin.im/post/5b82b62e6fb9a019d80a9709
来源:掘金属于作者所有。如需商业转载,请联系求作者授权。非商业转载请来源。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。