MySQL——日志

  • undo log(回滚日志)引擎层生成的日志,实现了事务的原子性,用于事务回滚和MVCC
  • redo log(重做日志)引擎层生成的日志,实现了事务的持久性,用于非正常关闭的数据恢复
  • bin log(归档日志)Server层生成的日志,主要用于数据备份和主从复制

undo log详解:

undo log是一种用于撤销回退的日志,在事务没提交之前,会先记录更新前的数据到undo log日志文件中,事务回滚时,可以利用undo log来进行回滚。

undo log中记录着update、insert、delete等修改操作的反操作。例如删除一条记录时,undo会先将记录中的内容先记录下来,并使用insert操作。

每个undo log都有一个roll_pointer指针和一个trx_id事务id

  • 通过事务id我们可知本次修改是哪个事务执行的
  • 通过roll_pointer我们可将undo log串成一个链表从最新指向最旧,这个链表就是版本链
  • 这两个字段是每行数据的隐藏字段
  • 每次事务开启时roll_pointer会指向开启前的undo log ,且该undo log作为版本链新的头节点

undo log利用版本链和Read View实现MVCC(多版本并发控制):

  • 对于读已提交可重复读隔离级别的事务来说,它们的快照读(普通select 语句)是通过Read View+undo log来实现的,它们的区别在于创建Read View的时机不同。
  • 读已提交每次select语句后都会生成一个新的Read View,也就是说可以看到其他事务提交的结果,可能会造成不可重复读。
  • 可重复读首次select语句后生成一个Read View,后续的查询都使用该Read View,期间其他事务的已提交数据无法感知,避免了不可重复读的问题。
  • 串行化无快照读不依赖Read View,通过加锁实现
Read View详解:
核心字段:
  • trx_ids:记录生成视图时系统中所有活跃(未提交)事务id的列表
  • min_trx_id活跃事务列表中的最小事务id,表示活跃事务的起始边界
  • max_trx_id+1即将分配的事务id,也就是当前最大事务id+1,表示未来事务的边界
  • m_creator_trx_id生成视图的当前事务id
