MySQL基本原理!

SQL查询

一条查询语句的执行过程一般是经过连接器、分析器、优化器、执行器等阶段后,最后到达存储引擎。

9cc38410df3b9a1992e3d5e24842a704 (1)

SQL更新

9cc38410df3b9a1992e3d5e24842a704 (1)

SQL写入

9cc38410df3b9a1992e3d5e24842a704 (1)

先去看缓冲区有没有这条数据,如果有就不进行缓存。

  • 将要修改的那一行数据所在的一整页加载到缓冲池Buffer Pool中。

将旧值写入undo日志中,便于回滚以及mvcc机制的运作。

Buffer Pool中的数据更新为新的数据。

写入redo日志缓冲池,redo日志的内容实际和binlog差不多,但是作用不同。

  • 什么时候刷新buffer logredo log日志,有innodb_flush_log_at_trx_commit参数可以控制

同时innodb写入磁盘用了两段提交。

准备提交事务前,将redo日志写入磁盘。

准备提交日志前,将binlog日志写入磁盘。

commit标记写到redo日志中,事务提交完成。

  • 该操作时为了保证事务提交后redobinlog数据一致性。

将缓冲区的数据写入磁盘,注意这里的写入不是及时写入的,而是随机的。

ChangeBuffer

ChangeBuffer是InnoDB缓存区的一种特殊的数据结构,当用户执行SQL对非唯一索引进行更改时。

如果索引对应的数据页不在缓存中时,InnoDB不会直接加载磁盘数据到缓存数据页中,而是缓存对这些更改操作。

  • 这些更改操作可能由插入、更新或删除操作(DML)触发。

ChangeBuffer用于存储SQL变更操作,比如Insert/Update/Delete等SQL语句。

ChangeBuffer中的每个变更操作都有其对应的数据页,并且该数据页未加载到缓存中。

当ChangeBufferd中变更操作对应的数据页加载到缓存中后,InnoDB会把变更操作Merge到数据页上。

InnoDB会定期加载ChangeBuffer中操作对应的数据页到缓存中,并Merge变更操作。

InnoDB缓存区结构

在什么场景下会触发ChangeBuffer的Merge操作?

访问变更操作对应的数据页。

InnoDB后台定期Merge。

数据库BufferPool空间不足。

数据库正常关闭时。

RedoLog写满时。

为什么ChangeBuffer只缓存非唯一索引数据?

由于唯一索引需要进行唯一性校验。

所以对唯一索引进行更新时必须将对应的数据页加载到缓存中进行校验,从而导致ChangeBuffer失效。

ChangeBuffer适用场景:

数据库大部分索引是非唯一索引。

业务是写多读少,或者不是写后立刻读取。

普通索引还是唯一索引?

从索引修改角度来看:

  • 由于非唯一索引无法使用ChangeBuffer,对索引的修改会引起大量的磁盘IO,影响数据库性能。

如果不是业务中要求数据库对某个字段做唯一性检查,最好使用普通索引而不是唯一索引。