MySQL进阶(日志)——MySQL的日志 bin log (归档日志) 事务日志redo log(重做日志) undo log(回滚日志)

在这里插入图片描述

前言

MySQL最为最流行的开源数据库,其重要性不言而喻,也是大多数程序员接触的第一款数据库,深入认识和理解MySQL也比较重要。

本篇博客阐述MySQL的日志,介绍重要的bin log (归档日志) 、 事务日志redo log(重做日志) 、 undo log(回滚日志)。

本系列文章合集如下:

【合集】MySQL的入门进阶强化——从 普通人 到 超级赛亚人 的 华丽转身

在这里插入图片描述

目录

  • 前言
  • 引出
  • 一、MySQL日志分类
  • 二、Redo Log
    • 1. redo log重做日志的组成
    • 2. 刷盘的时机
  • 三、undo log (事务回滚)
  • 四、Bin log
    • 两阶段提交
    • 为什么需要两阶段提交?
    • MySQL主从复制
  • 总结

引出


1.二进制日志bin log (归档日志)事务日志redo log(重做日志)undo log(回滚日志)
2.bin log用于备份恢复、主从复制;redo log用于掉电等故障恢复;
3.redo log一旦提交意味着持久化了,但是有时候需要对其进行rollback操作,那就需要undo log;
4.主从:写数据时只写主库,在读数据时只读从库,这样即使写请求会锁表或者锁记录,也不会影响读请求的执行;

一、MySQL日志分类

MySQL日志主要包括错误日志、查询日志、慢查询日志、事务日志、二进制日志几大类。其中,比较重要的还要属二进制日志binlog (归档日志)事务日志redo log(重做日志)undo log(回滚日志)

MySQL日志主要包括七种:

  • 1.重做日志(redo log)
  • 2.回滚日志(undo log)
  • 3.归档日志(bin log)
  • 4.错误日志(error log)
  • 5.慢查询日志(slow query log)
  • 6.一般查询日志(general log)
  • 7.中继日志(relay log)

二、Redo Log

redo log(重做日志)是nnoDB存储引擎独有的,它让MySQL拥有了崩溃恢复能力。比如MySQL实例挂了或宕机了,重启时,InnoDB存储引擎会使用redo log恢复数据

(1)redo log是物理日志,纪录页的物理修改操作

  • 记录的是在某个数据页做了什么修改,比如对x表空间中的N数据页ZZZ偏移量的地方做了AAA更新:

(2)保证数据的持久性

  • 持久性,redo log会在事务提交时将日志存储到磁盘redo log file,保证日志的持久性。同时mysql会将数据写入磁盘,保证数据的持久性。

1. redo log重做日志的组成

  • 一是内存中的重做日志缓存,叫做redo log buffer

  • 二是重做日志文件,叫做redo log file

MySQL中数据是以页为单位,你查询一条记录,会从硬盘把一页的数据加载出来,加载出来的数据叫数据页,会放入到Buffer Pool中。后续的查询都是先从Buffer Pool中找,没有命中再去硬盘加载,减少硬盘IO开销,提升性能。

更新表数据的时候,也是如此,发现Buffer Pool里存在要更新的数据,就直接在Buffer Pool里更新。然后会把在某个数据页上做了什么修改记录到重做日志缓存(redo log buffer)里,接着刷盘到redo log文件里。同时,InnoDB引擎会在适当的时候,将这个操作记录更新到磁盘里面。

redo log的更新流程如下,以一次update操作为例

在这里插入图片描述

在这里插入图片描述

(1)执行Update操作

(2)先将原始数据读从磁盘读取到内存,修改内存中的数据。

(3)生成一条重做日志写入redo log buffer ,纪录数据被修改后的值。

(4)当事物提交时,需要将redo log buffer中的内容刷新到redo log file。

(5)事物提交后,也会将内存中修改的数据写入到磁盘。

为什么需要写Redo Log Buffer 和 Redo Log Flle?

