MySQL 日志,难怪被模仿

news2024/9/23 1:31:28

一.前言

日志是mysql数据库的重要组成部分,记录着数据库运行期间各种状态信息。mysql日志主要包括错误日志、查询日志、慢查询日志、事务日志、二进制日志几大类。

通过分析日志,我们可以优化数据库性能,排除故障,甚至能够还原数据, 不管是哪个数据库产品,一定会有日志文件。在MariaDB/MySQL中,主要有下面几种日志文件:

  1. bin log (二进制日志):用于记录数据库执行的写入性操作(不包括查询)信息,以二进制的形式保存在磁盘中。
  2. redo log (重做日志):用于记录事务对数据页做了哪些修改。
  3. undo log (回滚日志):undo log主要记录了数据的逻辑变化,比如一条INSERT语句,对应一条DELETE的undo log,对于每个UPDATE语句,对应一条相反的UPDATE的undo log,这样在发生错误时,就能回滚到事务之前的数据状态。原子性 底层就是通过undo log实现的,undo log也是 MVCC(多版本并发控制) 实现的关键。
  4. relay log (中继日志) :主从复制时使用的日志。
  5. error log (错误日志):记录mysql服务的启停时正确和错误的信息,还记录启动、停止、运行过程中的错误信息。
  6. general log (查询日志):记录建立的客户端连接和执行的语句。
  7. slow log (慢查询日志):记录所有执行时间超过long_query_time的所有查询或不使用索引的查询。

作为开发,我们重点需要关注的是二进制日志(binlog)和事务日志(包括redo log和undo log),本文接下来会详细介绍这三种日志。下一篇文章将介绍innodb事务日志,见:MySQL的事务日志。

二.事务

mysql innodb存储引擎的事务,首先想到就是ACID(不知道的请google),数据库是如何做到ACID的呢?举个例子:

数据库数据存放的文件称为data file;日志文件称为log file;数据库数据是有缓存的,如果没有缓存,每次都写或者读物理disk,那性能就太低了。数据库数据的缓存称为data buffer,日志(redo)缓存称为log buffer;既然数据库数据有缓存,就很难保证缓存数据(脏数据)与磁盘数据的一致性。比如某次数据库操作:

update driver_info set driver_status = 2 where driver_id = 10001;

更新driver_status字段的数据会存放在缓存中,等待存储引擎将driver_status刷新data_file,并返回给业务方更新成功。如果此时数据库宕机,缓存中的数据就丢失了,业务方却以为更新成功了,数据不一致,也没有持久化存储。

上面的问题就可以通过事务的ACID特性来保证。

BEGIN trans;
 
update driver_info set driver_status = 2 where driver_id = 10001;
 
COMMIT;

这样执行后,更新要么成功,要么失败。业务方的返回和数据库data file中的数据保持一致。要保证这样的特性这就不得不说存储引擎innodb的redo和undo日志。

三. 日志分解

3.1 binlog

binlog用于记录数据库执行的写入性操作(不包括查询)信息,以二进制的形式保存在磁盘中。binlog是mysql的逻辑日志,并且由Server层进行记录,使用任何存储引擎的mysql数据库都会记录binlog日志。

  • 逻辑日志:可以简单理解为记录的就是sql语句。
  • 物理日志:因为mysql数据最终是保存在数据页中的,物理日志记录的就是数据页变更。

binlog是通过追加的方式进行写入的,可以通过max_binlog_size参数设置每个binlog文件的大小,当文件大小达到给定值之后,会生成新的文件来保存日志。

3.1.1 binlog使用场景

在实际应用中,binlog的主要使用场景有两个,分别是主从复制和数据恢复。

  • 主从复制:在Master端开启binlog,然后将binlog发送到各个Slave端,Slave端重放binlog从而达到主从数据一致。
  • 数据恢复:通过使用mysqlbinlog工具来恢复数据。

3.1.2 binlog刷盘时机

对于InnoDB存储引擎而言,只有在事务提交时才会记录biglog,此时记录还在内存中,那么biglog是什么时候刷到磁盘中的呢?mysql通过sync_binlog参数控制biglog的刷盘时机,取值范围是0-N:

  • 0:不去强制要求,由系统自行判断何时写入磁盘;
  • 1:每次commit的时候都要将binlog写入磁盘;
  • N:每N个事务,才会将binlog写入磁盘。

从上面可以看出,sync_binlog最安全的是设置是1,这也是MySQL 5.7.7之后版本的默认值。但是设置一个大一些的值可以提升数据库性能,因此实际情况下也可以将值适当调大,牺牲一定的一致性来获取更好的性能。

3.1.3 binlog日志格式

binlog日志有三种格式,分别为 STATMENT、ROW和MIXED。

在 MySQL 5.7.7之前,默认的格式是STATEMENT,MySQL 5.7.7之后,默认值是ROW。日志格式通过binlog-format指定。

