首页 > 数据库 >Mysql之日志

Mysql之日志

时间:2024-03-19 15:57:54浏览次数:29  
标签:binlog 事务 log 记录 Mysql 日志 redo

一、日志类型

MySQL中的日志主要分为两种类型:Server层的日志和引擎层的日志(引擎层日志本文主要介绍InnoDB引擎日志)

  • Server层日志

Error Log (错误日志):记录MySQL Server运行时出现的错误和警告。
Binary Log (二进制日志):记录了MySQL Server层执行的所有修改操作。
Relay Log ( 中继日志):主从复制过程中使用的一种日志类型,在从服务器上记录主服务器上所有的二进制日志(Binary log)的信息。
DDL Log :记录DDL操作的一种日志类型。
General Log(查询日志):记录MySQL Server层的所有查询语句。
Slow Query Log (慢查询日志):记录执行时间过长的查询语句。

  • InnoDB引擎日志(事务日志)

Redo Log:记录事务过程中的修改操作,以保证事务的安全性。
Undo Log:用于撤销与事务相关的修改操作,以保证事务的原子性。

比较重要是二进制日志binlog(二进制日志)和事务日志redo log(重做日志)和undo log(回滚日志)。

二、binlog

binlog是数据库server层实现的,所以任何存储引擎都能使用binlog。不管用什么存储引擎,只要发生了表数据更新,都会产生binlog日志。
binlog是追加写入的,可以一直增加
binlog是没有故障恢复能力的

  • 刷盘机制

binlog在内存中会对应一个binlog cache的区域(每个线程对应一个),当sql语句(修改表内容的语句,查询类语句是不记录的)执行时就会把语句逻辑写入到binlog cache中,当事务提交的时候MySQL会把binlog cache中的内容写入磁盘,一个事务的binlog是不能被拆分的,不论事务多大也要确保事务一次性写入磁盘,这意味着binlog中的语句是按一个个事务排好的,不存在事务语句相互穿插的情况。

在事务提交时进行日志刷盘的操作其实分为两个步骤,

第一步叫做write是把MySQL的binlog cache的内容写到操作系统的文件缓冲区,这个过程实际上是内存操作。
第二步叫做fsync,这才是真正把日志内容持久化到磁盘的操作,涉及到磁盘IO,执行速度较慢。

使用sync_binlog参数可以控制write和fsync的时机:

  • sync_binlog=0 的时候,表示每次提交事务都只 write,不 fsync;(不建议,断电后丢失日志)
  • sync_binlog=1 的时候,表示每次提交事务都会执行 fsync;(最多丢失一个事务日志,每次提交都持久化速度慢)
  • sync_binlog=N(N>1) 的时候,表示每次提交事务都 write,但累积 N 个事务后才 fsync。(主机断电会丢失最近N个事务的binlog日志,需要在风险和速度之间平衡)

我们还需要注意,每个线程的binlog cache是有限的,当事务很大缓存放不下时,会将放不下的部分存在临时文件中,临时文件也是每个线程一个。binlog文件是所有线程共享的。

  • 释放时机
    binlog的默认保持时间由参数expire_logs_days配置,也就是说对于非活动的日志文件,在生成时间超过expire_logs_days配置的天数之后,会被自动删除。

三、redo log
redo log(重做日志)是InnoDB存储引擎独有的,它让MySQL拥有了崩溃恢复能力。比如 MySQL 实例挂了或宕机了,重启时,InnoDB存储引擎会使用redo log恢复数据,保证数据的持久性与完整性。

  • Buffer Pool、redo log buffer

MySQL中数据是以页为单位,你查询一条记录,会从硬盘把一页的数据加载出来,加载出来的数据叫数据页,会放入到 Buffer Pool 中。
后续的查询都是先从 Buffer Pool 中找,没有命中再去硬盘加载,减少硬盘 IO 开销,提升性能。
更新表数据的时候,也是如此,发现 Buffer Pool 里存在要更新的数据,就直接在 Buffer Pool 里更新。
然后会把“在某个数据页上做了什么修改”记录到重做日志缓存(redo log buffer)里,接着刷盘到 redo log 文件里。

什么时候刷盘

redo log在innoDB的内存空间里也有一个redo log buffer的区域先行记录日志内容,当有数据更新时,直接在内存数据页上进行更新,并在redo log buffer中写下日志信息。
再在合适的时候把redo log buffer中的内容写入磁盘。这个写磁盘的操作和binlog一样也分为两步,write和fsync,具体过程见上一节。

我们接着说这个合适的时候,什么时候是什么时候呢?实际上有这么几种情况

  • 一个叫做Master Thread的线程每秒会进行一次写盘操作

每次事务提交的时候可能会执行一次写盘操作(innodb_flush_log_at_trx_commit参数决定);
设置为 0 的时候,表示每次事务提交时都只是把 redo log 留在 redo log buffer 中 ;(MySQL异常重启会丢失)
设置为 1 的时候,表示每次事务提交时都将 redo log 直接持久化到磁盘;(最稳妥)
设置为 2 的时候,表示每次事务提交时都只是把 redo log 写到操作系统缓存。(主机断电会丢失)

内存中redo log buffer剩余空间小于一半的时候会进行一次写盘操作。
redo log就没有binlog中那样每个事务排列在一起不存在事务之间交叉的性质,redo log只关注脏页不关注事务,所以刷新的时候可能是不同事务更新的数据相互穿插。

四、undo log

  • undo log(回滚日志)

用于记录数据被修改前的信息,作用包含两个:提供回滚 和 MVCC(多版本并发控制)。

