一条 SQL 查询语句是如何执行的?
连接器
- 负责服务端与客户端建立连接,验证密码是否正确,是否有权限
分析器
- 对要进行执行的 SQL 语句进行词法分析和语法解析
优化器
- 决定使用哪个索引,还有类似 join 时刻表的连接顺序等
执行器
一条 Update 语句是怎么执行的?
执行顺序
- 执行器先去引擎中找到对应的行
- 找到对应的行之后进行计算处理
- 引擎将这部分数据记录到内存中,同时记录 redo log 状态为 prepare,告知执行器执行结束
- 执行器生成 binlog 写入磁盘
- 执行器调用引擎提交事务的接口,修改 redo log 的状态为 commit
什么是 redo log
- 物理日志,InnoDB 特有。redo log 记录了对于哪个数据页进行修改,同时保证脏页能够及时回刷到磁盘中(两阶段提交)。有大小限制,写策略是循环写
- 什么是脏页?
- 内存中与磁盘数据不一致的部分
- 在 InnoDB 中,数据的读取是按照页(page)进行,读取一行数据时候会将这行数据整页的方式进行读入
什么是 binlog
- 逻辑日志,MySQL 的 server 层实现的,记录了每一行数据的执行逻辑,默认无大小限制,写策略是追加写
什么是两阶段提交
- redo log 的两种状态,prepare 和 commit,保证宕机后数据可以正确恢复
- 为什么两阶段提交可以保证数据可以被正确恢复?
- 两阶段提交把是否提交成功变成了可重放、可判定的状态机,不依赖内存状态
- 正确恢复主要有三件事:
- 已提交事务不丢失
- 未提交事务不生效
- 引擎存储数据和 binlog 一致(保证主从同步的数据一致性)
- 两阶段提交的原理:
- 写 redo log prepare(落盘)
- 写 binlog 落盘
- 写 redo log commit 落盘
- 崩溃恢复判定:
- 如果崩溃发生在阶段 3:事务已经提交
- 如果崩溃发生在阶段 2:事务可以提交
- 如果崩溃发生在阶段 1:事务回滚
- binlog 如果写入磁盘即可保证主从一致性,两阶段提交主要解决 redo log 以及 binlog 的一致性
为什么要有两份日志
- redo log 和 binlog 的职能不同
- redo log:给 InnoDB 自己用(本地崩溃恢复),主要解决的问题是内存数据没有回刷到磁盘的问题
- binlog:给 MySQL 的 server 层使用,逻辑变更日志可以回放当时业务操作,由于是追加写入可长期保存归档
- redo log 设计太底层,并且由于覆写限制无法实现归档/复制
- binlog 是逻辑日志,无法处理引擎页级崩溃恢复设计,不能替代 redo 的快速本地恢复能力
关联