可见性判断规则:
  • 可见:事务id<min_trx_id(该版本在Read View生成前就已提交
  • 不可见:事务id>max_trx_id||事务id包含在活跃事务列表中(Read View生成时处于未提交状态
  • 例外可见:事务id=m_creator_id(修改操作是生成视图的事务执行的

在实现这两个隔离级别的事务时,查询的行数据会通过事务id字段与Read View中的字段进行对比通过roll pointer在版本链中遍历直到找到可见的数据记录,从而并发控制事务访问同一个数据记录的行为,这就称为MVCC。

redo log详解:

Buffer Pool提高了读写效率,但它是基于内存的,遇到非正常关闭时会导致数据丢失

所以数据库更新记录时,会先在Buffer Pool中更新并标记为脏页随后将本次修改以redo log的形式记录下来,这时候更新操作才算完成了。

脏页数据刷盘时依然是根据Buffer Pool,日志用于崩溃恢复时重建脏页数据

后续,引擎会选择合适的时机异步刷盘脏页数据,这就是WAL(Write-Ahead Logging)技术。

WAL:MySQL的写操作不直接写入到磁盘上,而是先记录日志,再在合适的时机写入磁盘中。

redo具体记录什么?

  • redo log是物理日志记录了某个数据页做了什么修改,例如对XXX表空间中的YYY数据页ZZZ偏移量的地方做了AAA更新,每当执行一个事务时就有一条或者多条这样的物理日志。
  • 事务提交时,只需将redo log持久化到磁盘中即可,无需等待缓存中的脏页数据持久化。且redo log是顺序写入磁盘,Buffer Pool是随机写入,需要时间寻找可用空间。因此日志的持久化是远远快于完整数据持久化的。
  • 系统崩溃时,MySQL就可以根据redo log重构脏页数据,恢复到最新状态。

产生的redo log是否直接写入磁盘中?

  • 实际上,redo log也并非直接写入磁盘中,因为这样会产生大量IO操作,而且磁盘的运行速度远低于内存
  • redo log也有自己的缓存——redo log buffer,每当有redo log产生,会先写入到缓存中,后续再进行持久化。缓存默认大小16mb,可以通过innodb_log_Buffer_size参数动态调整大小,增大它的大小可以让MySQL处理大事务时不必直接写入磁盘

redo log什么时候刷盘?

  • MySQL正常关闭
  • redo log buffer记录的写入量大于redo log buffer内存空间的一半
  • InnoDB的后台线程每隔一秒刷盘一次
  • 每次事务提交时都将缓存持久化到磁盘(可选策略,通过innodb_flush_log_at_trx_commit参数控制)

redo log文件写满了怎么办?

  • 默认情况下,InnoDB存储引擎有1个重做日志组日志组由2个redo log文件组成,分别名为ib_logfile0和ib_logfile1
  • 两个文件的大小是固定且一致的,文件组是以循环写的方式工作的,类似于循环队列
  • 所以file0会先被写满,写满后切换至file1,file1写满后又会回到file0
  • redo log是为防止脏页数据意外丢失而存在的,当脏页数据已经持久化到磁盘中,我们就需要从redo log中移除对应的记录。check point相当于要擦除(覆盖)的位置(类似于redis的环形缓存区

  • write pos和checkpoint的移动都是顺时针方向;
  • write pos到checkpoint之间的部分,用于记录新的更新操作
  • checkpoint到write pos之间的部分,为待持久化的脏页数据记录
  • 若write pos追上了checkpoint,意味着redo log文件已满,此时MySQL不能执行新的更新操作,导致MySQL阻塞阻塞时会将Buffer Pool的脏页刷新到磁盘中,然后标记redo log哪些记录可以被擦除,接着对旧的redo log记录进行擦除,等待文件腾出空间后checkpoint继续移动,MySQL恢复正常运行
  • 对于并发量大的系统,适当设置redo log的文件大小非常重要,否则容易导致MySQL阻塞

redo log和undo log的区别?

  • redo log:记录的是事务修改后的数据状态,记录的是更新后的值,用于事务崩溃恢复,保证事务的持久性。
  • undo log:记录了事务修改前的数据状态,记录的是更新前的值,用于事务回滚,保证事务的原子性。
  • 事务提交前发生错误可通过undo log回滚,即使是崩溃也没事,因为事务没提交的数据本身就是无效的。
  • redo log针对的是事务提交后但数据还未持久化就发生崩溃的场景,重启后MySQL可根据redo log恢复事务

有了redo log后,通过WAL技术,就可以保证即使数据库异常关闭重启,之前提交的记录都不会丢失,这个能力就称为crash-safe(崩溃恢复)。保证了数据的持久性和一致性

binlog详解

前文介绍的undo log和redo log都是Innodb存储引擎生成的

MySQL完成更新操作后server层会生成一条binlog事务提交后会将该事务执行产生的所有binlog统一写入binlog文件中。

binlog文件记录了所有数据库表结构变更表数据修改的操作,但不会记录查询相关操作。

为什么还需要redo log?

最开始MySQL并没有Innodb引擎,使用的是MyISAM引擎,所以没有crash-safe特性bin log只能用于归档,而redo log可实现crash-safe。

redo log和bin log的区别:

1、适用对象不同:
  • binlog是MySQL的server层实现的日志,所有引擎都可以使用
  • redo log是Innodb引擎实现的日志
2、文件格式不同:
  • binlog 有 3 种格式类型,分别是 STATEMENT(默认格式)、ROW、 MIXED,区别如下:   
  1. STATEMENT:每一条修改数据的 SQL 都会被记录到 binlog 中(相当于记录了逻辑操作,所以针对这种格式, binlog 可以称为逻辑日志),主从复制中 slave 端再根据 SQL 语句重现。但 STATEMENT 有动态函数的问题,比如你用了 uuid 或者 now 这些函数,你在主库上执行的结果并不是你在从库执行的结果,这种随时在变的函数会导致复制的数据不一致;
  2.  ROW:记录行数据最终被修改成什么样了(这种格式的日志,就不能称为逻辑日志了),不会出现 STATEMENT 下动态函数的问题。但 ROW 的缺点是每行数据的变化结果都会被记录,比如执行批量 update 语句,更新多少行数据就会产生多少条记录,使 binlog 文件过大,而在 STATEMENT 格式下只会记录一个 update 语句而已;
  3.  MIXED:包含了 STATEMENT 和 ROW 模式,它会根据不同的情况自动使用 ROW 模式和 STATEMENT 模式;
  • redo log是物理日志,记录的是某个数据页做了什么修改,比如对XXX表空间中的YYY数据页ZZZ偏移量的地方做了AAA更新。
3、写入方式不同:
  • binlog是追加写,写满一个文件,就创建一个新的文件继续写入不会覆盖以前的日志,保存的是全量日志
  • redo log是循环写,日志空间大小固定,全部写满就从头开始,保存未被刷入磁盘的脏页数据
4、用途不同:
  • binlog用于备份恢复、主从复制
  • redo log用于崩溃等故障的数据恢复

主从复制如何实现?

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

三个阶段:
  • 写入binlog:主库写binlog日志,提交事务,并更新本地存储数据
  • 同步binlog:将binlog复制到所有从库上,每个从库将binlog写到暂存日志中
  • 回放binlog:恢复binlog,更新存储引擎中的数据

binlog什么时候刷盘?

  • 事务执行过程中,日志先写到binlog cache(Server层的缓存),事务提交时再将缓存中的日志写到binlog文件中
  • 一个事务的binlog是不能拆开的,需要保证一次性写入避免破坏原子性,也对应一个线程只能同时执行一个事务的设定。
  • MySQL为每个线程分配了一片内存用于缓冲binlog,该内存叫binlog cache,参数binlog_cache_size用于控制单个线程内binlog cache所占内存的大小
  • 事务提交时,执行器将binlog cache里的完整事务写入到binlog文件中,并清空缓存

write操作即为写到binlog文件中但并不是持久化,而是在内核缓存中存储,不涉及磁盘io

fsync才是真正的刷盘操作,涉及磁盘io

MySQL提供一个sync_binlog参数(默认为0)来控制数据库的binlog刷到磁盘上的频率:

  • sync_binlog=0时,表示每次提交事务都只write,不fsync,后续交由操作系统决定何时将数据持久化到磁盘。
  • sync_binlog=1时,表示每次提交事务都会write,并马上执行fsync
  • sync_binlog=N时,表示每次提交事务都会write,但积累N个事务后才fsync

update语句的执行过程:

优化器分析出成本最小的执行计划后,执行器按照执行计划开始更新:

1、执行器调用存储引擎接口,通过索引查询记录
  •         若该条记录所在的页存在于Buffer Pool中,直接返回给执行器使用
  •         若该条记录在Buffer Pool中,则从磁盘读取对应数据页到Buffer Pool中,并返回给执行器
2、执行器得到聚簇索引记录后,会比较更新前和更新后的记录是否一样
  •         若一样则直接跳过后续的日志写入、事务提交等操作。
  •         若不一样则将修改前和修改后的记录都作为参数传入InnoDB层,执行真正的更新记录操作。
3、开启事务,记录undo log,写入Buffer Pool的Undo页面,Undo页面变化时记录对应的redo log
4、InnoDB层开始更新记录,并更新内存(同时标记为脏页),然后将记录写入redo log里面,此时更新操作完成。
  •         为减少磁盘IO并不直接将脏页写入磁盘中,而是先记录redo日志,后寻找合适时机刷盘脏页数据。也就是WAL技术。
5、至此,更新语句结束。
  •         语句完成后,记录该语句对应的binlog,此时记录的binlog会被保存到binlog cache,并没有刷新到磁盘上的binlog文件,事务提交时才会统一将该事务运行过程中的所有的binlog文件刷新到磁盘(中途会先write到内核的页缓存中)中。
6、两阶段提交日志。

为什么需要两阶段提交?

事务提交后,redo log和binlog都需要持久化到磁盘中,但这两个是独立逻辑,可能出现半成功的情况,造成数据不一致,需要确保它们提交的原子性

redo log提交成功,binlog提交失败。主库数据更新成功但binlog丢失记录,进而导致主从复制时从库数据是旧的,以及备份的数据不一致。

binlog提交成功,redo log提交失败。主库数据更新丢失,但从库和备份有记录,导致主库数据是旧的,数据不一致。

两阶段提交则是将单个事务拆分为了两个阶段:prepare阶段和Commit阶段。每个阶段由协调者和参与者共同完成。这里的Commit阶段与commit语句不同,commit语句包含了这里的Commit阶段

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QML 动画控制、顺序动画与并行动画

目录 引言相关阅读基础属性说明工程结构示例代码解析示例1&#xff1a;手动控制动画&#xff08;ControlledAnimation.qml&#xff09;示例2&#xff1a;顺序动画&#xff08;SequentialAnimationDemo.qml&#xff09;示例3&#xff1a;并行动画&#xff08;ParallelAnimationD…

PowerShell 实现 conda 懒加载

问题 执行命令conda init powershell会在 profile.ps1中添加conda初始化的命令。 即使用户不需要用到conda&#xff0c;也会初始化conda环境&#xff0c;拖慢PowerShell的启动速度。 解决方案 本文展示了如何实现conda的懒加载&#xff0c;默认不加载conda环境&#xff0c;只…

R语言学习--Day03--数据清洗技巧

在一般情况下&#xff0c;我们都是在数据分析的需求前提下去选择使用R语言。而实际上&#xff0c;数据分析里&#xff0c;百分之八十的工作&#xff0c;都是在数据清洗。并不只是我们平时会提到的异常值处理或者是整合格式&#xff0c;更多会涉及到将各种各样的数据整合&#x…

谷歌地图代理 | 使用 HTML 和矢量模式 API 更轻松地创建 Web 地图

在过去的一年里&#xff0c;谷歌对 Maps JavaScript API 进行了两项重要更新&#xff0c;以便更轻松地采用我们最新、最好的地图&#xff1a;HTML 地图和矢量模式 API。今天谷歌地图亚太区最大代理商之一的 Cloud Ace云一 为大家介绍一下更新的具体内容。 联系我们 - Cloud Ac…

WL-G4048 Multi-Port PCIe 4.0 Switch

系列文章目录 文章目录 系列文章目录《WL-G4048 Multi-Port PCIe 4.0 Switch数据手册》总结一、芯片介绍二、芯片规格介绍&#xff08;一&#xff09;功能指标&#xff08;二&#xff09;管理调试和监控&#xff08;三&#xff09;参考时钟&#xff08;四&#xff09;系统复位 …

召回11:地理位置召回、作者召回、缓存召回

GeoHash 召回 属于地理位置召回&#xff0c;用户可能对附近发生的事情感兴趣。GeoHash 是一种对经纬度的编码&#xff0c;地图上每个单位矩形的 GeoHash 的前几位是相同的&#xff0c;GeoHash 编码截取前几位后&#xff0c;将相同编码发布的内容按时间顺序&#xff08;先是时间…

高效批量合并Word文档的工具介绍

软件介绍 本文介绍一款专门用于批量合并Word文档的工具&#xff0c;名为批量合并word工具。 使用方法与特点 如果需要将多个Word文档合并到一个Word文档中&#xff0c;就可以使用这款工具。使用前&#xff0c;需把要合并的Word文档都放在名为“word”的文件夹下。 该软件没有…

机器学习入门之KNN算法和交叉验证与超参数搜索(三)

机器学习入门之KNN算法和交叉验证与超参数搜索&#xff08;三&#xff09; 文章目录 机器学习入门之KNN算法和交叉验证与超参数搜索&#xff08;三&#xff09;一、KNN算法-分类1. 样本距离判断明可夫斯基距离 2. KNN 算法原理3. KNN 的缺点4. KNN 的 API5. 使用 sklearn 实现 …

小刚说C语言刷题—1700请输出所有的2位数中,含有数字2的整数

1.题目描述 请输出所有的 2 位数中&#xff0c;含有数字 2 的整数有哪些&#xff0c;每行 1个&#xff0c;按照由小到大输出。 比如&#xff1a; 12、20、21、22、23… 都是含有数字 2的整数。 输入 无 输出 按题意要求由小到大输出符合条件的整数&#xff0c;每行 1 个。…

在MYSQL中导入cookbook.sql文件

参考资料&#xff1a; GitHub 项目&#xff1a;svetasmirnova/mysqlcookbook CSDN 博客&#xff1a;https://blog.csdn.net/u011868279/category_11645577.html 建库&#xff1a; mysql> use mysql Reading table information for completion of table and column names …

Scrapy框架下地图爬虫的进度监控与优化策略

1. 引言 在互联网数据采集领域&#xff0c;地图数据爬取是一项常见但具有挑战性的任务。由于地图数据通常具有复杂的结构&#xff08;如POI点、路径信息、动态加载等&#xff09;&#xff0c;使用传统的爬虫技术可能会遇到效率低下、反爬策略限制、任务进度难以监控等问题。 …

【Win32 API】 lstrcmpA()

作用 比较两个字符字符串&#xff08;比较区分大小写&#xff09;。 lstrcmp 函数通过从第一个字符开始检查&#xff0c;若相等&#xff0c;则检查下一个&#xff0c;直到找到不相等或到达字符串的末尾。 函数 int lstrcmpA(LPCSTR lpString1, LPCSTR lpString2); 参数 lpStr…

代码随想录60期day38

2维背包 #include<bits/stdc.h> using namespace std;int main(){int n,bagweight;cin>>n>>bagweight;vector<int>weight(n,0);vector<int>value(n,0);for(int i 0 ; i <n;i){cin>>weight[i];}for(int j 0;j<n;j){cin>>val…

[模型部署] 1. 模型导出

&#x1f44b; 你好&#xff01;这里有实用干货与深度分享✨✨ 若有帮助&#xff0c;欢迎&#xff1a;​ &#x1f44d; 点赞 | ⭐ 收藏 | &#x1f4ac; 评论 | ➕ 关注 &#xff0c;解锁更多精彩&#xff01;​ &#x1f4c1; 收藏专栏即可第一时间获取最新推送&#x1f514;…

mac的Cli为什么输入python3才有用python --version显示无效,pyenv入门笔记,如何查看mac自带的标准库模块

根据你的终端输出&#xff0c;可以得出以下结论&#xff1a; 1. 你的 Mac 当前只有一个 Python 版本 系统默认的 Python 3 位于 /usr/bin/python3&#xff08;这是 macOS 自带的 Python&#xff09;通过 which python3 确认当前使用的就是系统自带的 Pythonbrew list python …

Java注解详解:从入门到实战应用篇

1. 引言 Java注解&#xff08;Annotation&#xff09;是JDK 5.0引入的一种元数据机制&#xff0c;用于为代码提供附加信息。它广泛应用于框架开发、代码生成、编译检查等领域。本文将从基础到实战&#xff0c;全面解析Java注解的核心概念和使用场景。 2. 注解基础概念 2.1 什…

前端方法的总结及记录

个人简介 &#x1f468;‍&#x1f4bb;‍个人主页&#xff1a; 魔术师 &#x1f4d6;学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全栈发展 &#x1f6b4;个人状态&#xff1a; 研发工程师&#xff0c;现效力于政务服务网事业 &#x1f1e8;&#x1f1f3;人生格言&…

组件导航 (HMRouter)+flutter项目搭建-混合开发+分栏效果

组件导航 (Navigation)flutter项目搭建 接上一章flutter项目的环境变量配置并运行flutter 1.flutter创建项目并运行 flutter create fluter_hmrouter 进入ohos目录打开编辑器先自动签名 编译项目-生成签名包 flutter build hap --debug 运行项目 HMRouter搭建安装 1.安…

城市排水管网流量监测系统解决方案

一、方案背景 随着工业的不断发展和城市人口的急剧增加&#xff0c;工业废水和城市污水的排放量也大量增加。目前&#xff0c;我国已成为世界上污水排放量大、增加速度快的国家之一。然而&#xff0c;总体而言污水处理能力较低&#xff0c;有相当部分未经处理的污水直接或间接排…

TCP/IP 知识体系

TCP/IP 知识体系 一、TCP/IP 定义 全称&#xff1a;Transmission Control Protocol/Internet Protocol&#xff08;传输控制协议/网际协议&#xff09;核心概念&#xff1a; 跨网络实现信息传输的协议簇&#xff08;包含 TCP、IP、FTP、SMTP、UDP 等协议&#xff09;因 TCP 和…