【MySQL进阶之路 | 高级篇】简谈redo日志

1. 前言

事务有四种特性:原子性,一致性,隔离性和持久性。那么事务的四种特性到底是基于什么机制实现呢?

  • 事务的隔离性由锁机制实现。
  • 而事务的原子性,一致性和持久性由事务的redo日志和undo日志来保证。

REDO LOG称为重做日志,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持久性。

UNDO LOG称为回滚日志,回滚行记录到某个特定版本,用来保证事务的原子性,一致性。

REDO和UNDO都可以视为一种恢复操作但是

  • redo log:是存储引擎层生成的日志,记录的是物理级别上的页修改操作,比如页号xxx,偏移量yyy写入了'zzz'数据。主要是为了保证数据的可靠性。
  • undo log:是存储引擎层生成的日志,记录的是逻辑操作的日志,比如对某一行数据进行了INSERT语句操作,那么undo log就记录一条与之相反的DELETE操作。主要用于事务的回滚(undo log记录的是每个修改操作的逆操作)和一致性非锁定读(undo log回滚行记录到某种特定的版本--MVCC,即多版本并发控制)。

2. redo日志

InnoDB存储引擎是以页为单位来管理存储空间的。在真正访问到页面之前,需要把在磁盘上的页缓存到内存中的Buffer Pool之后才可以访问。所有的变更都必须先更新缓冲池中的数据,然后缓冲池的脏页会会以一定频率被刷入磁盘(checkPoint机制),通过缓冲池来优化CPU和磁盘之间的鸿沟,这样就可以保证整体的性能不会下降的太快。

2.1 为什么需要REDO日志

一方面,缓冲池可以帮助我们消除CPU和磁盘之间的鸿沟,checkPoint机制可以保证数据的最终落盘,然而由于checkPoint机制并不是每次变更的时候就触发的,而是master线程隔一段时间去处理的。所以最坏的情况就是事务提交后,刚写完缓冲池,数据库宕机,那么这段数据就是丢失的,无法恢复。

另一方面,事务包含持久性的特性,就是说对于一个已经提交的事务,在事务提交后即使系统发生了崩溃,这个事务对数据库中所作的更改也不能丢失。

那么如何保证这个持久性呢?一个简单的做法:在事务提交完成之前把事务所修改的所有页面都刷新到磁盘上,但这个简单粗暴的做法有一些问题:

  • 修改量与刷新磁盘工作量严重不成比例:有时候我们仅仅修改了某个页面的一个字节,但是我们知道在InnoDB中是以页为单位来进行磁盘IO的,页就是说我们在该事务提交时不得不将一个完整的页面从内存中刷新到磁盘上,我们又知道一个页面的默认是16KB大小,只修改一个字节就要刷新16KB的数据到内存上显然是大题小作。
  • 随机IO刷新较慢:一个事务可能包含很多语句,即使是一条语句也可能修改很多页面,假如该事务修改的这些页面可能并不相邻,这就意味着在将某个事务修改的buffer pool中的页面刷新到磁盘上时,需要进行很多的随机IO,随机IO比顺序IO要慢。

另一个解决的思路:我们只是想让已经提交了的事务对数据库中数据所做的修改永远生效,即使后来系统崩溃,在重启后也能把这种修改恢复出来。所以我们其实也没必要在每次事务提交时就把改事务在内存中修改的全部页面刷新到磁盘上,只需要把修改了哪些东西记录一下就好了。比如,某个事物将系统表空间中第10号页面中偏移量为100处的那个字节的值1改成值2,我们只需要记录一下:将第0号表空间的第10个页面的偏移量为100处的值更新为2。

InnoDB引擎的事物采用了WAL技术(Write-Ahead Logging),这种技术的思想就是先写日志,再写磁盘,只有日志写入成功,才算事务提交成功,这里的日志就是redo log。当发生宕机且数据未刷到磁盘的时候,可以通过redo log来恢复,保证ACID中的D,这就是redo log的作用。

94f5c0a8402b4b8e907f06ac69a55ec9.png

