《MySql学习》 SQL 语句的更新过程
一.SQL查询语句的执行过程
上一篇博文记录了SQL查询语句的执行过程,首先客户端通过TCP三次握手与Server层的连接器建立连接(短连接与长链接),缓存权限。然后去查询缓存(8.0后移除)中查询数据,如果有数据就直接将缓存数据返回(对表的DML,DDL操作都会使缓存失效)。如果没有命中缓存,来到分析器,对SQL语句进行词法分析与语法分析(表元数据信息不需要通过存储引擎获取)。如果SQL语句没有语法错误,且要查询的表与列都是存在的,将来到优化器进行优化(选择合适的索引,不一定是最优的)。经过优化后轮到执行器处理,执行器将调用存储引擎的接口,获取数据并返回给客户端。
二.redo log 与 bin log 日志
与查询语句不同的是,SQL更新语句有两个重要的日记文件,分别是redo log (重做物理日志,环形,磁盘顺序写)与 bin log(归档逻辑日志),两者的搭配是MySQL WAL(Write-Ahead-Logging)技术的关键。
1.redo log 重做日志
redo log 由存储引擎生成,是物理级别的日志,记录了某一页上多少偏移量上的数据发生了什么变化,保证了事务的持久性
redo log称为重做日志 ,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持久性。
redo log由两部分组成 分别是 redo log buffer (重做日志缓冲区,内存中)与 redo log file (重做日志文件,磁盘上)
redo log 有固定的大小,从头写到尾部,不停的循环写 如下图所示 write pos 指向当前写数据的位置,check point 为已经刷到磁盘中数据已清除的位置 。 check point 与 wrote pos之间的空间为空闲空间,当write pos与
check point指向一块时,表示当前 redo log已经写满,需要停下来刷数据到磁盘上
2.bin log 归档日志
bin log 日志有server层生成 bin log 日志在记录的时候采用的是追加写入的方式,且有三种模式
- Statement Level模式 (记录每一条SQL) 优点 : 日志文件小,IO成本低 缺点 : 主从同步会出现不一致的情况
- Row Level模式 (日志中会记录成每一行数据修改的形式) 优点: 日志详细,主从同步时不会出现不一致的情况 缺点 : 日志文件大,IO成本高
- Mixed模式(混合模式)Statement Level 与 Row Level 一起使用,根据SQL来决定使用 Statement 模式还是 Row 模式
bin log 日志 与 redo log日志有三点不同
- redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
- redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
- redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。
三.SQL语句的更新过程
mysql> update T set c=c+1 where ID=2;
上述SQL的执行过程如下 :
- 执行器先找引擎取 ID=2 这一行。ID 是主键,引擎直接用树搜索找到这一行。如果 ID=2 这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁盘读入内存,然后再返回。
- 执行器拿到引擎给的行数据,把这个值加上 1,比如原来是 N,现在就是 N+1,得到新的一行数据,再调用引擎接口写入这行新数据。
- 引擎将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 里面,此时 redo log 处于 prepare 状态。然后告知执行器执行完成了,随时可以提交事务。
- 执行器生成这个操作的 binlog,并把 binlog 写入磁盘。
- 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新完成。
redo log 与 bin log 采用二阶段提交就是为了保证主从数据库的一致性,数据库的状态和用日志恢复的库状态保存一致。redo log 与 bin log 通过 XID 关联
内容来源于极客时间《课程名称》,强烈推荐该课程!