MySQL之谈谈MySQL里的日志

文章目录

  • 前言
  • 一、SQL是如何做更新操作的
  • 二、MySQL中的redo log
  • 三、MySQL中的binlog
  • 四、聊聊两阶段提交
  • 总结


前言

上一章我们讲了一条SQL是如何做查询的,其中经历了许多步骤。这次来讲讲一条SQL是如何做更新操作的。
常有大佬说他可以把MySQL恢复到半个月内任意一秒的状态,今天也来谈谈这是如何做到的呢?


一、SQL是如何做更新操作的

之前我们讲到了一条SQL的执行要经过连接器、查询缓存、分析器、优化器、执行器,最后到达存储引擎。其实更新语句也会同查询语句一样,把这些路都走一篇。不过会在此基础上更多一些步骤。还是以一条SQL为例子:

创建一个表T

mysql> create table T(ID int primary key, c int);

如果想把ID=10这行的值+1,SQL就是这样:

mysql> update T set c=c+1 where ID=10;

先通过连接器连接数据库。如果查询缓存中有值就取,没有就走下一步。,分析器会通过词法和语法解析知道这是一条更新语句。优化器决定要使用 ID 这个索引。然后,执行器负责具体执行,找到这一行,然后更新。

与查询流程不一样的是,更新流程还涉及两个重要的日志模块,它们正是我们今天要讨论的主角:redo log(重做日志)和 binlog(归档日志)。
在这里插入图片描述


二、MySQL中的redo log

设想一下,如果每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,整个过程 IO 成本、查找成本都很高。那么MySQL是如何解决这个问题的呢?
这就不得不提到MySQL里常说的WAL技术。全称是 Write-Ahead Logging,它的关键点就是先写日志,再写磁盘,也就是先写把那些SQL都记录下来,等统一时间再来写入。

具体来说,当有一条记录要更新的时候,InnoDB引擎会把这条记录先写到redo log里,并更新内存,再等到系统比较空闲的时候把这个操作记录更新到磁盘。如果一直都很忙没有空闲,那么redo log就会先写入一部分,为后面留下空间。(InnoDB的redo log是固定大小的。比如可以配置为一组 4 个文件,每个文件的大小是 1GB,那么总共就可以记录 4GB 的操作,每次更新一部分到磁盘就可以把已更新的内容擦除)。

有了 redo log,InnoDB 就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为 crash-safe。也就是就算异常重启也能找到写在redo log中的SQL执行内容了。


三、MySQL中的binlog

redo log是InnoDB引擎特有的日志。Sever层也有自己的日志,binlog(归档日志)。

这两种日志有以下三点不同。

  1. redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
  2. redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
  3. redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

那么我们回头来看看上面的SQL在MySQL里是怎么执行的:

  1. Server层中的执行器先找引擎取 ID=10 这一行。根据主键ID,引擎直接找到这一行。如果 ID=10 这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁盘读入内存,然后再返回。
  2. 执行器拿到引擎给的行数据,把这个值加上 1,得到新的一行数据,再调用引擎接口写入这行新数据。
  3. 引擎将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 里面,此时 redo log 处于 prepare 状态。然后告知执行器执行完成了,随时可以提交事务。
  4. 执行器生成这个操作的 binlog,并把 binlog 写入磁盘。
  5. 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新完成。

下图浅绿色为在Server层执行,白色为引擎中执行。
在这里插入图片描述

看完你可能会问,写入redo log后这个prepare是啥意思,还有写完binlog又要commit提交事务。这里的prepare和commit就是将redo log拆成了两阶段提交。


四、聊聊两阶段提交

为什么必须有“两阶段提交”呢?这是为了让两份日志之间的逻辑一致。由于 redo log 和 binlog 是两个独立的逻辑,如果不用两阶段提交,要么就是先写完 redo log 再写 binlog,或者采用反过来的顺序。还是以前面的SQL举例。

1.如果先写redo log后写binlog,结果服务器故障了。redo log写完后c的值就已经+1了,但是由于binlog还没有写完就挂了,之后备份恢复的时候,binlog语句丢失,恢复的值还会是0。
2.如果先写binlog后写redo log。由于binlog写完之后挂了,redo log还没写,服务器恢复后发现事务无效,这个值还是0。但是binlog中已经记录了c从0变成1的日志。最后用binlog恢复的时候就会成为1,和原来库中的不同。

简单说,redo log 和 binlog 都可以用于表示事务的提交状态,而两阶段提交就是让这两个状态保持逻辑上的一致。


总结

MySQL的日志系统在确保数据完整性、持久性和恢复能力方面起着关键作用。
数据一致性:通过重做日志和撤销日志,即使在系统故障的情况下,也能保证数据的一致性。当系统重启时,可以使用重做日志来恢复未完成的事务。
复制和备份:二进制日志用于主从复制和数据备份。从服务器可以读取主服务器的二进制日志,以保持与主服务器相同的数据状态。这使得实现高可用性和负载均衡变得容易。
慢查询监控:查询日志和慢查询日志可以帮助我们识别和优化性能问题。通过分析这些日志,可以找到需要优化的SQL语句或配置。
审计:查询日志可以用于审计目的,跟踪对数据库的访问和修改操作。这对于安全性和合规性检查非常有用。