2.2 REDO日志的好处,特性

1). 好处

  • redo日志降低了刷盘频率。
  • redo日志占用的空间非常小。

存储表空间ID,页号,偏移量以及需要更新的值,所需的存储空间是很小的,刷盘快。

2). 特点

  • redo日志是顺序写入磁盘的。

在执行事务的过程,每执行一条语句,就可能产生若干条redo日志,这些日志是按照产生的顺序写入磁盘的。也就是使用顺序IO,效率比随机IO快。

  • 事务执行过程中,redo log不断记录

redo log跟bin log的区别,redo log是存储引擎层产生的,而bin log是数据库层产生的。假设一个事务,对表做10万行记录插入,在这个过程中,一直不断的往redo log顺序记录,而bin log不会记录,直到这个事务被提交,才会一次写入到bin log文件中。

2.3 redo的组成

redo log可以简单分为以下两个部分:

  • 重做日志的缓冲(redo log buffer),保存在内存中,是易失的。

在服务器启动时就向操作系统申请了一大片空间称之为redo log buffer的连续内存空间,翻译成中文就是redo日志缓冲区。这片内存空间被划分为若干个连续的redo log block。一个redo log block占用512字节大小。66d574614d5a4d8ebc42be1ff8e13d29.png

参数设置:innodb_log_buffer_size:默认大小16M,最大值是4096M,最小为1M。

  • 重做日志文件(redo log file),保存在硬盘中,是持久的。ib_logfile0和ib_logfile1是REDO日志。

2.4 redo的整体流程

以一个更新事务为例,redo log流转流程,如下:

01921766c8524159be3360047c2a4344.png

  1. 先将原始数据从磁盘中读入内存中来,修改数据的内存拷贝。

  2. 生成一条重做日志并写入redo log buffer,记录的是数据被修改后的值。

  3. 当事务commit时,将redo log buffer中的内容刷新到redo log file,对redo log file采用追加写的方式。

  4. 定期将内存中修改的数据刷新到磁盘中。

2.5 redo的刷盘策略

注意,redo log buffer刷盘到redo log file的过程并不是真正的刷到磁盘中去,只是刷入到文件系统缓存(page cache)中去(这是现代操作系统为了提高文件写入效率做的一个优化),真正的写入会交给系统自己来决定(比如page cache足够大了)。那么对于InnoDB来说就存在一个问题,如果 交给系统来同步,同样如果系统宕机了,那么数据也丢失了。

针对这种情况,InnoDB给出了innodb_flush_log_at_trx_commit参数,该参数控制commit提交事务时,如何将redo log buffer中的日志刷新到redo log file中。它支持三种策略:

  • 设置为0:表示每次事务提交时不进行刷盘操作,(xito默认master thread每隔1s进行一次重做日志的同步)
  • 设置为1:表示每次事务提交的时都将进行同步,刷盘操作(默认值)
  • 设置为2:表示每次事务提交时都只把redo log buffer内容写入到page cache中,不进行同步。由os自己决定什么时候同步到磁盘文件。

查看变量:show variables like 'innodb_flush_log_at_trx_commit';

另外,InnoDB存储引擎有一个后台线程,每隔1s,就会把redo log buffer中的内容写到文件系统缓存(page cache),然后调用刷盘操作。

2.6 不同刷盘策略演示

1). innodb_flush_log_at_trx_commit=1

c04bc8f921104613be49657a3da62e97.png

  • 这种情况只要是1,redo log记录就一定在硬盘里,不会有任何数据的丢失。
  • 如果事务执行期间MySQL挂了或宕机,在部分日志丢了,但事务并没有提交,所以日志丢了也不会有损失。可以保证ACID的D,数据绝对不会丢失,但是效率最差的。
  • 建议使用默认值,虽然操作系统宕机的概率理论小于数据库宕机的概率,但是一般使用的事务,那么数据库的安全相对来说重要一些。

2). innodb_flush_log_at_trx_commit=2;