STATMENT
基于SQL语句的复制(statement-based replication, SBR),每一条会修改数据的sql语句会记录到binlog中。

  • 优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO, 从而提高了性能;
  • 缺点:在某些情况下会导致主从数据不一致,比如执行sysdate()、slepp()等。

ROW
基于行的复制(row-based replication, RBR),不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了。

  • 优点:不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题;
  • 缺点:会产生大量的日志,尤其是alter table的时候会让日志暴涨

MIXED
基于STATMENT和ROW两种模式的混合复制(mixed-based replication, MBR),一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog。

3.2 redolog

3.2.1 为什么需要redo log

我们都知道,事务的四大特性里面有一个是持久性,具体来说就是只要事务提交成功,那么对数据库做的修改就被永久保存下来了,不可能因为任何原因再回到原来的状态。那么mysql是如何保证一致性的呢?最简单的做法是在每次事务提交的时候,将该事务涉及修改的数据页全部刷新到磁盘中。但是这么做会有严重的性能问题,主要体现在两个方面:

  • 因为Innodb是以页为单位进行磁盘交互的,而一个事务很可能只修改一个数据页里面的几个字节,这个时候将完整的数据页刷到磁盘的话,太浪费资源了!
  • 一个事务可能涉及修改多个数据页,并且这些数据页在物理上并不连续,使用随机IO写入性能太差!

因此mysql设计了redo log,具体来说就是只记录事务对数据页做了哪些修改,这样就能完美地解决性能问题了 (相对而言文件更小并且是顺序IO)。

3.2.2 redo log基本概念

redo log包括两部分:一个是内存中的日志缓冲(redo log buffer),另一个是磁盘上的日志文件(redo log file)。mysql每执行一条DML语句,先将记录写入redo log buffer,后续某个时间点再一次性将多个操作记录写到redo log file。这种先写日志,再写磁盘的技术就是MySQL里经常说到的WAL(Write-Ahead Logging) 技术。

在计算机操作系统中,用户空间(user space)下的缓冲区数据一般情况下是无法直接写入磁盘的,中间必须经过操作系统内核空间(kernel space)缓冲区(OS Buffer)。因此,redo log buffer写入redo log file实际上是先写入OS Buffer,然后再通过系统调用fsync()将其刷到redo log file中,过程如下:
在这里插入图片描述
mysql支持三种将redo log buffer写入redo log file的时机,可以通过innodb_flush_log_at_trx_commit参数配置,各参数值含义如下:
在这里插入图片描述在这里插入图片描述

3.2.3 redo log记录形式

前面说过,redo log实际上记录数据页的变更,而这种变更记录是没必要全部保存,因此redo log实现上采用了大小固定,循环写入的方式,当写到结尾时,会回到开头循环写日志。如下图:
在这里插入图片描述
同时我们很容易得知,在innodb中,既有redo log需要刷盘,还有数据页也需要刷盘,redo log存在的意义主要就是降低对数据页刷盘的要求。在上图中,write pos表示redo log当前记录的LSN(逻辑序列号)位置,check point表示数据页更改记录刷盘后对应redo log所处的LSN(逻辑序列号)位置。

write pos到check point之间的部分是redo log空着的部分,用于记录新的记录;check point到write pos之间是redo log待落盘的数据页更改记录。当write pos追上check point时,会先推动check point向前移动,空出位置再记录新的日志。

启动innodb的时候,不管上次是正常关闭还是异常关闭,总是会进行恢复操作。因为redo log记录的是数据页的物理变化,因此恢复的时候速度比逻辑日志(如binlog)要快很多。

重启innodb时,首先会检查磁盘中数据页的LSN,如果数据页的LSN小于日志中的LSN,则会从checkpoint开始恢复。

还有一种情况,在宕机前正处于checkpoint的刷盘过程,且数据页的刷盘进度超过了日志页的刷盘进度,此时会出现数据页中记录的LSN大于日志中的LSN,这时超出日志进度的部分将不会重做,因为这本身就表示已经做过的事情,无需再重做。
在这里插入图片描述

3.2.4 redo log与binlog区别

由binlog和redo log的区别可知:binlog日志只用于归档,只依靠binlog是没有crash-safe能力的。但只有redo log也不行,因为redo log是InnoDB特有的,且日志上的记录落盘后会被覆盖掉。因此需要binlog和redo log二者同时记录,才能保证当数据库发生宕机重启时,数据不会丢失。

3.3 undolog

数据库事务四大特性中有一个是原子性,具体来说就是 原子性是指对数据库的一系列操作,要么全部成功,要么全部失败,不可能出现部分成功的情况。

