MYSQL中执行一条更新语句的流程是怎样的呢?
首先,在MYSQL中执行一条查询语句,大概流程是:
连接器–》分析器–》优化器–》执行器
那么执行一条Update语句,除了执行上面的流程,还涉及到两个重要的日志模块:redo log(重做日志)和 binlog(归档日志)。
redo log(重做日志)
支持crash-safe,是 InnoDB 引擎特有的,并且redo log 是物理日志,记录数据是在哪个数据页上被修改的。
binlog(归档日志)
是 MySQL 的 Server 层实现的,所有引擎都能够使用;binlog 是逻辑日志,记录的是数据的更新逻辑语句,比如id=1的这条记录,name字段更新成了“张三”。
两个日志相互配合就能保证MYSQL任何时刻都不会丢失数据,要了解为什么不会丢失数据,先来了解UPATE执行过程,和执行过程中,两个日志的处理逻辑。
我们来看看实际的update执行流程如下:
【执行器执行】update要更新的数据
↓
【InnoDB执行】判断是否在内存中→<否>→【InnoDB执行】磁盘查找加载到内存
↓-<是> ↓
↓←←------←←--------←←----←←----←←
【InnoDB执行】返回数据
↓
【执行器执行】执行更新
↓
【执行器执行】写入新行
↓
【InnoDB执行】更新到内存
↓
【InnoDB执行】写入redolog处于prepare状态
↓
【执行器执行】写入binlog------→更新到从库
↓
【InnoDB执行】提交事务处于commit状态
【重点】防止数据丢失,最重要的环节,就是最后三个步骤,分析在不同环节MYSQL崩溃,数据处理逻辑,我们把关键环节分为3个阶段:
1-prepare阶段
2-写binlog
3-commit
当在步骤1崩溃时,重启恢复数据,后发现没有commit,回滚。备份恢复:没有binlog,两个日志是一致的。
当在2崩溃,重启恢复数据,虽然没有commit,但满足prepare和binlog完整,所以重启后会自动commit,备份:有binlog,两个日志是一致的。
这里有个关键的概念叫“两阶段提交”,即redolog更新成功后,不马上提交,而是等binlog写成功后,再更新为commit状态。
为什么有这个“两阶段提交”呢?这是为了让两份日志之间的逻辑一致,只有两个数据日志是一致的,才认为数据是完整的。