9514956752a14f37ac86f4b6dd4b0470.png

当innodb_flush_log_at_trx_commit=2时,只要事务提交成功,redo log buffer的内容只是写入到文系统缓存(page cache)。如果仅仅是MySQL挂了不会有任何数据的丢失,但是操作系统宕机肯恩那个会有1s数据的丢失。这种情况 无法满足ACID中的D。但是数值2肯定是效率最高的。

3). innodb_flush_log_at_trx_commit=0

当innodb_flush_log_at_trx_commit=0时,master thread中每一秒进行一个重做日志的fsync的操作,因此实例crash最多丢失1s内的事务。(master thread是负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性)。

数值为0的话,是一种折中的做法,它的IO效率理论上高于1的,低于2的。这种策略也有丢失数据的风险,也无法保证D。

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

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

相关文章

云计算实训13——DNS域名解析、ntp时间服务器配置、主从DNS配置、多区域DNS搭建

一、DNS域名解析 1.正向解析 将域名解析为IP地址 DNS正向解析核心配置 (1)安装bind [rootdns ~]# yum -y install bind (2)编辑配置文件 编辑named.conf文件,限定访问权限 [rootdns ~]# vim /etc/named.conf 编辑named.rfc文件,指定要访问的域名 [ro…

【数据结构】:用Java实现链表

在 ArrayList 任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后搬移,时间复杂度为 O(n),效率比较低,因此 ArrayList 不适合做任意位置插入和删除比较多的场景。因此:java 集合中又引入了 LinkedList&…

一步一步测试DNS隧道

目录 0、前言 1、DNS解析 1.1 DNS简介 1.2 DNS查询类型 1.3 DNS解析过程 2、DNS隧道准备工作 2.1 DNS隧道介绍 2.1.1 什么是DNS隧道? 2.1.2 DNS隧道的原理 2.2 客户端、服务端准备 2.3 域名准备 2.4 连接隧道 2.5 遇坑 3、隧道确认和利用…

Windows本地启动Redis

找到本地redis目录 输入cmd,然后输入redis-server.exe redis.windows.conf,默认端口为6379 再新打开一个cmd,输入redis-cli.exe -p 6379 -a (你在redis.windows.conf中设置的密码)

如何做好服务器的安全管理

以下是一些服务器安全防护措施: 1、安装杀毒软件:安装杀毒软件是保护服务器免受病毒和恶意软件攻击的基本措施之一。保持杀毒软件更新至最新版本,定期扫描检测服务器以确保其不被病毒、蠕虫等恶意软件入侵。保护服务器免受侵害。像360杀毒&am…

HarmonyOS NEXT星河版零基础入门到实战

文章目录 一、HarmonyOS NEXT介绍学习内容1、鸿蒙APP开发2、能力套件开发3、全场景开发适合人群 持续更新中✒️总结 一、HarmonyOS NEXT介绍 放弃安卓框架之后,HarmonyOS NEXT成为真正独立于安卓、iOS的操作系统,堪称是一场史无前例的脱胎换骨。在其众多…

服务器利用宝塔面板部署Django项目

目录 1. 使用命令启动Django项目1.1 使用 Xshell 连接服务器1.2 安装Anaconda1.3 启动Django项目1.4 使用tmux实现项目的后台运行 2. 使用Python项目管理器部署项目2.1 安装宝塔面板和软件2.2 添加站点2.3 上传项目文件2.3.1 收集静态文件2.3.2 生成依赖文件 2.4 安装安装Pytho…

【周记】2024暑期集训第二周(未完待续)

文章目录 日常刷题记录合并果子题目解析算法思路代码实现 中位数题目解析算法思路代码实现 C学习笔记队列queue双端队列 deque优先队列 priority_queue定义常见操作 upper_bound 日常刷题记录 合并果子 题目解析 有一堆果子,每次可以将两小堆合并,耗费…

人的心体本乐,回归自己,清静快乐

