“这是我参与更文挑战的第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,
以后面试中可以提出这个机制,由日志来实现,先写日志再写磁盘,从而实现异常安全的机制,
我是卢卡,做个连更的小霸王,大家晚安了