1 bin log

1.1 定义

bin log应该说是Mysql里最核心的日志,是MySQL数据库级别的文件,记录对MySQL数据库各种引擎下执行修改的所有操作(包括DDL和DML语句),不会记录select和show语句,主要用于恢复数据库和同步数据库(主从同步)。

1.2 bin log的三种日志格式

binlog 有三种记录格式,分别是ROW、STATEMENT、MIXED。

1、ROW: 基于变更的数据行进行记录,如果一个update语句修改一百行数据,那么这种模式下就会记录100行对应的记录日志。

2、STATEMENT(mysql默认的日志格式):基于SQL语句级别的记录日志,相对于ROW模式,STATEMENT模式下只会记录这个update 的语句。所以此模式下会非常节省日志空间,也避免着大量的IO操作。

3、MIXED: 混合模式,此模式是ROW模式和STATEMENT模式的混合体,一般的语句修改使用statment格式保存binlog,如一些函数的日志;对于statement无法完成主从复制的操作,则采用row格式保存binlog。

这三种模式需要注意的是:使用 row 格式的 binlog 时,在进行数据同步或恢复的时候不一致的问题更容易被发现,因为它是基于数据行记录的。而使用 mixed 或者 statement 格式的 binlog 时,很多事务操作都是基于SQL逻辑记录,我们都知道一个SQL在不同的时间点执行它们产生的数据变化和影响是不一样的,所以这种情况下,数据同步或恢复的时候就容易出现不一致的情况。

1.3 bin log的刷盘时机

binlog 写入策略在进行事务的过程中,首先会把binlog 写入到binlog cache中(因为写入到cache中会比较快,一个事务通常会有多个操作,避免每个操作都直接写磁盘导致性能降低),事务最终提交的时候再吧binlog 写入到磁盘中。当然事务在最终commit的时候binlog是否马上写入到磁盘中是由参数 sync_binlog 配置来决定的。

1、sync_binlog=0 的时候,表示每次提交事务binlog不会马上写入到磁盘,而是先写到page cache,相对于磁盘写入来说写page cache要快得多,不过在Mysql 崩溃的时候会有丢失日志的风险。

2、sync_binlog=1 的时候,表示每次提交事务都会执行 fsync 写入到磁盘(mysql默认的机制);

3、 sync_binlog的值大于1 的时候,表示每次提交事务都 先写到page cach,只有等到积累了N个事务之后才fsync 写入到磁盘,同样在此设置下Mysql 崩溃的时候会有丢失N个事务日志的风险。很显然三种模式下,sync_binlog=1 是强一致的选择,选择0或者N的情况下在极端情况下就会有丢失日志的风险,具体选择什么模式还是得看系统对于一致性的要求。

2 redo log

2.1 定义

redo log是innodb引擎级别,用来记录innodb存储引擎的事务日志,不管事务是否提交都会记录下来,用于数据恢复。当数据库发生故障,innoDB存储引擎会使用redo log恢复到发生故障前的时刻,以此来保证数据的完整性。将参数innodb_flush_log_at_tx_commit设置为1,那么在执行commit时会将redo log同步写到磁盘。

redo log 的设计目标是支持innodb的“事务”的特性,事务ACID特性分别是原子性、一致性、隔离性、持久性, 一致性是事务的最终追求的目标,隔离性、原子性、持久性是达成一致性目标的手段,根据的文章我们已经知道隔离性是通过锁机制来实现的。 而事务的原子性和持久性则是分别通过undo log和redo log 来保障的。

2.2 binlog可以替换redo log用于宕机后的数据恢复吗?

  1. 最核心的一点就是redo log记录的数据变更粒度和binlog的数据变更粒度是不一样的,也正因为这个binlog是没有进行崩溃恢复事务数据的能力的。

  2. 以修改数据为例,binlog 是以表为记录主体,在ROW模式下,binlog保存的表的每行变更记录
    比如update tb_user set age =18 where name =‘赵白’ ,如果这条语句修改了三条记录的话,那么binlog记录就是

