MySQL(日志)

日志

日志分为三种:
undo log (回滚日志):用于事务回滚和MVCC
redo log (重做日志):用于故障恢复
binlog (归档日志):用于数据备份和主从复制

undo log

undo : 撤销

undo log :在Innodb存储引擎层生成的日志

在这里插入图片描述

一条记录的每一次更新操作产生的undo log格式都有一个roll_pointer指针和一个trx_id事务id:

  1. 通过trx_id可以知道该记录是被哪个事务修改的;
  2. 通过roll_pointer指针可以将这些undo log 串成一个链表,这个链表可以称为版本链

undo log 通过ReadView + undo log 实现MVCC(多版本并发控制)

undo log 两大作用:

  1. 实现事务回滚,保障事务的原子性。
  2. 实现MVCC关键因素之一。

Buffer pool(缓冲池)

建立Buffer pool的目的:提高读写效率。

MySQL读取一条记录时,先从磁盘读取该记录,然后在内存中修改该记录。修改完不直接写回磁盘,而是缓存起来,下次命中,直接从缓存中拿

InnoDB设计了一个缓冲池(Buffer Pool),来提高数据库的读写性能。

  1. 当读取数据时,如果数据存在于Buffer pool中,那么直接从Buffer pool中拿,否则从磁盘中拿。
  2. 修改数据时,如果数据存在于Buffer pool中,那么直接修改Buffer pool中数据所在的页,然后将其页设置为脏页,为了减少磁盘IO,不会立即将脏页写入磁盘,后续由后台线程选择一个合适的时机将脏页写入磁盘。

Buffer pool中的数据存储,和磁盘一样,是以页为单位,与磁盘的数据交换也是以页为单位。一页默认为16KB。

Buffer pool 除了缓存【索引页】和【数据页】,还包括 Undo页,插入缓存、自适应哈希索引、锁信息等。

Buffer pool

redo log

断电丢失问题:Buffer pool是基于内存的,如果断电重启,还未来的及写入磁盘的脏页数据就会丢失

解决:
为了防止断电丢失的问题,当有一条记录需要更新时,InnoDB引擎就会先更新内存(同时标记为脏页),然后将本次对这个页的修改以redo log的形式记录下来,这个时候,更新就算完成。后续由后台线程选择一个合适的时机将脏页写入磁盘。
这就是:WAL(Write-Ahead Logging)技术:MySQL的写操作并不是立刻写在磁盘上,而是先写日志,然后在合适的时间再写入磁盘。

在这里插入图片描述
什是redo log?

redo log 是物理日志,记录了某个数据页做了什么修改。
在事务提交时,只要先将redo log持久化到磁盘即可,可以不需要等到将缓存在Buffer pool里的脏页数据持久化到磁盘。
当系统崩溃时,虽然脏页数据没有写入磁盘,但是redo log已经写入磁盘,MySQL重启后,可以根据redo log的内容,将所有数据恢复到最新的状态。

被需改Undo 页面,需要记录对应的redo log吗?

需要
开始事务后,InnoDB层更新记录前,首先要记录相应的undo log,如果是更新操作,需要把更新的列的旧值记录下来,也就是生成一条undo log,undo log会写入Buffer pool中的Undo页面中。
不过,在内存修改undo 页面后,需要记录对于的redo log

redo log 和 undo log 的区别在哪?

redo log 记录了此次事务完成后的数据状态,记录的的是更新之后的值
undo log 记录了此次事务开始前的数据状态,记录的是更新之前的值
事务提交之前发生崩溃,重启后通过undo log回滚事务
事务提交之后发生崩溃,重启后通过redo log恢复事务

redo log 有自己的缓存 redo log buffer,每产生一条redo log时,会先写到redo log buffer,后续再持久化到磁盘中。
redo log buffer 默认大小为16MB,可以动态调整。

在这里插入图片描述
redo log 什么时候刷盘?