undo log和redo log记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo og中会记录一条对应的inset记录,反亦然,当update一条记录时,它记录一条对应相反的update记录。当执行rolback时,就可以从undo og中的逻辑记录读取到相应的内容并进行回滚。
Undo log销毁: undo log在事务执行时产生,事务提交时,并不会立即删除undo log,因为这些日志可能还用于MVCC。
Undo log存储: undo log采用段的方式进行管理和记录,存放在前面介绍的 rollback segment 回滚段中,内部包含1024个undo l0segment。

五、两阶段提交

  • redo log和binlog分别在什么时候提交

redo log(重做日志)让InnoDB存储引擎拥有了崩溃恢复能力。

binlog(归档日志)保证了MySQL集群架构的数据一致性。

虽然它们都属于持久化的保证,但是则重点不同。

在执行更新语句过程,会记录redo log与binlog两块日志,以基本的事务为单位,redo log在事务执行过程中可以不断写入,而binlog只有在提交事务时才写入,所以redo log与binlog的写入时机不一样。

  • 面临的问题
    假设执行过程中写完redo log日志后,binlog日志写期间发生了异常,会出现什么情况呢?

    由于binlog没写完就异常,这时候binlog里面没有对应的修改记录。因此,之后用binlog日志恢复数据时,就会少这一次更新,最终数据不一致。
    为了解决两份日志之间的逻辑一致问题,InnoDB存储引擎使用两阶段提交方案。

原理很简单,将redo log的写入拆成了两个步骤prepare和commit,这就是两阶段提交。

使用两阶段提交后,写入binlog时发生异常也不会有影响,因为MySQL根据redo log日志恢复数据时,发现redo log还处于prepare阶段,并且没有对应binlog日志,就会回滚该事务。

原文链接

https://zhuanlan.zhihu.com/p/609972086

https://blog.csdn.net/qq_40687433/article/details/112540401

标签:binlog,事务,log,记录,Mysql,日志,redo
From: https://www.cnblogs.com/OpenSourceSite/p/18081575

相关文章

  • 如何保证mysql的高可用性?我们用docker来做个实践。
    前言前段时间写了一篇关于mysql双主复制的文章,在这个的基础上我们来做个高可用的实践。前期准备,需要安装好docker、docker-compose的运行环境。mysql如何实现双主复制?我们用docker来个做实践。-CSDN博客一、安装haproxy1、创建haproxy目录,执行如下命令。mkdir-p/docke......
  • mysql存储过程查询结果循环遍历 判断 赋值 游标等基本操作
    时间:2018-03-2617:58:45一、首先说下本篇博客所实现功能的背景和功能是怎样的:   背景:因为公司项目开始迁移新平台项目,所以以前的平台老数据以及订单信息需要拆分表,而且需要业务逻辑来分析以前的订单表,来拆分成另外的几个新表,包括增加新的流水分析,以及更新其他用户或者......
  • Mysql带返回值与不带返回值的2种存储过程
    时间:2018-03-3000:25:57过程1:带返回值:dropprocedureifexistsproc_addNum;createprocedureproc_addNum(inxint,inyint,outsumint)BEGINSETsum=x+y;end然后,执行过程,out输出返回值:callproc_addNum(2,3,@sum);select@sum;过程2:不带返回值:dropp......
  • mysql查看数据库锁等待排查笔记
    实验版本:5.7.27 命令如下:mysql>useinformation_schema;  mysql>selectcount(*)fromINNODB_LOCK_WAITS; +----------+ |count(*)| +----------+ |      50| +----------+ 1rowinset,1warning(0.00sec)  SHOWENGINEINNODB......
  • MySQL面试内容2
    1、MySQL面试内容2、如何定位慢查询*聚合查询*多表查询*表数据量过大查询*深度分页查询表象:页面加载过慢、接口压测响应时间过长(超过1s)2.1使用开源组件调试工具:Arthas运维工具:Prometheus、Skywalking2.2使用MySQL自带的监控MySQL自带慢日志慢查询日志记录......
  • .Net Core微服务 - Seq 日志聚合
    Seq简介Seq是一款使用现代化技术构建的结构化日志存储,查询,分析工具。比起ELK这种组合要轻量级许多。只需要一个安装包就具有数据存储,查询,图表分析功能。它对windows友好,直接提供了安装包。当然也可以使用docker来部署。Seq对于单个用户是免费的,这对于一些小团队并没有什......
  • .Net Core微服务 - Serilog+Seq记录日志
    Serilog介绍Serilog是用于.NET应用程序的诊断日志记录库。它易于设置,具有干净的API,并且可以在所有最新的.NET平台上运行。Serilog通过NuGet分发,项目包括一个Seirlog核心项目Seirlog和很多接收器sinks(超过100个),这些接收是通过插件的方式来实现将日志写入到各种终端、文件......
  • MySQL虚拟列
    当我们谈论数据库优化时,经常会遇到各种技术和策略。其中,MySQL的虚拟列(也被称为生成列或存储列)是一个引人注目的特性。它不仅可以帮助开发者提高查询效率,还能为数据表提供额外的计算功能,而无需真正改变表的结构。在这篇文章中,我们将深入探讨MySQL虚拟列的发展、原理以及应用。一......
  • Mysql之刷盘机制
    一、刷盘机制总览刷盘过程mysql刷脏数据在写redo之后,逻辑跟oracle一致。checkpoint/commit->内存中的redo到redolog文件->内存中的脏数据到数据盘。但是mysql多一个环节,就是把binlog从binlogcache写入到binlog文件中。binlogcache不是共享内存,是为每个client分......
  • 配置MySQL-项目BotBattle
    目录数据库配置常用操作项目地址:https://github.com/aijisjtu/Bot-BattlegraphLRA[配置数据源]-->B[建立连接]B-->C[执行SQL语句]C-->D[处理结果]D-->E[关闭连接]配置数据源:设置数据库地址、用户名和密码等。建立连接:与数据库服务器建立通信通道......