前言
在 MySQL架构(二)SQL 更新语句是如何执行的?中,小鱼介绍了SQL 更新语句的执行流程,文章中考虑初次介绍MySQL 架构,涉及到服务层的流程并没有展开介绍。
于是今天把坑填了,本文将以更新语句执行过程对server 层的操作进行展开讲解。
MySQL 的缓存机制
在 InnoDB 存储引擎下,SQL 执行的缓存机制主要涉及两种类型的缓存:查询缓存和缓冲池(Buffer Pool)。
查询缓存
查询缓存会存储已经执行过的 SELECT 语句及其结果集,如果再次执行相同的 SELECT 语句,系统会直接返回缓存中的结果,而不需要重新执行查询。
在 InnoDB 中,默认情况下是不启用查询缓存的,因为对于更新较为频繁的数据表(或者高并发场景下)而言,缓存会频繁失效,若此时使用查询缓存容易对 MySQL 性能产生负面影响,因此通常情况下不建议使用查询缓存。
查询缓存在 MySQL架构(二)SQL 更新语句是如何执行的?中已经作过介绍,可以在这篇文章更详细的了解查询缓存。
Buffer Pool缓冲池
缓冲池是 InnoDB 存储引擎中最重要的缓存机制之一,主要用于缓存数据页。
数据页page是 InnoDB 存储引擎中的最小存储单位,每个数据页的大小通常为 16 KB。
当执行 UPDATE
语句时,首先会将相关的数据页加载到缓冲池中,然后在缓冲池中进行修改。如果数据页已经存在于缓冲池中,那么更新操作会直接在缓冲池中进行,而不需要从磁盘中读取数据,从而提高了更新操作的性能。
更详细的流程如下图所示:
- 加载目标数据所在的整页 page 数据到Buffer Pool 中(或者数据已经在 Buffer Pool 中,这是就不需要再从磁盘中读取了);
- 将从 Buffer Pool 中原目标数据(或)写入 undo 日志中;
- 更新 Buffer Pool 中数据;
- 将更新操作写入 Redo Log Buffer ;
- 准备提交事务,将redo 日志写入磁盘;
- 准备提交事务,将binlog 日志写入磁盘;
- 提交事务,将commit 标记写入redo 日志中,保证redo 和binlog 日志的一致性。
- Buffer Pool 数据随机写入磁盘,也是整页page 数据写入。 至此,整个更新流程完结。
小结
MySQL 的这套缓存机制看着十分复杂,但是能确保MySQL 每个更新操作都是先更新内存,再顺序写入日志文件,能保证MySQL 在各种异常情况下的数据一致性。
- 减少磁盘 I/O 操作:Buffer Pool 缓存了数据页,使得数据可以在内存中进行修改和访问,而不必每次都从磁盘读取。这样可以显著减少磁盘 I/O 操作的次数,提高了数据库的性能。
- 加快数据访问速度:由于数据页存储在内存中,访问这些数据页比从磁盘中读取数据要快得多。这样可以加快查询和更新操作的速度,提高了数据库的响应性能。
- 提高并发处理能力:Buffer Pool 可以同时缓存多个数据页,这意味着多个并发的查询和更新操作可以同时在内存中进行,而不会因为磁盘 I/O 的限制而被阻塞。这有助于提高数据库的并发处理能力,使得系统能够更好地支持高并发的访问。