为什么需要写Redo Log Buffer 和 Redo Log Flle?而不是直接持久化到磁盘?

直接写磁盘会有产生严重的性能问题:
(1)InnoDB在磁盘中存储的基本单元是页,可能本次修改只变更一页中几个字节,但是需要刷新整页的数据,就很浪费资源。
(2)一个事务可能修改了多页中的数据,页之间又是不连续的,就会产生随机IO,性能更差。

这种方案叫做WAL(Write-Ahead Logging),预写日志,就是先写日志,再写磁盘.

2. 刷盘的时机

InnoDB存储引擎为redo log的刷盘策略提供了innodb-f1ush_log-at_-trX-commit参数,它支持三种策略:

(1) 0(延迟写) :表示每次事务提交时都只是把redo log留在redo log buffer中,开启一个后台线程,每1s刷新一次到磁盘中;

在这里插入图片描述

(2)1(实时写,实时刷):表示每次事务提交时都将redo log直接持久化到磁盘,真正保证数据的持久性(默认值);

在这里插入图片描述

刷盘的时机为1时,只要事务提交成功,redo log记录就一定在硬盘里,不会有任何数据丢失

如果事务执行期间MySQL挂了或宕机,这部分日志丢了,但是事务并没有提交,所以日志丢了也不会有损失。

(3)2(实时写,延迟刷):表示每次事务提交时都只是把 redo log 写到 page cache,每秒刷一次到磁盘(速度快,但是会丢1s的数据,甚至更多,1s并不严格)

在这里插入图片描述

三、undo log (事务回滚)

redo log一旦提交意味着持久化了,但是有时候需要对其进行rollback操作,那就需要undo log。

undo log是逻辑日志,只是将数据库逻辑的恢复到原来的样子。并不能将数据库物理地恢复到执行语句或者事务之前的样子。虽然所有的逻辑修改均被取消了,但是数据结构和页本身在回滚前后可能不一样了。

既然是逻辑日志,可以理解为它存储的是SQL, 在事务中使用的每一条 INSERT 都对应了一条 DELETE,每一条 UPDATE 也都对应一条相反的 UPDATE 语句。

在这里插入图片描述

undo log实现了事务的一致性,是通过undo log恢复到事务之前的逻辑状态,保证一致性。

在事务没提交之前,MySQL会先记录更新前的数据到undo log日志文件里面,当事务回滚时,可以利用undo log来进行回滚。如下图:

在这里插入图片描述

Undo Logi通过两个隐藏列tx_id(最近一次提交事务的ID)和roll_pointer(上个版本的地址),建立一个版本链,实现回滚到上一个版本。

在这里插入图片描述

四、Bin log

bin log用于备份恢复、主从复制;
redo log用于掉电等故障恢复。

(1) 如果不小心整个数据库的数据被删除了,能使用redo log文件恢复数据吗?

不可以使用redo log文件恢复,只能使用binlog文件恢复。

因为redo log文件是循环写,是会边写边擦除日志的,只记录未被刷入磁盘的数据的物理日志,已经刷入磁盘的数据都会从redo log文件里擦除。

binlog文件保存的是全量的日志,也就是保存了所有数据变更的情况,理论上只要记录在binlog上的数据,都可以恢复,所以如果不小心整个数据库的数据被删除了,得用binlog文件恢复数据。

(2) MySQL在完成一条更新操作后,Server.层会生成一条binlog,Bin Log也是采用WL模式,先写日志,再写磁盘。

事务执行过程中,先把日志写到binlog cache,事务提交的时候,再把binlogcache写到binlog文件中。

因为一个事务的binlog?不能被拆开,无论这个事务多大,也要确保一次性写入,所以系统会给每个线程分配一块内存作为binlog cache。

至于什么时候刷新到磁盘,可以sync_binlog配置参数指定。

  • 0(延迟写)每次提交事务都不会刷盘,由系统自己决定什么时候刷盘,可能会丢失数据。
  • 1(实时写)每次提交事务,都会刷盘,性能较差。
  • N(延迟写)提交N个事务后,才会刷盘。

