mysql InnoDB架构
阅读原文时间:2023年07月08日阅读:3

1、InnoDB的磁盘结构

1)系统表空间

2)用户表空间

3)rodolog 文件组

4)磁盘文件逻辑结构

文件->段->区->页->行

InnoDB对数据的存取是以页为单位的,一个数据页默认是16k

2、InnoDB的内存结构

1)buffer pool

1.数据页

2.索引页

3.ChangeBuffer修改缓冲区(InsertBuffer插入缓冲区)

为了提高辅助索引(非聚集索引,除主键之外的索引)更新性能,暂时先把辅助索引的更新内容写到ChangeBuffer中。后台有线程定时更新。

4.自适应hash索引

为了提高查询性能,由InnoDB自己维护了一个hash索引。用户无法干预。

参考:https://juejin.im/post/6847902217270198286

5.锁信息和数据字典

2)redo log buffer重做日志缓冲区

1.redolog是一个顺序写的日志文件。wal(write ahead log)模式。顺序写比随机写效率要高。使用redo log暂存提交成功的数据。如果一旦系统崩溃,可以使用redo log恢复数据。

2.redo log buffer就是一个缓冲区,定时将缓冲区的数据保存到磁盘。

默认1s保存一次。默认在执行commit操作之前刷新redo log buffer。

    参数:innodb_flush_log_at_trx_commit控制redo log的落盘时机
        * 当属性值为0时,事务提交时,不会对重做日志进行写入操作,而是等待主线程按时写入每秒写入一次;
        * 当属性值为1时,事务提交时,会将重做日志写入文件系统缓存,并且调用文件系统的fsync,将文件系统缓冲中的数据真正写入磁盘存储,确保不会出现数据丢失;
        * 当属性值为2时,事务提交时,也会将日志文件写入文件系统缓存,但是不会调用fsync,而是让文件系统自己去判断何时将缓存写入磁盘。
3)双写缓冲区
    数据落盘需要执行双写操作,需要使用到双写缓冲区。稍后详解。

3、数据落盘

1)脏页

当更新数据commit之后,数据不是马上更新到磁盘。把数据更新到缓冲池中对应的数据页和索引页中。此时就会造成内存中的数据页和索引页与磁盘上的数据页不一致,就形成了脏页。

2)CheckPoint

执行脏页落盘操作的。

sharp checkpoint:在关闭数据库的时候,将buffer pool中的脏页全部刷新到磁盘中

fuzzy checkpoint:模糊落盘

1、Master Thread Checkpoint;

会以每秒或者每10秒一次的频率,将部分脏页从内存中刷新到磁盘,参数可调。

2、FLUSH_LRU_LIST Checkpoint;

使用LRU算法需要把一些数据页移除,但是数据页是脏页,需要执行checkpoint。

3、Async/Sync Flush Checkpoint;

redo log文件快写满时。

Async:当需要落盘的日志超过日志文件的75%并且小于90%时。

sync:当需要落盘的日志超过日志文件超过90%时。

4、Dirty Page too much Checkpoint

bufferPool缓冲池脏页太多

Dirty Page 由[innodb_max_dirty_pages_pct]配置,innodb_max_dirty_pages_pct的默认值在innodb 1.0之前是90%,之后是75%

3)双写落盘double write

当脏页落盘过程中,是使用双写操作执行落盘的。

1.把要落盘的数据写先写入双写缓冲区2m大小的双写缓冲区。

2.把双写缓冲区的数据写入系统表空间中的双写区。

3.把双写缓冲区的数据写入用户表空间中。

    redolog中记录的是数据页中修改了哪些内容,并不是完整的数据页。

    场景1:系统表空间中的数据页写坏了,可以通过用户表空间的数据页+redolog恢复。
    场景2:系统表空间中的数据页写完了,用户表空间写坏了。可以通过系统表空间的数据页恢复。

    通过双写机制保证数据落盘过程万无一失。