概述
在MySQL中,UPDATE语句的执行流程与SELECT语句类似,但包含了额外的数据修改和日志记录步骤。本文将深入探讨UPDATE语句在InnoDB引擎中的完整执行过程,包括缓冲区管理、各种日志的作用以及数据持久化机制。
Buffer Pool缓冲区
基本工作原理
当执行UPDATE语句时,MySQL首先从存储引擎层读取数据到服务层进行修改,然后再通过存储引擎将更新后的数据写回数据库。InnoDB引擎通过Buffer Pool这一内存缓冲区来优化这一过程:
-
每次读取数据以16KB为单位(称为一页)
-
数据从磁盘通过IO读取到Buffer Pool中
-
引擎直接在Buffer Pool中修改数据
-
修改后的数据仍留在Buffer Pool中
-
脏页与刷新机制
Buffer Pool中尚未同步到磁盘的数据称为"脏数据"。InnoDB通过以下机制管理脏页刷新:
-
当脏页比例超过
innodb_max_dirty_pages_pct_lwm
时,开始刷新脏页 -
当比例超过
innodb_max_dirty_pages_pct
(默认75%)时,进入"勤快刷新"模式 -
特殊情况下的"sharp checkpoint"会强制刷新所有相关页面
查看相关配置:
show VARIABLES like '%dirty_page%';
Buffer Pool管理
默认大小为128MB,使用改良的LRU算法管理内存:
show VARIABLES like '%innodb_buffer_pool%';
事务日志系统
Redo Log(重做日志)
问题:如果数据在Buffer Pool中未刷新到磁盘时服务崩溃,如何保证数据不丢失?
解决方案:Redo Log提供了持久性保证,记录所有数据修改操作。
性能考虑:Redo Log采用顺序IO写入,比随机IO快得多。
相关配置:
show VARIABLES like '%innodb_log%';
刷盘策略由innodb_flush_log_at_trx_commit
参数控制:
-
1:每次提交都刷盘(最安全,性能较低)
-
0:每秒刷盘(可能丢失1秒数据)
-
2:每次提交写入OS缓存,每秒刷盘
Undo Log(回滚日志)
Undo Log保证事务的原子性,记录修改前的数据,用于回滚操作。
show VARIABLES like '%undo%';
Binlog(二进制日志)
属于MySQL服务层的日志,用于:
-
主从复制
-
数据恢复
-
记录所有表结构变更和数据修改
特点:
-
逻辑日志
-
无大小限制(可追加)
-
所有存储引擎通用
show GLOBAL VARIABLES like '%log_bin%';
主从复制原理:
UPDATE语句完整执行流程
-
从磁盘读取数据页到Buffer Pool
-
记录Undo Log(用于回滚)
-
在Buffer Pool中修改数据(产生脏页)
-
记录Redo Log(保证持久性)
-
记录Binlog(用于复制和恢复)
-
提交事务
-
适时将脏页刷新到磁盘