当前位置: 首页 > article >正文

【数据库日志】undo log、redo log和bin log作用及原理

执行一条查询SQL发生了如下流程:

那么,执行一条Update语句经历了什么呢,流程和查询类似如下:

  • 客户端玉连接器建立连接,连接器判断用户身份
  • 因为是一条update所以不需要经过缓存,但是1表中有更新语句,需要把整个表的缓存进行删除(8.0版本移除了缓存)
  • 解析器会通过词法分析识别出update、表名等构建出语法树和语法分析判断sql是否出现语法问题
  • 由于处理器会判断表中字段或者表是否存在
  • 优化器会确定执行计划,内部进行部分优化是否走索引等等
  • 执行器负责具体执行,找到这一行数据进行执行

但是,更新语句会涉及到undo log(回滚日志)、redo log(重做日志)、bin log(归档日志)这三种日志:

  • undo log:是在innodb存储引擎层生成的日志,实现了事务的原子性,主要是用于事务的回滚和MVCC
  • redo log:是在innoddb存储引擎层生成的日志,实现了事务的持久性,主要是用于掉电等等故障恢复
  • bin log:是在server层生成的日志,主要是用于数据备份和主从复制

为什么需要Buffer Pool

Mysql中的数据都是存储在磁盘当中的,那么我们更新一条数据的时候,为了提升查询速度会将这条数据放在缓存起来。为此,innodb存储引擎设计了一个缓冲池,来提升数据库的读写性能。

  • 当读取数据的时候,如果数据存储在Buffer Pool中客户端就会直接读取Buffer Pool中的数据,否则再去磁盘中进行读取
  • 当修改数据的时候,如果数据存在Buffer Pool中,那么直接修i该Buffer Pool中的数据也,然后将其页设置为脏页,为了减少磁盘IO不会立即将脏页写入到磁盘当中,后续由后台线程选择一个合适的时机将脏页写入到磁盘当中

Buffer Pool中缓存的是什么

InnoDB会把存储的数据换分为若干,以页作为磁盘和内存进行交互的基本单位,,一个页默认的大小是166KB

在Mysql启动的时候,InnoDB会为Buffer Pool申请一片连续的内存空间,然后按照默认的16KB的大小划分出一个一个的页,Buffer Pool中的页就叫做缓存页。此时这些缓存页都是空闲的,之后随着程序的运行,才会有磁盘上的页被缓存到Buffer Pool中

所以,Mysql启动的时候,就会观察到使用的虚拟内存空间很大,而使用到的物理内存空间却是很小,这是因为只有这些虚拟内存被访问后,操系统才会触发缺页中断,申请物理内存,接着虚拟内存和物理内存建立映射关系

Buffer Pool除了缓存索引页数据页,还包括Undo页、插入缓存、锁信息等

undo log作用

实现事务的回滚,保证事务的原子性:如执行insert就会在日志中记录一条delete语句

实现MVCC:MVCC就是通过ReadView+undo log实现的。undo log会记录每一条记录保存多份历史数据,mysql在执行快照读(普通的select),会根据事务的Read View里的信息,顺着undo log版本链找到满足其可见性的记录

redo log作用

Buffer Pool是用来提升读写效率的,但是问题来了,Buffer Pool是基于内存的,而内存是不可靠的,万一遇到断电重启,内存中没有落盘的数据就会丢失。

为了防止断电导致的数据丢失,有一条数据需要更新的时候,InnoDB引擎就会先更新内存(同时标记为脏页),然后将本次对这个页的修改以redo log的形式记录下来,这个时候就算更新完成了

后续,InnoDb引擎就会在适当的啥时候,由后台线程将缓存在Buffer Pool的脏页数据刷新到磁盘中,这个就是WAL技术

WAL技术指的就是,Mysql的写操作并不是立刻写到磁盘中,而是先写日志,在合适的时间在写到磁盘上

redo log是物理日志,记录了某个数据页做了什么修改,比如对XX表空间的XX数据页XXX偏移量的地方做了XX的更新,每当执行一个事务就会产生这样的一条或者多条的物理日志

在事务提交的时候,只要先将redo log持久化到磁盘中即可,可以不需要等到将缓存在Buffer Pool里的脏页数据持久化到磁盘