UPDATE `db_test`.`tb_user` WHERE @1=5 @2='赵白' @3=91 @4='1543571201' SET  @1=5 @2='赵白' @3=18 @4='1543571201'
UPDATE `db_test`.`tb_user` WHERE @1=6 @2='赵白' @3=91 @4='1543571201' SET  @1=5 @2='赵白' @3=18 @4='1543571201'
UPDATE `db_test`.`tb_user` WHERE @1=7 @2='赵白' @3=91 @4='1543571201' SET  @1=5 @2='赵白' @3=18 @4='1543571201'redo
  1. log则是记录着磁盘数据的变更日志,以磁盘的最小单位“页”来进行记录。
    上面的修改语句,在redo
    log里面记录得可能就是下面的形式。

把表空间10、页号5、偏移量为10处的值更新为18。

把表空间11、页号1、偏移量为2处的值更新为18。

把表空间12、页号2、偏移量为9处的值更新为18。

当我们把数据从内存保存到磁盘的过程中,Mysql是以页为单位进行刷盘的,这里的页并不是磁盘的页,而是Mysql自己的单位,Mysql里的一页数据单位为16K,所以在刷盘的过程中需要把数据刷新到磁盘的多个扇区中去。 而把16K数据刷到磁盘的每个扇区里这个过程是无法保证原子性的,也就意味着Mysql把数据从内存刷到磁盘的过程中,如果数据库宕机,那么就可能会造成一步分数据成功,一部分数据失败的结果。而这个时候通过binlog这种级别的日志是无法恢复的,一个update可能更改了多个磁盘区域的数据,如果根据SQL语句回滚,那么势必会让那些已经刷盘成功的数据造成数据不一致。所以这个时候还是得需要通过redo log这种记录到磁盘数据级别的日志进行数据恢复。

  1. 另一个很重要的点就是并不知道 bin log中的sql语句是否执行成功,因为没有事务是否提交成功的状态记录字段

2.3 redo log刷盘时机

  1. redo lo占用的空间是一定的,并不会无线增大(可以通过参数设置),写入的时候是进顺序写的,所以写入的性能比较高。当redo log空间满了之后又会从头开始以循环的方式进行覆盖式的写入。

  2. 在写入redo log的时候也有一个redo log buffer,日志什么时候会刷到磁盘是通过innodb_flush_log_at_trx_commit 参数决定。

    • innodb_flush_log_at_trx_commit=0 ,表示每次事务提交时都只是把 redo log 留在 redo log buffer 中,只有当buffer中存储了多个事务日志才会刷入磁盘中;
    • innodb_flush_log_at_trx_commit=1,表示每次事务提交时都将 redo log 直接持久化到磁盘;
    • innodb_flush_log_at_trx_commit=2,表示每次事务提交时都只是把 redo log 写到 page cache。
  3. 除了上面几种机制外,还有其它两种情况会把redo log buffer中的日志刷到磁盘。

    • 定时处理:有线程会定时(每隔 1 秒)把redo log buffer中的数据刷盘。
    • 根据空间处理:redo log buffer 占用到了一定程度( innodb_log_buffer_size 设置的值一半)占,这个时候也会把redo log buffer中的数据刷盘。

3 undo log

除了记录redo log外,当进行数据修改时还会记录undo log,undo log用于数据的撤回操作,它保留了记录修改前的内容。通过undo log可以实现事务回滚,并且可以根据undo log回溯到某个特定的版本的数据,实现MVCC。

注释:redo log 和 undo log都是属于事务日志