加入写Bin Log 后的事务流程

在这里插入图片描述

加入写Bin Log.之后的事务流程,先写处于prepare状态的Redo Log,事务提交后,再写处于commit状态的Redo Log,这就是二阶段提交的概念。

两阶段提交

redo log(重做日志)让 InnoDB 存储引擎拥有了崩溃恢复能力。
bin log(归档日志)保证了MySQL集群架构的数据一致性。

bin log是MySQL Server提供的一种日志,叫做归档日志,所有引擎都可以使用bin log。

redo log是 InnoDB 引擎特有的。
redo log主要记录的是某个数据页做了什么修改,bin log记录的是语句的原始逻辑,比如更新了某一行的某个字段。
redo log是循环写的,数据会被覆盖。bin log是追加写,一个文件写满,就写下一个文件。

两者是如何配合完成两阶段提交的。

在这里插入图片描述

从上图中可以看出,在最后提交事务的时候,有3个步骤:
1.写入redo log,处于prepare状态。
2.写bin log。
3.修改redo log状态变为commit。

先写处于prepare状态的Redo Log,事务提交后,再写处于commit状态的Redo Log。由于redo log的提交分为prepare和commit两个阶段,所以称之为两阶段提交。

为什么需要两阶段提交?

(1) redo log与bin log两份日志之间的逻辑不一致,会出现什么问题?

以updatei语句为例,假设id=2的记录,字段c值是0,把字段c值更新成1,SQL语句为update T set c=1 where id=2。假设执行过程中写完redo log日志后,binlog日志写期间发生了异常,会出现什么情况呢?由于binlog没写完就异常,这时候binlog里面没有对应的修改记录。因此,之后用binlog日志恢复数据时,就会少这一次更新,恢复出来的这一行c值是0,而原库因为redo log日志恢复,这一行c值是1,最终数据不一致。

为了解决两份日志之间的逻辑一致问题,InnoDB存储引擎使用两阶段提交方案。

(2)使用两阶段提交后,写入bin log时发生异常也不会有影响,因为MySQL根据redo log日志恢复数据时,发现redo log还处于prepare阶段,并且没有对应bin log日志,就会回滚该事务。

在这里插入图片描述

(3)再看一个场景,redo log设置commit阶段发生异常,那会不会回滚事务呢?

并不会回滚事务,虽然redo log是处于prepare 阶段,但是能通过事务id找到对应的bin log日志,所以MySQL认为是完整的,就会提交事务恢复数据。

在这里插入图片描述

MySQL主从复制

MySQL的主从复制依赖于bin log,也就是记录MySQL上的所有变化并以二进制形式保存在磁盘上。复制的过程就是将bin log中的数据从主库传输到从库上。

这个过程一般是异步的,也就是主库上执行事务操作的线程不会等待复制binlog的线程同步完成。

MySQL集群的主从复制过程梳理成3个阶段:

  • 写入Bin log:主库写bin log日志,提交事务,并更新本地存储数据,
  • 同步Bin log:把bin log复制到所有从库上,每个从库把bin log写到暂存日志中。
  • 回放Bin log:回放bin log,并更新存储引擎中的数据。

在这里插入图片描述

具体详细过程如下:

  • MySQL主库在收到客户端提交事务的请求之后,会先写入bin log,再提交事务,更新存储引擎中的数据,事务提交完成后,返回给客户端“操作成功的响应。
  • 从库会创建一个专门的/o线程,连接主库的log dump线程,来接收主库的bin log日志,再把bin log信息写入relay log的中继日志里,再返回给主库“复制成功的响应
  • 从库会创建一个用于回放bin log的线程,去读relay log中继日志,然后回放bin log更新存储引擎中的数据最终实现主从的数据一致性。

在完成主从复制之后,你就可以在写数据时只写主库,在读数据时只读从库,这样即使写请求会锁表或者锁记录,也不会影响读请求的执行。

