MySQL(日志)

news2024/9/22 21:17:52

日志

日志分为三种:
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.coloradmin.cn/o/2155899.html

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

相关文章

qt-C++笔记之作用等同的宏和关键字

qt-C笔记之作用等同的宏和关键字 code review! Q_SLOT 和 slots: Q_SLOT是slots的替代宏,用于声明槽函数。 Q_SIGNAL 和 signals: Q_SIGNAL类似于signals,用于声明信号。 Q_EMIT 和 emit: Q_EMIT 是 Qt 中用于发射…

Tomcat 靶场攻略

CVE-2017-12615 步骤一:环境搭建 cd vulhub/tomcat/CVE-2017-12615 docker-compose up -d docker ps 步骤二:漏洞复现 http://192.168.10.190:8080/ 步骤二:首页进行抓包 Tomcat允许适⽤put⽅法上传任意⽂件类型,但不允许js…

安卓13去掉下拉菜单的Dump SysUI 堆的选项 android13删除Dump SysUI 堆

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析3.1 位置13.2 位置24.代码修改5.编译6.彩蛋1.前言 客户需要去掉下拉菜单里面的Dump SysUI 堆图标,不让使用这个功能。 2.问题分析 android的下拉菜单在systemui里面,这里我们只需要定位到对应的添加代…

【优选算法之二分查找】No.5--- 经典二分查找算法

文章目录 前言一、二分查找模板:1.1 朴素二分查找模板1.2 查找区间左端点模板1.3 查找区间右端点模板 二、二分查找示例:2.1 ⼆分查找2.2 在排序数组中查找元素的第⼀个和最后⼀个位置2.3 搜索插⼊位置2.4 x 的平⽅根2.5 ⼭脉数组的峰顶索引2.6 寻找峰值…

Linux自主学习篇

用户及权限管理 sudo 是 "superuser do" 的缩写,是一个在类 Unix 操作系统(如 Linux 和 macOS)中使用的命令。它允许普通用户以超级用户(root 用户)的身份执行命令,从而获得更高的权限。 useradd…

多模态交互才是人机交互的未来

交互方式 在探讨文字交流、语音交流和界面交流的效率时,我们可以看到每种方式都有其独特的优势和局限性。文字交流便于记录和回溯,语音交流则在表达情绪和非语言信息方面更为高效,而界面交流则依赖于图形用户界面(GUI&#xff09…

<<编码>> 第 16 章 存储器组织(4)--内存 示例电路

内存内部结构 info::操作说明 译码器用于写入, 操作同上 选择器用于输出, 操作同上 地址信号同时控制译码器和选择器, 注意地址的高位在右(比如 001 实际是 100, 选择的是 Q6 和 I6) 缺省情况下, 内部数据全是 0. 读者可先通过译码器写入, 再通过选择器输出 primary::在线交…

初学者的鸿蒙多线程并发之 TaskPool 踩坑之旅

1. 背景 目标群体:鸿蒙初学者 版本:HarmonyOS 3.1/4.0 背景:鸿蒙 App 的全局路由管理功能,需要在 App 启动时初始化对 raw 下的相关配置文件进行读取、解析并缓存。App 启动时涉及到了大量模块的初始化,好多模块都涉…

【machine learning-15-如何判定梯度下降是否在收敛】

我们在运行梯度下降的时候,如何判定梯度下降是否在收敛呢? 梯度下降的时候,权重和偏置根据如下的公式同时更新: 程序要做的就是更新w 和 b,让梯度下降尽快的收敛,但是如何判定正在收敛呢? 方法…

关于神经网络的一个介绍

这篇文章中,我将简单介绍下与神经网络有关的东西,包括它的基本模型,典型的算法以及与深度学习的联系等内容。 一、神经元 神经网络是由许多个神经元组成的,在生物的神经网络中,就是神经元间相互连接,传递…

Arthas getstatic(查看类的静态属性 )

文章目录 二、命令列表2.1 jvm相关命令### 2.1.7 getstatic(查看类的静态属性 ) 二、命令列表 2.1 jvm相关命令 ### 2.1.7 getstatic(查看类的静态属性 ) 使用场景: 我们项目部署在linux上,我有个本地内存…

从一到无穷大 #35 Velox Parquet Reader 能力边界

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。 文章目录 引言源码分析功能描述功能展望 引言 InfluxDB IOX这样完全不使用索引,只…

《沧浪之水》读后感

未完待续..... 未完待续.... 未完待续.... 【经典语录】 01、我一辈子的经验就是不要做瞎子,也不能做聋子,该听到的信息要听到,但是要做哑巴,看到了听到了心中有数就行了,可千万不要张口说什么。 02、你刚从学校毕业…

MQ入门(一):同步调用和异步调用--RabbitMQ基础入门

目录 1.初识MQ 1.1.同步调用 1.2.异步调用 1.3.技术选型 2.RabbitMQ 2.1.安装部署 2.2.RabbitMQ基本架构 2.3.收发消息 2.3.1.交换机 2.3.2.队列 2.3.3.绑定关系 2.3.4.发送消息 2.4.数据隔离 2.4.1.用户管理 2.4.2.virtual host 1.初识MQ 微服务一旦拆分&…

web前端字段大小写下划线转换工具

文章目录 前言一、如何使用?二、相关代码总结 前言 程序员在敲代码的过程中都要命名一些字段,但是Java语言对字段的命名规范和sql命名规范不一样,如下图所示,这种机械性的转换工作很劳神费力,为了省点劲写了一个web小…

尚品汇-Jenkins部署构建服务模块、Linux快照备份(五十七)

目录: (1)构建作业(server-gateway) (2)构建service_product模块 (3)演示添加新代码 (4)学会使用linux快照 (1)构建作…

在SpringCloud中实现服务间链路追踪

在微服务架构中,由于系统的复杂性和多样性,往往会涉及到多个服务之间的调用。当一个请求经过多个服务时,如果出现问题,我们希望能够快速定位问题所在。这就需要引入链路追踪机制,帮助我们定位问题。 Spring Cloud为我们…

【沪圈游戏公司作品井喷,游戏产业复兴近在眼前】

近期财报季中,腾讯、网易及B站等国内游戏巨头纷纷亮出亮眼的游戏业务表现,均实现了接近或超越双位数的同比增长。然而,审视过去一年,国内游戏行业仍笼罩在宏观经济“降本增效”的阴影下。 行业数据揭示,全国游戏公司社…

封装 wx.request 的必要性及其实现方式

目录 为什么需要封装 wx.request 1. 避免回调地狱 2. 统一管理 3. 扩展功能 小程序异步 API 的改进 封装实现方式 在小程序开发中,网络请求是不可或缺的功能之一。小程序提供了 wx.request API 来实现网络请求,但直接使用这个 API 在复杂场景下可…

关于SpringBoot项目使用maven打包由于Test引起的无法正常打包问题解决

一、问题描述 在日常工作中,在接手项目时,项目未必是“正常”的,一般平常搭建项目,都不会采用一键式生成的方式,现在说下旧项目,可能项目结构并不是那么简洁,通常都带有与main同层级的test&…