select 和 update 的执行流程
1、mysql 构成
server层:连接器->缓存器->分析器(预处理器)->优化器->执行器
引擎层 : 查询和存储数据
2、select 执行过程
客户端发送请求,建立连接
server层查找缓存,命中直接返回,否则继续
分析七分析sql语句以及预处理(验证字段合法性及类型等)
优化器生成执行计划
执行器调用引擎API查询结果
返回查询结果
3、update执行过程
基础概念
buffer pool(缓存池)在内存中,下次读取同一页的数据的时候可以直接从buffer pool中返回(innodb的聚簇索引)
更新数据的时候先更新buffer pool然后在更新磁盘
脏页:内存中的缓存池更新了但是没有更新磁盘
刷脏:inndb 中有一个专门的进程将buffer pool的数据写入磁盘,每隔一段时间将多个修改一次性写入磁盘
redo log 和 binlog
redo log(重做日志)innodb特有的日志,物理日志,记录修改
redo log是重复写空间固定且会用完会覆盖老日志
binlog 是server层共有的日志,逻辑日志记录语句的原始逻辑
binlog 是追加写到一定大小切换到下一个不会覆盖以前的日志
redo log主要是用来恢复崩溃,bin log是用来记录归档的二进制日志
redo log只能恢复短时间内的数据,binlog可以通过设置恢复更大的数据
WAL(write-ahead-logging)先写日志方案
记录日志是顺序IO
直接写入磁盘(刷盘)是随机IO因为数据是随机的可能分布在不同的扇区
顺序IO的效率更高先写入修改日志可以延迟刷盘时机,提高吞吐量
redo log 刷盘机制,check point
redo log大小固定循环写入
redo log 就像一个圆圈前面是check point (到这个point就开始覆盖老的日志)后面是write point (当前写到的位置)
write point 和check point 重叠的时候就证明redo log 满了需要开始同步redo log 到磁盘中了
执行步骤(两阶段提交 - 分布式事务,保证两个日志的一致性)
分析更新条件查找需要更新的数据(会用到缓存)
server 调用引擎层的APIInnodb 更新数据到内存中,然后写入redo log,然后进入prepare
引擎通知server层开始提交数据
server层写入binlog 日志并且调用innodb 的接口发出commit请求
引擎层收到请求之后提交commit
宕机后数据崩溃恢复规则
如果redo log 状态为commit 则直接提交
如果redo log 状态为prepare则判断binlog 中的事务是否commit是则提交,否则回滚
如果不使用两次提交的错误案例(update table_x set value = 10 where value = 9)
先redo log 再写入binlog
1. redo log 写完之后,binlog没写完,这时候宕机。
2. 重启之后redo log 完整,所以恢复数据 value = 10
3. bin log日志中没有记录,如果需要恢复数据的时候 value = 9
先写binlog 再写redo log
1. binlog 写入完成,redo log 未完成
2. 重启之后没有redo log ,所以value 还是9
3. 当需要恢复数据的时候binlog 日志完整,value 更新成10
undo log
在更新写入buffer pool之前记录
如果更新过程中出错,直接回滚到undo log 的状态