MySQL专栏(二)–>update语句执行的故事

“这是我参与更文挑战的第26天,活动详情查看: 更文挑战

欢迎关注公众号:[卢卡多多]

对于上文MySQL架构的了解,详细小伙伴们都收获许多,今天我们来聊聊数据库更新发生的事情?

为什么不用查询缓存

这个问题其实很好理解,因为只要表结构变化,更新,缓存就会被清空, 命中几率也会越来越难;

细节过程:

前面我们说过, 连接器链接成功后,表示当前用户权限校验成功,先会查询缓存,
但是我们不建议使用缓存,因为缓存常常容易失效,命中率不高;

因为 ,表示一个更新的过程,都是动态的,如果说表结构,表更新, 跟这个表有关的查询缓存都会失效,
就会把当前这个表之前查询的缓存语句全部清空,(所以多走了一遍缓存,而且知道是不会命中的,影响效率)

今天的主题是关于,更新后的数据库是怎么做操作的?

UPDATE Person SET FirstName = 'look' WHERE LastName = 'lukaduoduo' 

复制代码

更新操作中 server层如何工作的;

连接器和查询缓存就不说了,

  • 分析器会 根据 update关键字,以及参数,语法分析去定义为一个更新语句,
  • 优化器决定使用ID这个索引
  • 然后执行器一执行,完美

当前 更新操作与之前的查询语句,流程中有很大的不同, 因为更新还涉及了两个 日志模块,

redo log —> 重做日志( 今天的收益额的账本)

binlog——>归档日志 (汇总的总账本)

面粉板—账本
当天的—合计

MySQL中有一个WAL的技术,也就是write ahead logging ,先写日志,后写磁盘的过程
也就是先写粉板,在晚上对账本

write pos 是当前记录的位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头。checkpoint 是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。

操作过程:

当需要更新操作的时候, innodb会将记录先写到redo log, 更新内存,然后就完成更新;
等到适当的时候,将日志操作,写入磁盘中;

当redo log达到一定数据,也会触发存储引擎写磁盘的操作;这就是innodb的保证数据库异常重启后,数据不丢的能力crash-safe;(奔溃安全,碰撞安全)

redolog日志是innodb特有的

其中binlog 是server层的日志, 所以的引擎都可以使用;

redo log 和 binlog的区别

  • redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。

  • redo log 是物理日志,记录的是“在某个数据页上做了什么修改”; binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。

  • redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。


更新操作,

从执行器触发, 开始调用存储引擎调用更新接口:

  • 执行更新接口时,获取到当前数据,从磁盘写入内存, 然后更新,获取到磁盘中的数据,写入内存,然后更新内存中的数据

  • 先写 redo log日志,改为prepare的准备状态,(表示数据引擎已经更新完成)

  • 告诉执行器已经完成,可以提交事务, 执行器生成binlog的归档日志,并写入磁盘

  • 执行器调用存储引擎的事务提交接口, 将redolog 的准备prepare的状态改为 commit的状态
    更新完成
更新过程
更新过程

卢卡问答

为什么分布式事务中,分布式系统中,会要求两段式提交?

我们下期解答:
提示一下与innodb引擎的日志有关

卢卡寄语

当前我们确定一个添加语句和更新操作中,最重要的日志关系,
以及为什么MySQL会异常时候不丢失数据, 有一个WAL技术
保证crash-safe

以后面试中可以提出这个机制,由日志来实现,先写日志再写磁盘,从而实现异常安全的机制,

我是卢卡,做个连更的小霸王,大家晚安了

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享