实际上,原子性底层就是通过undo log实现的。undo log主要记录了数据的逻辑变化,比如一条INSERT语句,对应一条DELETE的undo log,对于每个UPDATE语句,对应一条相反的UPDATE的undo log,这样在发生错误时,就能回滚到事务之前的数据状态。

同时,undo log也是MVCC(多版本并发控制)实现的关键,这部分内容在面试中的老大难-mysql事务和锁,一次性讲清楚!中有介绍,不再赘述。

四. 案例实践

4.1 关于redo和undo

某一事务的事务序号为T1,其对数据X进行修改,设X的原值是5,修改后的值为15,那么Undo日志为<T1, X, 5>,Redo日志为<T1, X, 15>。

梳理下事务执行的各个阶段:

  1. 写undo日志到log buffer;
  2. 执行事务,并写redo日志到log buffer;
  3. 如果innodb_flush_log_at_trx_commit=1,则将redo日志写到log file,并刷新到磁盘(落盘)。
  4. 提交事务。

可能有同学会问,为什么没有写data file,事务就提交了?

在数据库的世界里,数据从来都不重要,日志才是最重要的,有了日志就有了一切。

因为data buffer中的数据会在合适的时间 由存储引擎写入到data file,如果在写入之前,数据库宕机了,根据落盘的redo日志,完全可以将事务更改的数据恢复。好了,看出日志的重要性了吧。先持久化日志的策略叫做Write Ahead Log,即预写日志。

分析几种异常情况:

  • innodb_flush_log_at_trx_commit=2(innodb_flush_log_at_trx_commit和sync_binlog参数详解)时,将redo日志写入logfile后,为提升事务执行的性能,存储引擎并没有调用文件系统的sync操作,将日志落盘。如果此时宕机了,那么未落盘redo日志事务的数据是无法保证一致性的。
  • undo日志同样存在未落盘的情况,可能出现无法回滚的情况。

checkpoint(检查点)

checkpoint是为了定期将db buffer的内容刷新到data file。当遇到内存不足、db buffer已满等情况时,需要将db buffer中的内容/部分内容(特别是脏数据)转储到data file中。在转储时,会记录checkpoint发生的”时刻“。在故障回复时候,只需要redo/undo最近的一次checkpoint之后的操作。

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

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

相关文章

中文文献检索网站

1. 中国知网 网址&#xff1a; https://www.cnki.net/ 中国知网被称众多科研人称国内文献论文最全最权威的中文文献库&#xff0c;知网提供中国学术文献、外文文献、学位论文、报纸、会议、年鉴、工具书等各类资源统一检索、统一导航、在线阅读和下载服务。 2. 掌桥科研 网址…

25.Django大型电商项目之地址管理——如何使用三级联动菜单数据加载地址、保存数据、动态获取数据、设置默认值