94天 孔颜之乐,乐是心的本体;真乐,常人所共有; 人心本体,原来就没有什么不快乐的 - 陆元静问:孔颜之乐与七情之中的“ 乐 ”是否相同呢?我经常愁闷,未曾体会过“真乐”的感受&#x…

classfinal太强了,再也不怕被反编译了

这段时间在辛辛苦苦的编写一个算法程序,担心部署到客户服务器,客户反编译jar包,破解程序,那努力就白费了! 在网上查询,发现个好东东,classfinal可以加密jar包,防止反编译&#xff0…

华杉研发九学习日记18 集合 泛型

华杉研发九学习日记18 一,集合框架 1.1 集合和数组的区别 集合就是在java中用来保存多个对象的容器 集合是数组的升级版,集合中只能放置对象[object]. 数组: 在java中用来保存多个具有相同数据类型数据的容器 数组弊端: 1.数组只能保存…

【计算机网络】网络层——IPv4地址(个人笔记)

学习日期:2024.7.24 内容摘要:IPv4地址,分类编址,子网,无分类编址 IPv4地址概述 在TCP/IP体系中,IP地址是一个最基本的概念,IPv4地址就是给因特网上的每一台主机的每一个接口分配一个在全世界…

C语言 之 理解指针(4)

文章目录 1. 字符指针变量2. 数组指针变量2.1 对数组指针变量的理解2.2 数组指针变量的初始化 3. 二维数组传参的本质4. 函数指针变量4.1 函数指针变量的创建4.2 函数指针变量的使用 5. 函数指针数组 1. 字符指针变量 我们在前面使用的主要是整形指针变量,现在要学…

实战练习之Linux上实现shell脚本自动化编程

实验拓扑要求 主机环境描述 注意: 172.25.250.101-172.25.250.105 共 5 个 IP 地址由servera.exam.com服务器进行提供。172.25.250.106 由 serverb.exam.com 服务器进行提供。 需求描述 1. 172.25.250.101 主机上的 Web 服务要求提供 www.exam.com Web站点&#…

A Comprehensive Study of Knowledge Editing for Large Language Models

大型语言模型(LLMs)在理解和生成与人类交流密切相关的文本方面表现出了非凡的能力。然而,一个主要的限制在于训练期间的大量计算需求,这是由于它们的广泛参数化而产生的。世界的动态性质进一步加剧了这一挑战,需要经常…

Unity UGUI 之Text 控件

本文仅作学习笔记与交流,不作任何商业用途 本文包括但不限于unity官方手册,唐老狮,麦扣教程知识,引用会标记,如有不足还请斧正 1.Text是什么 UI里面写文本的(注意是legacy Text,而不是TextmeshP…

前端网页打开PC端本地的应用程序实现方案

最近开发有一个需求,网页端有个入口需要跳转三维大屏,而这个大屏是一个exe应用程序。产品需要点击这个入口,并打开这个应用程序。这个就类似于百度网盘网页跳转到PC端应用程序中。 这里我们采用添加自定义协议的方式打开该应用程序。一开始可…

springboot项目从jdk8升级为jdk17过程记录

背景:公司有升级项目jdk的规划,计划从jdk8升级到jdk11 开始 首先配置本地的java_home 参考文档:Mac环境下切换JDK版本及不同的maven-CSDN博客 将pom.xml中jdk1.8相关的版本全部改为jdk17,主要是maven编译插件之类的&#xff0c…

mysql定时备份

为什么写这篇文章 最近项目里面需要定时备份mysql的数据,网上找了下,找到了一些比较好的解决方案。但是发现有几个地方与自己不匹配,我期望有如下 备份过程不能锁表,网上很多都是会锁表备份定时任务无法执行,但是手动…

【如何在Jenkins的从节点切换NPM镜像源查看和切换】

【问题】 Jenkins打包时,前端npm构建时很慢,所有需要更换镜像源 【自查】 找到Jenkins从节点上的nodejs安装的路径,进入bin目录 执行./npm -v查看是不能正常查看, [rootlocalhost bin]# ./npm -v /usr/bin/env: ‘node’: No su…