做者:NotFound9
连接:
https://www.cnblogs.com/notfo...html
这是在网上找到的一张流程图,写的比较好,你们能够先看图,而后看详细阅读下面的各个步骤。segmentfault
客户端与MySQL Server创建链接,发送语句给MySQL Server,接收到后会针对这条语句建立一个解析树,而后进行优化,(解析器知道语句是要执行什么,会评估使用各类索引的代价,而后去使用索引,以及调节表的链接顺序)而后调用innodb引擎的接口来执行语句。缓存
innodb 引擎首先开启事务,对旧数据生成一个UPDATE的语句(若是是INSERT会生成UPDATE语句),用于提交失败后回滚,写入undo log,获得回滚指针,而且更新这个数据行的回滚指针和版本号(会设置为更新的事务id)。异步
根据查询条件去B+树中找到这一行数据(若是是惟一性索引,查到第一个数据就能够了(由于有惟一性约束),若是是普通索引,会把全部数据查找出来。)优化
首先判断数据页是否在内存中?spa
先判断更新的索引是普通索引仍是惟一性索引?线程
若是更新的索引是普通索引,直接更新内存中的数据页指针
若是更新的索引是惟一性索引,判断更新后是否会破坏数据的惟一性,不会的话就更新内存中的数据页。日志
先判断更新的索引是普通索引仍是惟一性索引?server
若是是更新的索引是普通索引,将对数据页的更新操做记录到change buffer,change buffer会在空闲时异步更新到磁盘。
若是是更新的索引是惟一性索引,由于须要保证更新后的惟一性,因此不能延迟更新,必须把数据页从磁盘加载到内存,而后判断更新后是否会数据冲突,不会的话就更新数据页。
将对数据页的更改写入到redo log,将redo log设置为prepare状态。
通知MySQL server已经更新操做写入到redo log 了,随时能够提交,将执行的SQL写入到bin log日志,将redo log改为commit状态,事务提交成功。(一个事务是否执行成功的判断依据是是否在bin log中写入成功。写入成功后,即使MySQL Server崩溃,以后恢复时也会根据bin log, redo log进行恢复。具体能够看看下面的崩溃恢复原则)
更新时,先改内存中的数据页,将更新操做写入redo log日志,此时redo log进入prepare状态,而后通知MySQL Server执行完了,随时能够提交,MySQL Server将更新的SQL写入bin log,而后调用innodb接口将redo log设置为提交状态,更新完成。若是只是写了bin log就提交,那么突然发生故障,主节点能够根据redo log恢复数据到最新,可是主从同步时会丢掉这部分更新的数据。若是只是写binlog,而后写redo log,若是突然发生故障,主节点根据redo log恢复数据时就会丢掉这部分数据。MySQL崩溃后,事务恢复时的判断规则是怎么样的?(以redolog是否commit或者binlog是否完整来肯定)若是 redo log 里面的事务是完整的,也就是已经有了 commit 标识,则直接提交;
若是 redo log 里面的事务只有完整的 prepare,则判断对应的事务 binlog 是否存在并完整:a. 若是是,则提交事务;b. 不然,回滚事务。
undo log主要是保证事务的原子性,事务执行失败就回滚,用于在事务执行失败后,对数据回滚。undo log是逻辑日志,记录的是SQL。(能够认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。)在事务提交后,undo log日志不会当即删除,会放到一个待删除的链表中,有purge线程判断是否有其余事务在使用上一个事务以前的版本信息,而后决定是否能够清理,简单的来讲就是前面的事务都提交成功了,这些undo才能删除。change buffer是什么(就是将更新数据页的操做缓存下来)在更新数据时,若是数据行所在的数据页在内存中,直接更新内存中的数据页。若是不在内存中,为了减小磁盘IO的次数,innodb会将这些更新操做缓存在change buffer中,在下一次查询时须要访问这个数据页时,在执行change buffer中的操做对数据页进行更新。适合写多读少的场景,由于这样即使当即写了,也不太可能会被访问到,延迟更新能够减小磁盘I/O,只有普通索引会用到,由于惟一性索引,在更新时就须要判断惟一性,因此没有必要。
redo log就是为了保证事务的持久性。由于change buffer是存在内存中的,万一机器重启,change buffer中的更改没有来得及更新到磁盘,就须要根据redo log来找回这些更新。优势是减小磁盘I/O次数,即使发生故障也能够根据redo log来将数据恢复到最新状态。缺点是会形成内存脏页,后台线程会自动对脏页刷盘,或者是淘汰数据页时刷盘,此时收到的查询请求须要等待,影响查询。
若有错误或其它问题,欢迎小伙伴留言评论、指正。若有帮助,欢迎点赞+转发分享。
欢迎你们关注民工哥的公众号:民工哥技术之路