从库数量增加,从库连接上来的/O线程也比较多,主库也要创建同样多的log dump线程来处理复制的请求,对主库资源消耗比较高,同时还受限于主库的网络带宽

所以在实际使用中,一个主库一般跟2~3个从库(1套数据库,1主2从1备主),这就是一主多从的MySQL集群结构。


总结

1.二进制日志bin log (归档日志)事务日志redo log(重做日志)undo log(回滚日志)
2.bin log用于备份恢复、主从复制;redo log用于掉电等故障恢复;
3.redo log一旦提交意味着持久化了,但是有时候需要对其进行rollback操作,那就需要undo log;
4.主从:写数据时只写主库,在读数据时只读从库,这样即使写请求会锁表或者锁记录,也不会影响读请求的执行;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/105345.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Rookit系列二【文件隐藏】【支持Win7 x32/x64 ~ Win10 x32/x64平台的NTFS文件系统】

文章目录 前言探究代码演示 前言 文件隐藏的方法有很多,这里分享的是一种通过内核文件重定向的方式动态规避检测的方法。举例:假设有一个安全软件A,A要扫描文件B,B是我们想要隐藏的文件。那么我们在内核中将A打开文件B的操作重定…

MFC 注册表

文章目录 打开注册表对注册表的键的操作创建子键删除子键遍历子键 对注册表值的操作读取值设置值 打开注册表 void CREGDemoDlg::OnBnClickedBtnOpen() {//打开注册表HKEY hKey;if (ERROR_SUCCESS ! RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Baidu.com", 0, KEY…

JS加密/解密之那些不为人知的基础逻辑运算符

不多说,直接上干货 使用逻辑非运算符 ! 和双重逻辑非运算符 !!:例如 ![]、!![]、!0、!!0 和 !""、!!""。空字符串的转换:!"" 和 !!""。数组和对象的类型转换:[] []、[] - []、{} [] 和…

2023年中国汽车覆盖件模具竞争格局、市场规模及行业需求前景[图]

汽车覆盖件模具是汽车车身生产的重要工艺装备,其设计和制造时间约占汽车开发周期的 2/3,是汽车换型的重要制约因素之一。汽车覆盖件模具具有尺寸大、工作型面复杂、技术标准高等特点,属于技术密集型产品。汽车覆盖件模具按以其冲压的汽车覆盖…

如何在linux服务器上安装Anaconda与pytorch,以及pytorch卸载

如何在linux服务器上安装Anaconda与pytorch,以及pytorch卸载 1,安装anaconda1.1 下载anaconda安装包1.2 安装anaconda1.3 设计环境变量1.4 安装完成验证 2 Anaconda安装pytorch2.1 创建虚拟环境2.2 查看现存环境2.3 激活环境2.4 选择合适的pytorch版本下…

基于ssm的宠物医院管理系统的设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…

hibernate源码(2)--- springboot-jpa是如何引入的

starter引入 要想看jpa是如何将hibernate引入容器,首先要看的是 spring-boot-starter-data-jpa 如何引入依赖: 如果注意的话,starter的包内容其实没有什么实质的内容,关键是pom里的依赖 pom中规定了各依赖和依赖的版本&#xf…

Docker 容器服务的注册、发现及Docker安全

目录 Docker容器服务的注册和发现 1、什么是服务注册与发现? 2、什么是consul consul的部署 1、环境准备 2、部署consul服务器 1)建立 Consul 服务 2)设置代理,在后台启动 consul 服务端 3)查看集群信息 4&a…

BES2700 蓝牙协议之RFCOMM通道使用方法

是否需要申请加入数字音频系统研究开发交流答疑群(课题组)?可加我微信hezkz17, 本群提供音频技术答疑服务 BES2700 RFCOMM通道使用方法 RFCOMM_CHANNEL_NUM 枚举定义了一系列的通道号码,并为每个通道号码指定了一个具体的名称。以下是其中一些通道的中文含义: RFCOMM_CHAN…

RustDay06------Exercise[91-100]

