MySQL 篇-深入了解 InnoDB 引擎的逻辑存储结构、架构、事务原理、MVCC 原理分析(RC 级别、RR 级别)-        2.0 InnoDB 引擎 - 架构

时间:2024-10-14 14:56:35

        MySQL 5.5 版本开始,默认使用 InnoDB 存储引擎,它擅长事务处理,具有崩溃恢复特性,在日常开发中使用非常广泛。

下面时 InnoDB 架构图,左侧为内存结构,右侧为磁盘结构:

        2.1 InnoDB 引擎 - 内存结构

        1)Buffer Pool:缓冲区是主内存中的一个区域,里面可以缓存磁盘上经常操作的真实数据,在执行增删改查操作时,先操作缓冲区中的数据,若缓冲区没有目标数据,则从磁盘加载并缓存,然后再以一定频率刷新到磁盘,从而减少磁盘 I/O,加快处理速度。

        缓冲池以 Page 页为单位,底层采用链表数据结构管理 Page,根据状态,将 Page 分为三种类型:

        - free page:空闲 page,未被使用。

        - clean page:被使用 page,数据没有被修改过。

        - dirty page:脏页,被使用 page,数据被修改过,页中数据与磁盘数据产生不一致,因此,缓冲池会以一定的频率将数据刷新到磁盘中,以保证数据一致性。

        2)Change Buffer:更改缓冲区(针对于非唯一的二级索引页),在执行 MDL 语句时,如果这些数据 Page 没有在 Buffer Pool 中,不会直接操作磁盘,而会将数据变更存放到更改缓冲区 Change Buffer 中,在未来数据被读取时,再将数据合并恢复到 Buffer Pool 中,再将合并后的数据刷新到磁盘中。

        Change Buffer 的意义是什么?

        与聚集索引不同,二级索引通常是非唯一,并且以相对随机的顺序插入二级索引。同样,删除和更新可能会影响索引树种不相邻的二级索引页,如果每一次都操作磁盘,会造成大量的磁盘 IO,有了 Change Buffer 之后,就可以在缓冲池中进行合并处理,减少磁盘 IO 。

        3)Adaptive Hash Index:自适应 hash 索引,用于优化对 Buffer Pool 数据的查询。InnoDB 存储引擎会监控对表上各索引页的查询,如果观察到 hash 索引可以提升速度,则建立 hash 索引,称之为自适应 hash 索引。

        自适应哈希索引,无需人工干预,是系统根据情况自动完成。

        4)Log Buffer:日志缓冲区,用来保存要写入到磁盘中的 log 日志数据(redo log、undo log),默认大小为 16 MB,日志缓冲区的日志会定期刷新到磁盘中。如果需要更新、插入或删除许多行的事务,增加日志缓冲区的大小可以节省磁盘 IO。

        相关的参数:

        - innodb_log_buffer_size(缓冲区大小)

        - innodb_flush_log_trx_commit(日志刷新到磁盘时机):设置为 1,代表日志在每次事务提交时写入并刷新到磁盘;设置为 0,每秒将日志写入并每秒刷新到磁盘一次;设置为 2,日志在每次事务提交后写入,并每秒刷新到磁盘一次。

        2.2 InnoDB 引擎 - 磁盘结构

        1)undo Tablespaces:撤销表空间,MySQL 实例在初始化时会自动创建两个默认的 undo 表空间(初始大小 16 M),用于存储 undo log 日志。

        2)Temporary Tablespaces:InnoDB 使用会话临时表空间和全局临时表空间。存储用户创建的临时表等数据。

        3)Doublewrite Buffer Files:双写缓冲区,InnoDB 引擎将数据页从 Buffer Poll 刷新到磁盘前,先将数据页写入双写缓冲区文件中,便于系统异常时恢复数据。

        4)Redo log:重做日志,是用来实现事务的持久性,该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log),前者是在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都会存到该日志中,用于在刷新脏页到磁盘时,发生错误时,进行数据恢复使用。

        以循环方式写入重做日志文件,涉及两个文件:ib_logfile0、ib_logfile1 。

        2.3 InnoDB 引擎 - 后台线程

        将数据从缓冲区写入到磁盘中,会用到后台线程:

        1)Master Thread:核心后台线程,负责调度其他线程,还负责缓冲池中的数据异步刷新到磁盘中,保持数据的一致性,还包括脏页的刷新、合并插入缓存、undo 页的回收。

        2)IO Thread:在 InnoDB 存储引擎中大量使用了 AIO 来处理 IO 请求,这样可以极大地提高数据库的性能,而 IO Thread 主要负责这些 IO 请求的回调。

        3)Purge Thread:主要用于回收事务已经提交了的 undo log,在事务提交之后,undo log 可能不用了,就用它来回收。

        4)Page Cleaner Thead:协助 Master Thread 刷新脏页到磁盘的线程,它可以减轻 Master Thread 的工作压力,减少阻塞。