sql查询到提交事务流程复习

问题综述:

  1. undo log和redo log了解过吗?它们的作用分别是什么?

  2. redo log是如何保证事务不丢失的?

  3. mysql的事务是先提交还是先刷盘?

  4. 更新操作为什么不直接更新磁盘反而设计这样一个复杂的InnoDB存储引擎来完成?

Mysql架构图和InnoDB存储引擎图

image-20210310095750339

流程图解析

  1. 前台用户各种操作触发后台sql执行

    ​ 通过web项目中自带的数据库连接池:如dbcp、c3p0、druid等,与数据库服务器的数据库连接池建立网络连接;数据库连接池中的线程监听到请求后,将接收到的sql语句通过SQL接口响应给查询解析器,查询解析器将sql按照sql的语法解析出查询哪个表的哪些字段,查询条件是啥;再通过查询优化器处理,选择最优的该sq最优的一套执行计划,然后执行器负责调用存储引擎的一系列接口,执行该计划而完成整个sql语句的执行。

  2. InnoDB存储引擎-缓冲池中完成更新的基本操作
    具体执行这些执行计划得要存储引擎来完成,如图所示,首次更新users表中id=10的这条数据,缓冲池中一开始肯定没有该条数据的,得要先从磁盘中将被更新数据的原始数据加载到缓冲池中(这里涉及到的innodb buffer暂时不讲)。同时为了保证并发更新数据安全问题,会对这条数据先加锁,防止其他事务进行更新。接着将更新前的值先备份写入到undo log中(便于事务回滚时取旧数据),比如update语句即存储被更新字段之前的值。最后更新缓存页中的数据为最新的数据,至此就完成了在缓冲池中的执行流程。

  3. Redo Log和BinLog保证事务的可靠性

    ​ 缓冲池中更新完数据后,需要将本次的更新信息顺序写到Redo Log日志以及Binlog日志中(此时信息还在内存中,后续的刷盘策略如图所示),一般我们为了保证数据不丢失会配置双1策略,Redo Log落盘后,写Binlog落盘,再将Binlog的文件名、文件所在路径信息以及commit标记给同步顺序写到Redo log中(其中以commit标记是否更新到Redo Log中,是判定事务是否成功提交的一个比较重要的标准),Redo Log和BinLog分别在物理和逻辑层面为本次事务、提供数据上的一致性保障。

  4. 将事务的操作持久化

    ​ 前面一些列操作执行成功后,InnoDB存储引擎后台有一个IO线程,会在数据库压力的低峰期间时如凌晨时分,将缓冲池中被事务更新、但还没来得及写到磁盘中的数据(脏数据,因为磁盘数据和内存数据已经不一致了)给刷到磁盘中,完成事务的持久化。