主要有以下几个时机:

  1. MySQL正常关闭时
  2. 当redo log buffer被写满一半时
  3. InnoDB的后台线程每隔1秒,将redo log buffer写入磁盘
  4. 每次事务提交时都将redo log buffer中的redo log直接写入磁盘。(这里有一个参数可以控制innodb_flush_log_at_trx_commit

innodb_flush_log_at_trx_commit
0:事务提交后,redo log留在buffer
1:事务提交后,redo log直接写入磁盘
2:事务提交后,redo log写入操作系统的Cache中
数据安全性:1 > 2 > 0
写入性能:0 > 2 > 1
当其值为 0 和 2时,InnoDB的后台线程每隔1秒

  1. 针对参数0:调用write()写入Cache中,再调用 fsync()持久化磁盘中。如果MySQL进程崩溃,会导致上一秒钟所有事物数据丢失
  2. 调用fsync(),将Cache中的redo log写入磁盘。MySQL进程的崩溃不会丢失数据,只有OS崩溃或者系统断电的情况下,上一秒所有事物数据才会丢失

redo log 文件写满了怎么办?

redo log并不是无限大的,也就是说,redo log不会记录自数据库创建以来的所有redo操作。一条记录被更改,产生redo log,当buffer pool中的脏页持久化到磁盘,那么相应的redo log也就失去了作用。

默认情况下,InnoDB存储引擎有一个重做日志文件组(redo log group),其有两个redo log文件组成,大小一直。
重做日志文件组一循环写的方式工作的,从开头写到结尾,再从结尾写到开头。

在这里插入图片描述

binlog(归档日志)

undo log 和 redo log 是由InnoDB存储引擎产生的
binlog 是由Server层产生的

binlog 文件记录了所有数据库表结构变更和表数据修改,不会记录查询类操作。
binlog有三种格式类型

  1. STATEMENT(默认格式):记录SQL语句,但是存在动态函数的问题,比如获取当期时间、uuid
  2. ROW:记录行数据最终被修改成什么样了。如果批量执行update语句,那可能会导致binlog文件过大。
  3. MIXED:包含了上述两种模式,根据不同情况自动使用ROW和STATEMENT。

redo log 和 binlog 的区别

  1. 适用对象不同。
    binlog由Server层实现,所有引擎都可以使用,
    redo log是InnoDB存储引擎实现。
  2. 文件格式不同。
    binlog有三种格式类型。
    redo log是物理日志,记录的是某个数据页做了什么修改,比如对xxx表空间中的yyy数据页zzz偏移量的地方做了aaa更新。
  3. 写入方式不同。
    binlog是追加写,写满一个文件,就创建一个新的文件继续写,不会覆盖以前的,保存全量的日志。
    redo log 是循环写,日志空间大小是固定的。
  4. 用途不同。
    binlog用于备份恢复,主从复制。
    redo log 用于掉电故障恢复。

恢复整个数据库,应该用binlog

主从复制是怎么实现的?

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

在这里插入图片描述

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

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

主从复制模型

主要有三种:

  • 同步复制:MySQL主库提交事物的线程等待所有从库的复制成功响应,才返回客户端结果。
  • 异步复制(默认模型):MySQL主库提交事务的线程并不会等待binlog同步到个从库,就直接返回客户端结果。这种模式一旦主库宕机,数据就会发生丢失。
  • 半同步复制:介于两者之间,事务线程不用等待所有的从库复制成功响应,只要一部分复制成功响应回来就行。这种半同步复制的方式,兼顾两者的优点,即使主库宕机,至少还有个从库有最新的数据,不存在数据丢失的风险。

binlog什么时候刷盘?

  • 事务执行过程中,先把日志写到binlog cache(Server层的cache,MySQL给每个线程分配了一片内存空间用于缓存binlog,可以用binlog_cache_size参数控制大小),事务提交的时候,再把binlog cache写到binlog文件中。

  • 一个事务的binlog是不能被拆开的,无论这个事务有多大,也要要保证一次性写入。

  • 事务提交时,执行器把binlog cache里的完整事务写入到binlog文件中,并清空binlog cache
    在这里插入图片描述

  • 虽然每个线程都有自己的binlog cache,但最终都会写到一个binlog文件中。

  • 图中的write,指的就是把日志写入到binlog文件,但是并没有持久化到磁盘。这时,数据在OS的cache中。

  • 图中的fsync,才是将数据持久化到磁盘的操作,这里就会涉及磁盘I/O。
    MySQL提供一个sync_binlog参数来控制数据库的binlog刷到磁盘上的频率

  • sync_binlog = 0:表示每次提交事务都只write,不fsync,后续交由操作系统决定合适将数据持久化到磁盘。(MySQL系统默认为0)

  • sync_binlog = 1:表示每次事务都会write,然后马上fsync。

  • sync_binlog = N(N > 1):表示每次提交事务都会write,但累计N个事务后才会fsync

一条update语句执行流程

在这里插入图片描述

两阶段提交

事务提交后,redo log 和 binlog 都要持久化到磁盘中,但这是两个独立的逻辑,可能出现半成功的状态,造成主从数据不一致

解决:两阶段提交
两阶段提交把单个事务的提交拆分成2个阶段:**准备阶段(Prepare)**和 提交阶段(Commit)。
每个阶段都由 协调者参与者 共同完成

大致的思想是:把redo log的提交分成两个阶段,将binlog的提交插入其中

未来保证这两个日志的一致性,MySQL使用了内部XA事务,内部事务有binlog作为协调者,存储引擎为参与者。

两阶段提交过程

两阶段提交过程

  • prepare阶段将XID(内部事务的ID)写入到redo log, 同时将redo log对应的的事物状态设置为prepare,然后将redo log写入磁盘
  • commit阶段将XID写入binlog,然后将binlog写入磁盘,将redo log状态设置为commit。

两阶段提交是以binlog写成功作为事务成功的标识。

redo log 可以在事务没提交之前持久化到磁盘,但是binlog必须在事务提交之后,才可以持久化到磁盘。

异常崩溃会出现什么现象

在这里插入图片描述

  • 时刻A崩溃:redo log处于prepare状态,redo log完成刷盘,binlog没有刷盘。磁盘中的redo log中有XID,binlog没刷盘,没有XID,则回滚事务。
  • 时刻B崩溃:redo log处于prepare状态,redo log完成刷盘,binlog完成刷盘。磁盘中的redo log 和 binlog 都有XID,则提交事务。
两阶段提交存在的问题
  • 磁盘I/O次数高:每一次进行两阶段提交,都会进行两次磁盘IO。
  • 锁竞争激烈:在多事务的情况下,需要加一个锁来保证两阶段提交的原子性。锁的是整个两阶段提交过程。
组提交
MySQL引入了**binlog组提交**(group commit)机制,当多个事务提交的时候,会将多个binlog刷盘操作合并成一个,从而减少磁盘I/O次数。

组提交机制,prepare阶段没变,只针对commit阶段,将其分为了三个阶段:

  • flush阶段(不刷盘):多个事务按照进入的顺序将binlog从cache(这里的cache应该是MySQL Server层的binlogcache)写入文件。也就是把binlog写入OS的Cache,为刷盘做准备。
  • sync阶段(刷盘):对binlog文件做fsync操作(多个事务的binlog合并一次刷盘)
  • commit阶段(返回OK):各个事务按顺序做InnoDB commit操作
以上每个阶段都有一个队列,每个阶段都有锁进行保护,因此保证了事务写入的顺序。

锁的粒度减小了,这样就使得多个阶段可以并发执行,从而提升效率。

第一个进入队列的事物会成为leader,leader领导所在队列的所有事务,全权负责整队的操作,完成后通知其他事物操作结束。

有binlog组提交,redo log也有组提交(MySQL 5.7)
redo log的刷盘操作推迟到flush阶段,也就是说prepare阶段融合在flush阶段。

总结

在这里插入图片描述

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

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

相关文章

一个简单的个人博客管理平台适合新手学习(最底下有github链接)

一个简单的个人博客管理平台 欢迎大家一起学习 前端技术栈 vue3jshtmlcsselement-plus 后端技术栈 springbootredismysqlmybatis 首页展示 页面介绍 左边为文章界面点击文字名字就能进行阅读 右边为热门博客功能能够实时统计前五名博客热度并且将前三名展示在卡片中(卡片…

【人工智能学习之常用损失函数浅谈】

【人工智能学习之常用损失函数浅谈】 Focal Loss基本概念Focal Loss的定义作用应用场景 Arc Loss基本概念ArcFace Loss的定义作用应用场景 CenterLoss基本概念Center Loss 的定义作用应用场景实现细节 Cross Entropy Loss (CELoss)基本概念二分类任务多分类任务作用优点缺点应用…

oracle avg、count、max、min、sum、having、any、all、nvl的用法

组函数 having的使用 any的使用 all的使用 nvl 从执行结果来看,nvl(列名,默认值),nvl的作用就是如果列名所在的这一行出现空则用默认值替换

D. Determine Winning Islands in Race (cf div2,dp、图论最短路)

D. Determine Winning Islands in Race 思路: bfs找到E到达每个点的最短时间t[i]。 如果E要超过B&#xff0c;那么一定要借助辅助桥&#xff0c;从而获胜。 假设有u->v的辅助桥&#xff0c;E能通过这个桥超过B的条件是: s>u 且 t[v] < v-s 即 s的取值要为[u1,v-t[v]-…

每天分享一个FPGA开源代码(6)- 浮点数运算

FPGA&#xff08;现场可编程门阵列&#xff09;是一种高度可配置的集成电路&#xff0c;它可以用于实现各种数字信号处理任务&#xff0c;包括浮点数运算。 在FPGA上进行浮点数运算通常涉及以下几个步骤&#xff1a; 1. 选择浮点数格式 浮点数运算首先要确定使用哪种浮点数格…

第二十八篇——用间篇:使用间谍,先学习花钱的价值观

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 间谍的本质&#xff0c;任何策略没有好坏没有道德&#xff0c;它是平衡路…

【大模型】AutoDL部署AI绘图大模型Stable Diffusion使用详解

目录 一、前言 二、AI绘图大模型概述 2.1 AI绘图大模型介绍 2.2 AI绘图大模型特点 2.3 AI绘图大模型优势 三、主流的AI绘图大模型介绍 3.1 Midjourney 3.1.1 Midjourney介绍 3.1.2 Midjourney功能特点 3.1.3 Midjourney使用场景 3.2 Stable Diffusion 3.2.1 Stable …

Unity中的功能解释(数学位置相关和事件)

向量计算 Vector3.Slerp&#xff08;起点坐标&#xff0c;终点坐标&#xff0c;t&#xff09;&#xff0c;可是从起点坐标以一个圆形轨迹到终点坐标&#xff0c;有那么多条轨迹&#xff0c;那怎么办 Vector3.Slerp 进行的是沿球面插值&#xff0c;因此并不是沿着严格的“圆形…

【LeetCode】146. LRU缓存

1.题目 2.思想 3.代码 3.1 代码1 下面这是一版错误的代码。错误的原因在于逻辑不正确导致最后的代码也是不正确的。 class LRUCache:def __init__(self, capacity: int):self.time 0 # 用于全局记录访问的时间self.num2time {} # 数字到时间的映射self.key2val {} # 数字…

大数据新视界 --大数据大厂之HBase 在大数据存储中的应用与表结构设计

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

.net core集成Minio,构建一个文件存储的基础设施

背景 先简单介绍下MinIO吧&#xff0c;官方给的介绍是它是一种高性能、S3 兼容的对象存储。它专为大规模 AI/ML、数据湖和数据库工作负载而构建&#xff0c;并且它是由软件定义的存储。不需要购买任何专有硬件&#xff0c;就可以在云上和普通硬件上拥有分布式对象存储。 MinI…

【动态规划-多重背包】【hard】力扣2585. 获得分数的方法数

考试中有 n 种类型的题目。给你一个整数 target 和一个下标从 0 开始的二维整数数组 types &#xff0c;其中 types[i] [counti, marksi] 表示第 i 种类型的题目有 counti 道&#xff0c;每道题目对应 marksi 分。 返回你在考试中恰好得到 target 分的方法数。由于答案可能很…

【线程】POSIX信号量---基于环形队列的生产消费者模型

信号量概念 这篇文章是以前写的&#xff0c;里面讲了 System V的信号量的概念&#xff0c;POSIX信号量和SystemV信号量作用相同&#xff0c;都是用于同步操作&#xff0c;达到无冲突的访问共享资源目的。 但POSIX可以用于线程间同步。 信号量的概念 POSIX信号量的接口 初始化…

基于yolov8的红外小目标无人机飞鸟检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv8的红外小目标无人机与飞鸟检测系统是一项集成了前沿技术的创新解决方案。该系统利用YOLOv8深度学习模型的强大目标检测能力&#xff0c;结合红外成像技术&#xff0c;实现了对小型无人机和飞鸟等低空飞行目标的快速、准确检测。 YOLOv8作为YOLO系列的…

光伏开发:一分钟生成光伏项目报告

传统光伏项目报告的编制往往需要收集大量数据、进行复杂计算与分析&#xff0c;耗时长且易受人为因素影响。自动生成光伏项目报告&#xff0c;依托大数据、云计算、人工智能等先进信息技术&#xff0c;实现了对光伏项目关键参数的快速分析、评估与预测。 一、核心功能与流程 1…

进程间通信 (一)【管道通信(上)】

目录 1. 概况2. 管道通信的原理2.1 初步理解2.2 深入理解 1. 概况 是什么&#xff1a;两个及以上的进程实现数据层面的交互&#xff0c;称为进程间的通信。 因为进程独立性的存在&#xff0c;所以一个进程无法直接访问另一个进程的数据&#xff0c;即便是父子进程&#xff0c;子…

使用 KuboardSpray 安装kubernetes_v1.23.1

ps:亲测有效,十分方便,记录下来 pps:下面文档来自官网 使用 KuboardSpray 安装kubernetes_v1.23.1 #Kuboard-Spray Kuboard-Spray 是一款可以在图形界面引导下完成 Kubernetes 高可用集群离线安装的工具&#xff0c;开源仓库的地址为 Kuboard-Spray (opens new window) 安…

git push出错Push cannot contain secrets

报错原因&#xff1a; 因为你的代码里面包含了github token明文信息&#xff0c;github担心你的token会泄漏&#xff0c;所以就不允许你推送这些内容。 解决办法&#xff1a; 需要先把代码里面的github token信息删除掉&#xff0c;并且删掉之前的历史提交&#xff0c;只要包…

【深海王国】初中生也能画的电路板?目录合集

Hi٩(๑ ^ o ^ ๑)۶, 各位深海王国的同志们&#xff0c;早上下午晚上凌晨好呀~辛勤工作的你今天也辛苦啦 (o゜▽゜)o☆ 今天大都督为大家带来系列文章《初中生也能画的电路板》&#xff0c;帮你一周内快速入门PCB设计&#xff0c;手把手教你从元器件库添加、电路原理图绘制、…

go 运行报错missing go.sum entry for module providing package

运行&#xff1a; #清理go.mod中不再需要的模块&#xff0c;并且会添加缺失的模块条目到go.sum中 go mod tidy