补充:
MySQL的日志:
二进制日志(Binary Log):记录了对数据库执行的所有修改操作,以二进制形式存储。主要用于复制和数据恢复。
重做日志(Redo Log):存在于InnoDB存储引擎中,用于保证事务的持久性。
撤销日志(Undo Log):也存在于InnoDB存储引擎中,用于支持事务的回滚操作和多版本并发控制。
查询日志(General Query Log)和慢查询日志(Slow Query Log):用于记录数据库的活动和慢查询。

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

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

相关文章

openGauss学习笔记-214 openGauss 性能调优-确定性能调优范围

文章目录 openGauss学习笔记-214 openGauss 性能调优-确定性能调优范围214.1 性能因素214.2 调优范围确定 openGauss学习笔记-214 openGauss 性能调优-确定性能调优范围 数据库性能调优通常发生在用户对业务的执行效率不满意,期望通过调优加快业务执行的情况下。正…

linux搭建jupyter

查看虚拟环境 conda info --envs进入虚拟环境 conda activate my_env pip install jupyter pip install ipykernel1. jupyter notebook启动 1.1 创建临时jupyter notebook任务 jupyter notebook --ip0.0.0.0 --no-browser --allow-root --notebook-dir/home/xxx1.2 jupyter…

[嵌入式AI从0开始到入土]5_炼丹炉的搭建(基于wsl2_Ubuntu22.04)

[嵌入式AI从0开始到入土]嵌入式AI系列教程 注:等我摸完鱼再把链接补上 可以关注我的B站号工具人呵呵的个人空间,后期会考虑出视频教程,务必催更,以防我变身鸽王。 第一章 昇腾Altas 200 DK上手 第二章 下载昇腾案例并运行 第三章…

【Springcloud篇】学习笔记四(九章):Hystrix—服务降级、熔断、限流

第九章_Hystrix服务降级 1.Hystrix简介 1.1分布式系统面临的问题 服务雪崩 1.2Hystrix是什么 1.3Hystrix能干嘛 服务降级服务熔断接近实时的监控 1.4官网资料 官网资料:https://github.com/Netflix/Hystrix/wiki/How-To-Use Hystrix官宣,停更进维…

C#用正则表达式验证密码长度vs用Char.IsLetterOrDigit方法遍历字符数组验证密码长度

目录 一、使用的方法 1.正则表达式 2.Char.IsLetterOrDigit方法 二、源码 1.源代码 2.生成效果 一、使用的方法 1.正则表达式 在注册用户时,经常需要填写密码信息,为保证用户信息的安全性,密码一般情况下要求输入6位或6位以上。本…

如何写好论文——(15)如何写研究目标之实例讲解

写好研究目标一要有方向、二要有边界。 定边界的时候要有方法和结论。 下面的例子为目标的两种写法,第二种提供了更明确可以测量的目标。 下面的第二个例子更有方向性。第一个例子的本质是去验证一种假说,这种假说如果成立完全可以支撑第二种写法中的目…

如何在Windows系统使用Plex部署影音服务与公网访问本地资源【内网穿透】

文章目录 1.前言2. Plex网站搭建2.1 Plex下载和安装2.2 Plex网页测试2.3 cpolar的安装和注册 3. 本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 正文开始前给大家推荐个网站,前些天发现了一个巨牛的 人工智能学习网站, 通…

【Spring】Spring 启示录

一、OCP 开闭原则 核⼼:在扩展系统功能时不需要修改原先写好的代码,就是符合OCP原则的,反之修改了原先写好的代码,则违背了OCP原则的 若在扩展系统功能时修改原先稳定运⾏程序,原先的所有程序都需要进⾏重新测试&…

户外没有电源和网络,但需要安装监控系统,怎么办?太阳能智能监控系统给你解决

近期有粉丝给小编求助:需要在没网没电的户外进行智能监控的安装,不知道如何解决。收到粉丝的问题,小编立刻联系了技术人员给出方案。针对野外、户外等场景只需使用太阳能供电模组4G摄像机视频监控EasyCVR平台智能分析网关V4的架构&#xff0c…

minicoda安装使用

这里写目录标题 1、安装2、使用 1、安装 官网安装教程:https://docs.conda.io/projects/miniconda/en/latest/ 参考:https://www.jianshu.com/p/4d4c786ed454 选择对应的系统 #下载安装 mkdir -p ~/miniconda3 wget https://repo.anaconda.com/minico…

【数据结构与算法】(9)基础数据结构 之 阻塞队列的单锁实现、双锁实现详细代码示例讲解

目录 2.8 阻塞队列1) 单锁实现2) 双锁实现 2.8 阻塞队列 之前的队列在很多场景下都不能很好地工作,例如 大部分场景要求分离向队列放入(生产者)、从队列拿出(消费者)两个角色、它们得由不同的线程来担当,…

Day 2.几个简单的函数接口 今日份浅学

1.函数接口 (1).fgetc: int fgetc(FILE *stream); 功能:从流中度区下一个字符 参数: stream:文件流指针 返回: 成功返回ASCII值 失败返回 EOF 读到文件末尾返回EOF 练习: 读出文…