4 bin log和redo log有什么区别?

  1. bin log会记录所有日志记录,包括InnoDB、MyISAM等存储引擎的日志;redo log只记录innoDB自身的事务日志。
  2. bin log主要用于数据库的 主从复制 以及数据恢复工作(比如恢复到数据库的某一个历史版本),redo log 主要用于发生故障后,让所有数据恢复到发生故障之前的状态
  3. bin log是逻辑日志,记录的是SQL语句;redo log是物理日志,记录的数据格式是 “在某个数据页上做了什么修改”。
  4. bin log的日志空间是二进制流式的缓冲区,写完一个缓冲区后,不会覆盖之前的内容,而是重开一个缓冲区,继续写入日志;
    而redo log的日志空间大小是固定的,通过循环写入的方式将日志写入磁盘,一旦没有空闲空间,则会采用覆盖的方式,覆盖的之前的内容
  5. bin log只在事务提交前被写入一次磁盘(MySQL 5.7.7之后版本的默认保存方式),一个事务只写一次;而对于redo log,在事务开始时会写入一次磁盘,提交redo log为prepare状态,事务提交后又会写入一次磁盘,提交redo log 为commit状态

5 redo log 和 undo log的区别

  1. 目的不同:redo log主要是用于发生故障时的数据恢复操作,将数据恢复到故障发生前的状态,而undo log主要用于事务的回滚,将数据恢复为事务发生前的状态

6 redo、undo、binlog的生成流程与崩溃恢复

当我们执行update user_info set name =“李四” where id=1 的时候大致流程如下:

  1. 从磁盘读取到id=1的记录,放到内存。
  2. 记录undo log 日志。
  3. 记录redo log (预提交状态)
  4. 修改内存中的记录。
  5. 记录binlog
  6. 提交事务,写入redo log (commit状态)

我们根据上面的流程来看,如果在上面的某一个阶段数据库崩溃,如何恢复数据。

1、在第一步、第二步、第三步执行时据库崩溃:因为这个时候数据还没有发生任何变化,所以没有任何影响,不需要做任何操作。

2、在第四步修改内存中的记录时数据库崩溃:因为此时事务没有commit,所以不管有没有将修改的数据写回磁盘,这里都要进行数据回滚,所以这里会通过undo log进行数据回滚。

3、第五步写入binlog时数据库崩溃:这里和第四步一样的逻辑,此时事务没有commit,所以这里要进行数据回滚,会通过undo log进行数据回滚。

4、执行第六步事务提交时数据库崩溃:如果数据库在这个阶段崩溃,那其实事务还是没有提交成功,但是这里并不能像之前一样对数据进行回滚,因为在提交事务前,binlog可能成功写入磁盘了,所以这里要根据两种情况来做决定。

  • 如果binlog存在事务记录:那么就"认为"事务已经提交了,这里可以根据redo log对数据进行重做。其实你应该有疑问,其实这个阶段发生崩溃了,最终的事务是没提交成功的,这里应该对数据进行回滚。 这里主要的一个考虑是因为binlog已经成功写入了,而binlog写入后,那么依赖于binlog的其它扩展业务(比如:从库已经同步了日志进行数据的变更)数据就已经产生了,如果这里进行数据回滚,那么势必就会造成主从数据的不一致。

  • 另外一种情况就 是binlog不存在事务记录,那么这种情况事务还未提交成功,所以会对数据进行回滚。

