在数据库里面,我们说的 update
操作其实包括了更新、插入和删除。更新流程和查询流程有什么不同呢?今天我想把MySQL的更新过程拆解一下,借由这个过程,对MySQL有更深入的了解,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
首先,我们来回顾一条查询语句的执行过程,一条查询语句的执行过程一般是经过连接器、分析器、优化器、执行器等阶段后,最后到达存储引擎。执行流程图如下:
更新SQL语句的执行过程与查询的基本一致,经过连接器、分析器、优化器、执行器等阶段后再进行update,重点在于多了一点东西,那就是redo_log
、undo_log
和binlog
。更新语句的执行过程图如下:
执行流程如下:
redo_log
又叫重做日志,是 InnoDB
引擎特有的日志,用来记录事务操作的变化,记录的是数据修改之后的值,不管事务提交是否成功,都会被记录下来,如果服务器出问题了,我们就从这个日志文件里面读取数据,恢复数据——保证数据的持久性与完整性。
之前你可能经常听DBA同事说,MySQL
可以恢复到半个月内任意一秒的状态,你是不是也会好奇这是怎样做到的呢?其实主要是应用到的binlog
日志。
binlog日志我们又称归档日志,在server
端生成的以二进制形式存储,以事件的形式记录了所有的 DDL
和 DML
语句(因为它记录的是操作而不是数据值,属于逻辑日志),可以用来做主从复制和数据恢复。
由于redo_log
和 binlog
是两个独立的逻辑,在不保证两个逻辑都能执行成功的情况下,那么数据库的状态就有可能和用它的日志恢复出来的库的状态不一致,为了保证写redo_log
和binlog
的一致性,实际采用了二阶段提交的方式。我们来看一下什么是二阶段提交?
InnoDB
存储引擎将更改更新到内存中后,同时将这个更新操作记录到redo
日志里面,此时redo日志处于prepare
状态;binlog
,并将binlog
刷盘;InnoDB
把刚刚写入的redo
日志改成commit
状态。至此,所有操作完成。以上就是文章的全部内容,对于一个SQL语句的更新来说,前面的流程跟一条SQL的查询流程是类似的,通过解析器进行语法分析,优化器优化,执行引擎去执行,这个都没有什么问题,唯一的不同的就是拿到符合条件的数据之后的操作,更新语句还涉及到两个重要的日志模块,那就是redo_log
、undo_log
和binlog
。
为了保证写redo_log
和binlog
的一致性,实际采用了二阶段提交的方式。
一条更新语句的执行过程可以总结如下: