前言
mysql相信大家都不陌生了,分享之前我们先思考几个面试题:
1.undo log和redo log了解过吗?它们的作⽤分别是什么?
2.redo log是如何保证事务不丢失的?
3.mysql的事务是先提交还是先刷盘?
4.更新操作为什么不直接更新磁盘反而设计这样⼀个复杂的InnoDB存储引擎来完成?
下面我们开始逐步探索Mysql架构的运行流程。
前台操作触发Mysql服务器执⾏请求
前台⽤户各种操作触发后台sql执⾏,通过web项⽬中⾃带的数据库连接池:如dbcp、c3p0、druid等,与数据库服务器的数据库连接池建⽴⽹络连接;
数据库连接池中的线程监听到请求后,将接收到的sql语句通过SQL接⼝响应给查询解析器,
查询解析器将sql按照sql的语法解析出查询哪个表的哪些字段,查询条件是啥;
再通过查询优化器处理,选择该sql最优的⼀套执⾏计划,然后执⾏器负责调⽤存储引擎的⼀系列接⼝,执⾏该计划⽽完成整个sql语句的执行,如下图所示:
InnoDB存储引擎-缓冲池中完成更新的基本操作
具体执⾏这些执⾏计划得要存储引擎来完成,比如⾸次更新users表中id=10的这条数据,缓冲池中⼀开始肯定没有该条数据的,
得要先从磁盘中将被更新数据的原始数据加载到缓冲池中(这⾥涉及到的innodb buffer暂时不讲)。
同时为了保证并发更新数据安全问题,会对这条数据先加锁,防⽌其他事务进⾏更新。
接着将更新前的值先备份写⼊到undo log中(便于事务回滚时取旧数据),⽐如update语句即存储被更新字段之前的值。
最后更新缓存⻚中的数据为最新的数据,⾄此就完成了在缓冲池中的执⾏流程,如下图所示:
Redo Log和BinLog保证事务的可靠性
缓冲池中更新完数据后,需要将本次的更新信息顺序写到Redo Log⽇志以及Binlog⽇志中(此时信息还在内存中),
Redo Log刷盘策略由innodb_flush_log_at_trx_commit属性值来定,
0:不会写到磁盘 ,宕机会导致已提交事务数据丢失
1:数据过来即写磁盘,做到教据零丢失但是效率会很低
2:写到os cache,每秒刷新一次到磁盘,宕机最多丢失1s的数据,速度够快
Binlog刷盘策略由sync_binlog属性来定,
1:强制刷盘;0:写入os cache。
⼀般我们为了保证数据不丢失会配置双1策略,
Redo Log落盘后,写Binlog落盘,再将Binlog的⽂件名、⽂件所在路径信息以及commit标记给同步顺序写到Redolog中(其中commit标记是否更新到Redo Log中,是判定事务是否成功提交的⼀个⽐较重要的标准),
Redo Log和BinLog分别在物理和逻辑层⾯为本次事务、提供数据上的⼀致性保障,如下图所示
将事务的操作持久化
前⾯⼀些列操作执⾏成功后,InnoDB存储引擎后台有⼀个IO线程,会在数据库压⼒的低峰期间时如凌晨时分,
将缓冲池中被事务更新、但还没来得及写到磁盘中的数据(脏数据,因为磁盘数据和内存数据已经不⼀致了)给刷到磁盘中,完成事务的持久化。
面试题解答
1.undo log和redo log了解过吗?它们的作⽤分别是什么?
undo log和redo log是mysql中InnoDB存储引擎的基本组成:
(1)undo log保存了事务执⾏前数据的值,以便于事务回滚时能回到事务执⾏前的数据版本,多次更
新会有undo log的版本链;
(2)redo log在物理层⾯上记录了事务操作的⼀系列信息,保证就算遇到mysql宕机等因素还没来得
及将数据刷到磁盘⾥,通过redo log也能恢复事务提交的数据。
2.redo log怎样保证事务不丢失的?
当⼀个事务提交成功后,虽然缓冲池中的数据不⼀定来得及⻢上落地到磁盘中,但是redo log记录的
事务信息持久化到磁盘中了、且含有commit标记,此时如果mysql宕机导致缓冲池中的、已经被事务更新
过的内存数据丢失了,此时在mysql重启时,将磁盘中的redo log中将事务变更信息给加载到缓冲池中,
保证事务信息不会丢失。或者redo log刷盘了,binlog写成功了,在重启时会⾃动给上commit标记,在重
放数据。
3.事务是先提交还是先刷盘?
事务先提交后刷盘;
1.Redo log刷盘成功->2.Binlog刷盘->3.BinLog名称和⽂件路径信息、commit标志写到Redo log
中,事务两阶段提交的⽅式来保证。
4.更新操作为什么不直接更新磁盘反⽽设计这样⼀个复杂的InnoDB存储引擎来完成?
直接更新磁盘是随机IO写,存在磁盘地址寻址操作,性能⾮常低,承载不了⾼并发场景;
⽽转换为InnoDB中,内存⾼速读写、redo log和undo log顺序写磁盘性能相对于随机IO写性能会⾼
的多,⽽这种性能上的提⾼⾜以抵消这种架构上带来的复杂,可在⼀定QPS内承载⾼并发场景。