bin log,redo log以及undo log详解相关推荐

  1. 【MySql进阶】undo日志详解:undo日志结构、undo日志链表、回滚段、undo log原理

    undo日志 本文为阅读<MySql是怎样运行的>的笔记,供大家参考. 文章目录 undo日志 概述 undo日志数据结构 insert 对应的undo log delete 对应的und ...

  2. 容器编排技术 -- Kubernetes kubectl rollout undo 命令详解

    容器编排技术 -- Kubernetes kubectl rollout undo 命令详解 1 kubectl rollout undo 2 语法 3 示例 4 Flags kubectl roll ...

  3. linux bin fuser,Linux中fuser命令用法详解

    描述: fuser可以显示出当前哪个程序在使用磁盘上的某个文件.挂载点.甚至网络端口,并给出程序进程的详细信息. fuser显示使用指定文件或者文件系统的进程ID. 默认情况下每个文件名后面跟一个字母 ...

  4. 蓝牙btsnoop log,HFP协议连接流程详解,以及RFCOMM连接和常用AT指令

    HFP(Hands-Free):蓝牙免提协议,两个角色AG,HF端,AG端通常是手机设备,HF免提端一般为耳机车载等,hfp的连接首先要进行SDP,然后建立RFCOMM,然后SLC连接完成,HFP正式 ...

  5. oracle segment undo_Oracle undo管理详解

    一.What isundo Every Oracle database must have a method of maintaining information that is used to ro ...

  6. undo系统参数详解

    查看与undo相关的系统参数 1.undo_management 有两个参数值:auto.manual(默认) manual:系统启动后使用rollback segment存储undo信息: auto ...

  7. 【图文详解】MySQL事务日志 Redo log(重做) 和 Undo log(撤销)

    InnoDB Architecture https://dev.mysql.com/doc/refman/5.6/en/innodb-architecture.html 我们都知道数据库有四大属性AC ...

  8. 一文聊透binlog、redo log、undo log

    今日推荐 Web登录很简单?开玩笑!知乎热问:国家何时整治程序员的高薪现象?太可怕了!注解+反射优雅的实现Excel导入导出(通用版)Fluent Mybatis 牛逼!Nginx 常用配置清单这玩意 ...

  9. MYSQL专题-MySQL三大日志binlog、redo log和undo log

    日志是mysql数据库的重要组成部分,记录着数据库运行期间各种状态信息.mysql日志主要包括重做日志(redo log).回滚日志(undo log).二进制日志(bin log).错误日志(err ...

  10. 【转】【MySQL】运行原理(四):重做日志(redo log),回滚日志(undo log),二进制日志(binlog)

    MySQL中有六种日志文件,分别是:重做日志(redo log).回滚日志(undo log).二进制日志(binlog).错误日志(errorlog).慢查询日志(slow query log).一 ...

最新文章

  1. jmeter+mysql+set_Jmeter中如何进行对数据库压测(上)
  2. 关系数据库和nosql
  3. 《SpringBoot揭秘:快速构建微服务体系》—第3章3.5节本章小结
  4. 一起来做个免登录资源导航小程序!
  5. 网络管理不简单 需化被动为主动
  6. (25)二分频verilog与VHDL编码(学无止境)
  7. 如何在ASP.NET Core中编写自定义日志记录提供程序
  8. 全网首发:JDK绘制文字:二、绘制句柄的初始化流程
  9. F - Firetrucks Are Red
  10. 蓝桥杯 基础练习 特殊回文数 JAVA
  11. 计算机怎么连接手机网络,电脑怎么连接手机的热点上网?
  12. windows系统c++/VS2019编译gRPC
  13. php file_get_contents 失效,phpfile_get_contents返回空无效解决办法_PHP教程
  14. UVM factory机制源码探微
  15. Android开发本地及网络Mp3音乐播放器(十五)网络音乐及歌词下载功能实现
  16. 开关数字方格哥德巴赫猜想自我数积木
  17. 一条命令轻松绘制CNS顶级配图-ggpubr
  18. hive插入表数据以及出现问题的解决
  19. plc secs通讯协议_SECS/GEM通信协议学习笔记
  20. C语言给出点坐标进行克里金插值,Arcgis笔记之克里金插值——求助surfer8.0

热门文章

  1. 论分布式数据库架构的“存”与“算”
  2. c语言入门经典18个程序,C语言入门经典
  3. 群聊系统项目(基于TCP、UDP实现)
  4. (python)班级身高排序
  5. 说“快乐”还是“安康”?如何在不抬杠的情况下用AI搞定这问题
  6. php中h语言是什么意思,stdio.h是什么意思?
  7. 本人40多岁大龄码农,国内已经没人要了,被优化后去日本工作,一人上班轻松养活三口之家!...
  8. vue.config.js配置完代理还是提示跨域?
  9. 数据库模糊查询和范围查询
  10. 40年未有之大变局,小家电江湖谁主风云