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

Mysql中的日志-undo/redo/binlog详解

在缓存一致性的方法中,有一种是用binlog同步消息,完成缓存的同步,提高了可靠性。这里详细学习一下数据库中的三种日志。

1. 日志的作用

1.1 事物的特性

在MySQL中,事务具有四大特性(ACID):

  • 原子性(Atomicity):事务是一个不可分割的单元,要么都执行要么都不执行。

  • 一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性没有被破坏

  • 隔离性(Isolation):数据库允许多个并发事务同时对数据进行读写和修改,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。

  • 持久性(Durability):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

事务的原子性、一致性、持久性是通过数据的redo log(重做日志)和undo log(回滚日志)来完成的,而隔离性则是数据库另一个重要机制锁来实现的。

2. undo log回滚日志

2.1 作用

实现了事务中的原子性,主要用于事务回滚和 MVCC

undo log生成的时机:

  • 事务开始时分配
  • 事务修改数据前记录旧值
  • 事务提交后不会立即删除,可能被其他读事务引用
  • 当没有事务需要访问旧版本数据时,由系统清理

2.2 原理

2.2.1 回滚场景

事务在执行过程中,提交事务之前,MySQL发生了崩溃,数据如何回滚到事务之前呢?

undo log是一种可以撤销回退的日志,在事务没有提交前,会记录更新前的数据到undo log中。

一条记录的每一次更新操作产生的undo log格式如上图,都有一个trx_id和roll_pointer,

  • trx_id:知道该记录是哪个事务修改的
  • roll_pointer:指向该记录的上一次更新数据,通过该指针形成链表,称为版本链。

id=1的新数据balance=2000000,是事务51更新的数据;历史数据是balance=1000000,是事务50更新的数据。

回滚原理:在发生回滚时,读取undo log中的数据,然后做相反的操作,例如delete一条记录,会将该数据记录到undo log中,回滚时,直接读取undo log中的数据即可。不同类型的操作,insert/update/delete有不同的undo log格式。

2.2.2 MVCC

MVCC是多版本并发控制,是通过read view和undo log实现的,undo log中存储着多个历史版本,事务中在第一个查询语句后,会创建一个read view,read view记录当前已经提交和未提交的所有事务,在事务内如果再次查询,依然用的是这个read view,所以事务内查询的数据都是一样的。在read view中可以知道当前事务可见的记录,顺着undo log版本链找到可见的行。

2.3 刷盘

undo log是存储在buffer pool内存中的,那如何持久化呢?

undo log在buffer pool中,对undo log的修改也会记录到redo log,redo log每秒进行刷盘,提交事务的时候也会刷盘,数据页和undo页都是通过这种机制持久化的。

3. buffer pool存储引擎缓存

在讲redo log前需要先说一下buffer pool

数据是存储在磁盘中的,磁盘的IO耗时高,需要缓存数据,减少磁盘的访问。

innodb存储引擎中有个缓冲池buffer pool,用来缓存页数据,提高读写性能。

读操作:直接从缓存中获取数据即可

写操作:修改缓存中数据,并将该页修改为脏页(缓存和磁盘数据不一致),后台线程会在合适的时机更新到磁盘中。

mysql启动时,会将buffer pool划分为多个页空间,其中包括数据页,索引页,undo页等。

4. redo log重做日志

实现了事务中的持久性,主要用于掉电等故障恢复

如下图中存储引擎中有buffer pool缓存提高了读写效率,但是内存中的数据一旦断电,还没有刷盘的脏页数据就会丢失,为了防止这种情况,innodb引擎在更新内容中数据时,会将该页数据以redo log的形式保存下来,

redo log记录某个数据页做了什么操作,例如xxx表的yyy数据页zzz偏移量的地方做了aaa操作。

在事务提交时,即可将该redo log持久化到磁盘中,不需要等脏页数据持久化到磁盘中。

当系统崩溃重启后,虽然脏页数据没有持久化到磁盘,但是可以用redo log中的内容恢复数据。

其中undo log内容的修改也会记录到redo log并持久化到磁盘中。

区别undo logredo logbinlog
记录内容记录更新之前的值记录更新之后的值所有的操作
产生时机事务开始时事务提交时每条操作
作用回滚、事务原子性恢复,事务持久性备份,主从复制

5. binlog归档日志

undo log与redo log都是innodb引擎层生成的。

是 Server 层生成的日志,主要用于数据备份和主从复制

数据完成一条更新操作就会产生一条binlog,在事务提交时,会将事务产生的所有binlog统一写入到binlog文件中,binlog记录数据表结构变更和数据变更,不会记录查询操作。

binlog日志是追加写,写满一个文件就会产生一个新的文件,不会覆盖之前的日志,保存全量日志,redo log是循环写,日志空间大小固定,写满从头开始写,保存未被刷入磁盘的脏页数据

5.1 数据备份场景

如果不小心将整个数据库的数据都删除了,可以用redo log恢复么?不能,因为redo log会擦除已经刷入磁盘的数据,只保留未被刷入磁盘的页数据,binlog记录了所有数据变更,需要用binlog恢复数据。

5.2 主从复制场景

步骤1.客户端提交事务后,先在server层写入binlog,然后将事务提交给引擎层,更新引擎层数据,返回给客户端事务提交成功。

步骤2.从库会有一个IO线程链接主库的log dump线程,接收主库的binlog日志,写入replay log中继日志中,返回主库复制成功。

步骤3.从库会创建一个回放binlog的线程,读取中继日志,回放binlog更新存储引擎中的数据,最终实现主从一致性。

参考自小林coding

http://www.dtcms.com/a/271158.html

相关文章:

  • 学习open62541 --- [79] 在docker中运行open62541工程
  • pytorch chunk 切块
  • 【C++】容器适配器 + stack/queue/deque详解
  • Java基础,反射破坏封装性 - 单例模式的崩塌
  • 掌握PDF转CAD技巧,提升工程设计效率
  • 第四节 chatPDF
  • 机器视觉之工业相机讲解
  • unity animtor播放动画的指定位置
  • spring boot使用mybatis-plus实现分页功能
  • C++学习笔记三
  • MATLAB基于voronoi生成三维圆柱形
  • Token 和 Embedding的关系
  • 基于AOP+Redis的简易滑动窗口限流
  • C#基础篇(10)集合类之列表
  • 列表页智能解析算法:大规模数据采集的核心引擎
  • 2024-2025-2 山东大学《编译原理与技术》期末(回忆版)
  • 【ARM嵌入式汇编基础】- 操作系统基础(二)
  • JSP数据交互
  • php绘图添加水印,文字使用imagick库的操作
  • Docker 高级管理-容器通信技术与数据持久化
  • C语言结构体对齐
  • SpringCloud系列 - xxl-job 分布式任务调度 (七)
  • 链表和数组和列表的区别
  • 力扣网编程150题:加油站(贪心解法)
  • Origin将Y偏移图升级为双Y轴3D瀑布图
  • SAP-ABAP:SAP中‘SELECT...WHERE...IN’语句IN的用法详解
  • 想要抢早期筹码?FourMeme专区批量交易教学
  • Cadence模块复用
  • SQL 视图与事务知识点详解及练习题
  • 基于Spring Boot+Vue的巴彦淖尔旅游网站(AI问答、腾讯地图API、WebSocket及时通讯、支付宝沙盒支付)