当系统崩溃的时候,虽然脏页数据没有持久化,但是redo log已经持久化了,Mysql重启后,可以根据redo log的内容,将所有数据恢复到最新状态

redo log 要写到磁盘,数据也要写到磁盘,为什么要多此一举呢

保证数据的持久性

  • 数据库系统在运行过程中,为了提高性能,数据的修改通常先在内存的缓冲池中进行,而不是立即写入磁盘。redo log 记录了对数据进行修改的操作记录,当数据库发生故障(如服务器崩溃、突然断电等)时,在数据库恢复阶段,系统可以根据 redo log 中的记录,将未写入磁盘的数据修改操作重新执行一遍,从而保证数据的持久性和一致性,确保已提交的事务不会丢失。

提升数据库的性能

  • redo log的方式是追加操作,所以磁盘操作是顺序IO,而写入数据需要先找到写入的位置,然后写入到磁盘,所以磁盘操作是随机IO
产生的redo log是直接写入到磁盘中呢

不是的。在执行一个1事务的过程中,产生的redo log也不是直接写入到磁盘中的,因为会产生大量IO操作,而磁盘的运行速度远小于内存。所以redo log需要自己的缓存redo log buffer,每当产生一条redo log的时候,会先写入到redo log buffer中,后续在持久化到磁盘。

bin log作用

mysql在完成一条更新操作后,Server层,还会生成一条bin log,之后事务提交的时候,会将该事务执行过程中产生的所有bin log(二进制的形式)统一写入到bin log日志中。

bin log文件是记录所有数据库表结构变更和数据修改的日志。

bin log和redo log区别

适用对象不同:

  • bin log是Mysql的Server层实现的日志,所有的存储引擎都可以使用
  • redo log只在InnoDB大的存储引擎中实现的日志1

文件格式不同:

  • bin log有3中格式类型,STATEMENT(默认格式)、ROW、MIXED区别如下:
    • STATEMENT:每一条修改SQL都会被记录
    • ROW:记录行数据修改前和修改后的情况
    • MIXED:是一种混合模式,会根据不同的情况选择使用 STATEMENT 或 ROW 格式
  • redo log是物理日志,记录着某个数据页在做什么修改,比如对XX表空间的XX数据页XXX偏移量的地方做了XX的更新

写入时机不同:

  • bin log在写入是由事务提交触发
  • redo log在数据修改的时候触发


http://www.kler.cn/a/511559.html

相关文章:

  • Chrome 132 版本新特性
  • Kinova仿生机械臂Gen3搭载BOTA 力矩传感器SeneOne:彰显机器人触觉 AI 与六维力传感的融合力量
  • 第3章:Python TDD更新测试用例测试Dollar类
  • 第5章:Python TDD定义Dollar对象相等性
  • 口令攻击和钓鱼攻击
  • python编程-OpenCV(图像读写-图像处理-图像滤波-角点检测-边缘检测)图像变换
  • Docker的原理:如何理解容器技术的力量
  • 基于Matlab实现MPC模型预测控制仿真程序(源码)
  • 【Spiffo】环境配置:Linux下LVGL项目构建(含v8、v9)、针对git不到子项目的手动组装
  • java spring,uName,kValue,前端传值后端接不到
  • 《知识图谱:鸿蒙NEXT中人工智能的智慧基石》
  • 【蓝桥杯】43687.赢球票
  • 【Linux系统】Linux下的图形库 ncurses(简单认识)
  • 基于VSCode+CMake+debootstrap搭建Ubuntu交叉编译开发环境
  • 电子电气架构 --- ECU故障诊断指南
  • LeetCode 题目 2545. 根据第 K 场考试的分数排序
  • Yii框架中的数据提取:从不同数据源获取数据
  • GoLang教程002:Go语言中的变量声明
  • Flutter+vsCode 安装问题记录
  • python怎么搞定输入??
  • 【Linux】Linux命令:ifconfig
  • Java 基于 SpringBoot+Vue 的校园数字化图书馆(源码+部署+文档)
  • 电梯系统的UML文档06
  • 从单机到集群:Docker、Kubernetes 与 Helm 部署 Redis 全攻略
  • Cyber Security 101-Offensive Security-SQLMap: The Basics(sqlmap基础)
  • 2024年博客成长记:成就、挑战与未来展望