极客--日志系统:一条SQL更新语句是如何执行的?
前篇我们知道,一个查询语句的执行流程,并介绍执行过程中涉及的模块,一条查询语句的执行过程一般是经过连接器、分析器、优化器、执行器等功能模块,最后到达存储引擎
一条更新语句的执行流程
update T set c = c + 1 where ID = 2
-
首先连接器的工作,TCP三次握手,账号密码校验,权限校验
-
Mysql8.0已经取消缓存,在一个表更新的时候,查询缓存失效
-
分析器通过词法和语法解析这是一条更新语句,优化器决定要使用ID这个索引,然后执行器负责具体执行,找到这一行,然后更新。
-
更新流程涉及两个重要的模块,redo log与binlog
redo log
-
如果每一次更新都会写入磁盘,然后磁盘也要找到对应那条记录,然后再更新,整个过程的IO成本,查找成本很高
-
Mysql中WAL技术,关键点就是先写日志,再写磁盘
-
当更新一条记录的时候,Innodb引擎会先把记录写到redo log,然后更新内存,这个时候就算更新完成,同时Innodb引擎会在适当的时候写入磁盘中
-
Innodb的redo log是固定大小,比如可以配置一组4个文件,每个文件大小1GB

-
write pos是当前记录的位置,一边写一边后移,写到第三号文件末尾后就回到0号文件开头,checkpoint是当前擦除的位置,也是往后推移并且循环,擦除记录前要把记录更新到数据文件
-
有了redo log,InnoDB就可以保证即使数据库发送异常重启,之前提交的记录也不会丢
-
binlog
从mysql整体上看分为Server层与引擎层,redolog是Innodb特有的日志,而Server层特有的日志就是binlog
这两种日志有以下三点不同。
- redo log 是 InnoDB 引擎特有的;
- binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
- redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;
- binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
- redo log 是循环写的,空间固定会用完;
- binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

两阶段提交
-
binlog 会记录所有的逻辑操作,并且是采用“追加写”的形式。如果你的 DBA 承诺说半个月内可以恢复,那么备份系统中一定会保存最近半个月的所有 binlog,同时系统会定期做整库备份。这里的“定期”取决于系统的重要性,可以是一天一备,也可以是一周一备。
-
如果不使用“两阶段提交”,那么数据库的状态就有可能和用它的日志恢复出来的库的状态不一致。
-
redo log保证crash-safe能力。innodb_flush_Log_at_trx_commit设置为1的时候,表示每次事务redo log都持久化到磁盘。这个参数建议设置为1,这样保证Mysql异常重启之后数据不丢失
-
sync_binlog这个参数设置为1的时候,表示每次事务Binlog都持久化到磁盘,这个参数也建议设置为1,这样保证Mysql异常重启以后binlog不丢失
-
redo log记录的是磁盘上数据的物理变化,binlog记录当时执行高级编程语言
-
Binlog有两种模式,statement 格式的话是记sql语句, row格式会记录行的内容,记两条,更新前和更新后都有。

浙公网安备 33010602011771号