03 用一次数据更新流程,初步了解InnoDB存储引擎的架构设计

2020-11-30  本文已影响0人  呢看了看

【1】MySQL最常用的就是InnoDB存储引擎,更新语句在MySQL中是如何执行的?我们的系统通过一个数据库连接发送到了MySQL上,然后肯定会经过SQL接口、解析器、优化器、执行器几个环节,解析SQL语句,生成执行计划,接着由执行器负责这个计划的执行,调用InnoDB存储引擎的接口去执行。

【2】InnoDB的重要存储结构:缓冲池。InnoDB存储引擎中有一个非常重要的放在内存里的组件,就是缓冲池。这里面会缓冲很多的数据,以便于以后在查询的时候,万一你要是内存缓冲池里有数据,就可以不用去查询磁盘了。所以当我们的InnoDB存储引擎执行更新语句的时候,会看这行数据是否在缓冲池里,如果不在的话,那么会直接从磁盘里加载到缓冲池里,接着会对这行记录加独占锁。更新这行数据的时候,肯定是不允许别人同时更新的,所以必须对这行记录加上独占锁。

【3】undo日志文件:如何让你更新的数据可以回滚。如果我们执行一个更新语句,要是他在一个事务里的话,那么事务提交之前都是可以对数据进行回滚的,也就是把你更新的数据回滚到之前的数据去。所以为了考虑未来要回滚的需要,这里会把你更新前的值写入undo日志文件。

【4】更新buffer pool中的缓存数据。当我们把更新的那行记录从磁盘文件加载到缓冲池,同时对他加上锁之后,而且还把更新前的旧值写入undo日志文件之后,我们就可以正式开始更新这行记录了。更新的时候,先是会更新缓冲池中的记录,此时这个数据就是脏数据了。为什么这个时候是脏数据呢?因为磁盘上的数据还没有修改,内存中的数据已经修改了。

【5】Redo Log Buffer:万一系统宕机,如何避免数据丢失?目前已经将内存里的数据进行了修改,但是磁盘上的数据还没有修改,此时万一MySQL所在的机器宕机了,必然会导致内存里修改过的数据丢失,这该怎么办呢?这个时候,就必须要对内存所做的修改写入到一个Redo Log Buffer里去,这也是内存里的一个缓冲区,是用来存放redo日志的,所谓的redo日志,就是记录下来你对数据做了什么修改。这个redo日志其实是用来在MySQL宕机的时候,用来恢复你更新过的数据的。redo日志目前还仅仅停留在内存缓冲里。

【6】如果还没有提交事务,MySQL宕机了怎么办?在数据库中,哪怕执行一条SQL语句,其实也是一个独立的事务,只有当你提交事务之后,SQL语句才算执行结束。如果还没有提交事务,此时如果MySQL崩溃,必然导致内存里Buffer Pool中修改过的数据都丢失,同时你写入Redo Log Buffer中的redo日志也会丢失。但是此时Redo Log Buffer丢失数据,要紧吗?不要紧,磁盘上的数据依旧是老样子。

【7】提交事务的时候将redo日志写入磁盘中。我们要提交事务了,此时就会根据一定的策略把redo日志从Redo Log Buffer里刷入磁盘文件里去,此时这个策略是通过innodb_flush_log_at_try_commit来配置的,有几个选项:

··1··当这个参数的值为0的时候,你提交事务的时候,不会把redo log buffer里的数据刷入磁盘文件里的,此时可能你都提交事务了,结果MySQL宕机了,此时内存里的数据全部丢失。相当于你提交事务成功了,但是由于MySQL突然宕机了,导致内存中的数据和redo日志都丢失了。

··2··当这个参数的值为1的时候,提交事务的时候,就必须把redo log从内存刷入到磁盘文件里去,只要事务提交成功,那么redo log就必然在磁盘里了。然后MySQL系统突然崩溃了,此时会如何?会丢失数据吗?肯定不会的,虽然内存里的数据会丢失,但是redo日志已经刷入到磁盘里,此时MySQL重启之后,就可以根据redo日志去恢复之前做过的修改。

··3··当这个参数的值为2的时候,提交事务的时候,把redo日志写入磁盘文件对应的os cache缓存里去,而不是直接进入磁盘文件,可能1秒后才会把os cache里的数据写入到磁盘文件里去。这种模式下,你提交事务之后,redo log可能仅仅停留在os cache内存缓存里,没有实际进入磁盘文件,万一此时机器宕机了,那么os cache里的redo log就会丢失,同样会感觉提交事务了,结果数据丢了。

上一篇 下一篇

猜你喜欢

热点阅读