91.将指针还原成指定类型 因为指针不知道里面具体有什么,所以一般约定打上unsafe 申明开发者自己对该部分可用性负责,且在调试的时候也能起强调作用 // tests6.rs // // In this example we take a shallow dive into the Rust standard librarys // unsafe functions. Fix …

大数据Flink(一百零二):SQL 聚合函数(Aggregate Function)

文章目录 SQL 聚合函数(Aggregate Function) SQL 聚合函数(Aggregate Function) Python UDAF,即 Python AggregateFunction。Python UDAF 用来针对一组数据进行聚合运算,比如同一个 window 下的多条数据、或者同一个 key 下的多条数据等。针对同一组输入数据,Python A…

2017年亚太杯APMCM数学建模大赛B题喷雾轨迹规划问题求解全过程文档及程序

2017年亚太杯APMCM数学建模大赛 B题 喷雾轨迹规划问题 原题再现 喷釉工艺用喷釉枪或喷釉机在压缩空气下将釉喷入雾中,使釉附着在泥体上。这是陶瓷生产过程中一个容易实现自动化的过程。由于不均匀的釉料在烧制过程中会产生裂纹,导致工件报废&#xff0…

Dubbo 路由及负载均衡性能优化

作者:vivo 互联网中间件团队- Wang Xiaochuang 本文主要介绍在vivo内部针对Dubbo路由模块及负载均衡的一些优化手段,主要是异步化缓存,可减少在RPC调用过程中路由及负载均衡的CPU消耗,极大提升调用效率。 一、概要 vivo内部Java…

AIR101 LuatOS LVGL 显示多个标签例程

屏幕资料 AIR101与屏幕连接 PC端仿真环境合宙官方PC端版本环境搭建教程 PC电脑仿真 -- sys库是标配 _G.sys require("sys") sys.taskInit(function()local cnt0lvgl.init(480,320)--lvgl初始化local cont lvgl.cont_create(nil, nil);-- lvgl.cont_set_fit(cont, …

2023 年最佳开源软件

InfoWorld 公布了 2023 年最佳开源软件榜单,旨在表彰年度领先的软件开发、数据管理、分析、人工智能和机器学习开源工具。 上榜的 25 个软件涵盖编程语言、运行时、应用程序框架、数据库、分析引擎、机器学习库、大型语言模型 (LLM)、用于部署 LLM 的工具等领域 Ap…

李沐——论文阅读——VIT(VIsionTransformer)

一、终极结论: 如果在足够多的数据上面去做预训练,那么,我们也可以不用 卷积神经网络,而是直接用 自然语言处理那边搬过来的 Transformer,也能够把视觉问题解决的很好 (tips:paperswithcode.co…

【保姆级教程】:docker搭建MongoDB三节点副本集

容器可以理解为一个进程,镜像是把环境,组件等都配置好,运行成容器的,容器里面运行服务,也可以说是一个进程。镜像是模板,镜像是实例。 一个镜像可以创建多个实例。也就是多个容器,容器之间相互…

18.1 Socket 原生套接字抓包

原生套接字抓包的实现原理依赖于Windows系统中提供的ioctlsocket函数,该函数可将指定的网卡设置为混杂模式,网卡混杂模式(Promiscuous Mode)是常用于计算机网络抓包的一种模式,也称为监听模式。在混杂模式下&#xff0…

ThinkPHP8学习笔记

ThinkPHP8官方文档地址:ThinkPHP官方手册 一、composer换源 1、查看 composer 配置的命令composer config -g -l 2、禁用默认源镜像命令composer config -g secure-http false 3、修改为阿里云镜像源composer config -g repo.packagist composer https://mirror…

Ubuntu环境下DOSBOX的配置

【步骤一】 先打开命令行,进入root模式,输入如下语句: sudo apt-get install dosbox 该语句的作用主要是安装dosbox 【步骤二】 安装完成之后,命令行输入dosbox 会进入dosbox页面: 【步骤三】 在你的主机中&…