1. 地址管理基本页面 1.1 概述 1.2 流程 修改templates的跳转链接center.html <ul><li><a href"/userapp/address/">地址管理</a></li> </ul>templates {% extends base.html %} {% block title %}用户中心{% endblock %} {…

东北大学数据结构第八周(排序)

7-1 快速排序 作者 朱允刚 单位 吉林大学 给定包含n个元素的整型数组a[1],a[2],…,a[n]&#xff0c;利用快速排序算法对其进行递增排序&#xff0c;请输出排序过程&#xff0c;即每次Partition之后的数组。每次选择所处理的子数组的第一个元素作为基准元素。 输入格式: 输入为…

MapReduce 序列化案例

文章目录MapReduce 序列化案例一、案例需求二、案例分析map 阶段Reduce 阶段三、代码实现1、编写流量统计的Bean对象2、Mapper阶段代码MapReduce 序列化案例 一、案例需求 1、需求&#xff1a; 统计每一个手机号耗费的总上行流量&#xff0c;下行流量&#xff0c;总流量 2、输…

二、ZFNet可视化卷积神经网络——可解释性机器学习(DataWhale组队学习)

目录引言ZFNet的网络结构可视化反卷积反池化反激活反卷积训练细节特征可视化特征演化特征不变性局部遮挡测试敏感性分析相关性分析消融实验宽度影响深度影响迁移学习能力有效性分析总结引言 纽约大学ZFNet&#xff0c;2013年ImageNet图像分类竞赛冠军模型。对AlexNet进行改进的…

AOP 操作

AOP 操作AOP 操作&#xff08;准备&#xff09;1. Spring 框架一般是基于 AspectJ 实现 AOP 操作&#xff08;1&#xff09;什么是 AspectJ2. 基于 AspectJ 实现 AOP 操作3. 在项目工程里面引入 AOP 先关的依赖4. 切入点表达式举例1&#xff1a;对 com.fairykunkun.dao.UserDao…

谈谈自己对依赖注入的理解

1. 絮絮叨叨 1.1 想学习Google Guice 在工作的过程中&#xff0c;发现有名的大数据组件Presto大量使用Google Guice实现各种Module的构建 很多bind(interface).to(implementClass).in(scope)语句&#xff0c;实现接口与实现类的绑定&#xff0c;并指定实现类是单例还是多例 /…

Service的绑定过程

前言 Service的绑定过程将分为两个部分来进行讲解&#xff1b;分别是Contextlmpl到AMS的调用过程和Service的绑定过程。 frameworks/base/core/java/android/content/ContextWrapper.javapublic boolean bindService(Intent service, ServiceConnection conn,int flags) {ret…

计算机毕设Python+Vue-新型冠状病毒防控咨询网站(程序+LW+部署)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

根据端口划分虚拟局域、集线器、中继器、交换机、路由器、网桥----计算机网络

集线器&#xff1a; 连接计算机和交换机&#xff0c;类似于多台中继器。 实现多台电脑的同时使用一个进线接口来上网或组成局域网 中继器&#xff1a; 连接两条电缆&#xff0c;作用是放大前一条电缆里面的信号并传入下一条电缆。 是对接收到的信息进行再生放大&#xff0c;以…

Jenkins + Jmeter + Ant 持续集成

搭建提前安装好&#xff1a;ant Jenkins 环境 一、Jenkins 安装 Ant 插件&#xff1a; 进入Jenkins 配置插件页面&#xff0c;安装ant 插件&#xff1a; 打开插件配置页面&#xff0c;如下图&#xff1a; 点击“Available” 在输入框搜索 ant 安装即可&#xff1a; 二、安装…

计算机毕业设计springboot+vue基本微信小程序的透析耗材管理系统

项目介绍 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理程序应运而生,各行各业相继进入信息管理时代,透析耗材管理小程序就是信息时代变革中的产物之一。 任何程序都要遵循…

vue前端案例教学:动态获取最新疫情数据展示(代码详解)

【辰兮要努力】&#xff1a;hello你好我是辰兮&#xff0c;很高兴你能来阅读&#xff0c;昵称是希望自己能不断精进&#xff0c;向着优秀程序员前行&#xff01; 博客来源于项目以及编程中遇到的问题总结&#xff0c;偶尔会有读书分享&#xff0c;我会陆续更新Java前端、后台、…

[leetcode.4]寻找两个正序数组的中位数 多思考边界

题目展示 题目要点 题目其实本身的思路非常简单&#xff0c;就是把两个数组给合并起来&#xff0c;然后寻找中位数&#xff0c;具体可以参考我们使用归并排序时候的最后一步&#xff0c;这题的难点其实在于&#xff08;1&#xff09;时间压缩到lognm&#xff08;2&#xff09;…

[附源码]Nodejs计算机毕业设计基于与协同过滤算法的竞赛项目管理Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

基于MMEngine和MMDet搭建目标跟踪框架MMTracking-1.0.0rc1-Win10

缘由&#xff1a; 1. 目标跟踪是工业检测和学术研究的基础课题&#xff0c;其pipeline通常分为视频目标检测、视频实例分割、单目标跟踪、多目标跟踪和Re-ID五类&#xff0c;同时&#xff0c;还细分为在线检测和离线检测两种任务模式。由于现阶段关于目标跟踪的教程较少&#…

机器学习 KNN算法原理

目录 一&#xff1a;KNN算法概念 二&#xff1a;KNN原理 三&#xff1a;KNN超参数 四&#xff1a;KNN算法选择 一&#xff1a;KNN算法概念 KNN(K-Nearest Neighbor)法即K最邻近法&#xff0c;最初由Cover和Hart于1968年提出&#xff0c;是最简单的机器学习算法之一 算法思路…

NNDL 作业9:分别使用numpy和pytorch实现BPTT

6-1P&#xff1a;推导RNN反向传播算法BPTT. 6-2P&#xff1a;设计简单RNN模型&#xff0c;分别用Numpy、Pytorch实现反向传播算子&#xff0c;并代入数值测试.、 forward&#xff1a; 我们知道循环卷积网络的cell的计算公式为&#xff1a; stf(UxtWst−1)\mathrm{s}_tf(…

UML学习入门

UML 举一个简单的例子&#xff0c;来看这样一副图&#xff0c;其中就包括了UML类图中的基本图示法。 首先&#xff0c;看动物矩形框&#xff0c;它代表一个类&#xff08;Class&#xff09;。类图分三层&#xff0c;第一层显示类的名称&#xff0c;如果是抽象类&#xff0c;则…

多模块之前的消息引用问题

多模块引用之前的问题目录概述需求&#xff1a;设计思路实现思路分析1.在第一个模块中调用另一个调用模块的Bean2.普通java类 如何获取另一个模块的Bean3.启用消息机制4.为什么普通java类很难调用SpringBean的&#xff1f;参考资料和推荐阅读Survive by day and develop by nig…