• MySQL的Redo log 、Undo log、 Binlog


    MySQL的redo log 、undo log、 binlog

    redo log概念

    redo log翻译过来叫重做日志,是一种保证持久化的措施,innodb存储引擎的物理日志文件

    redo log是固定大小的,是循环写的过程

    有了redo log之后,innodb就可以保证即使数据库发生异常重启, 之前的记录也不会丢失,叫做crash-safe

    undo log概念

    Undo Log是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中, 还用Undo Log来实现多版本并发控制(简称:MVCC)

    操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份的地方 称为Undo Log)。然后进行数据的修改。如果出现了错误或者用户执行了 ROLLBACK语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之 前的状态

    注意:undo log是逻辑日志,undo log记录在redo log里面,可以理解为:

    • 当delete一条记录时,undo log中会记录一条对应的insert记录
    • 当insert一条记录时,undo log中会记录一条对应的delete记录
    • 当update一条记录时,它记录一条对应相反的update记录

    binlog概念

    bin log是服务端的日志文件,主要做mysql功能层面的事情

    与redo日志的区别:

    1、redo是innodb独有的,binlog是所有引擎都可以使用的

    2、redo是物理日志,记录的是在某个数据页上做了什么修改,binlog是逻 辑日志,记录的是这个语句的原始逻辑

    3、redo是循环写的,空间会用完,binlog是可以追加写的,不会覆盖之前 的日志信息

    数据刷盘流程

    innodb是用页单位来管理存储空间的,任何的DML都会操作完整的一个页,会将整个页加载到用户态中内存下的Buffer Pool中,然后对需要修改的数据进行修改,这时数据不会立即刷新到到磁盘(目的是不浪费磁盘IO)而是通过undo log 数据备份、redo log先记录数据变化,再由异步线程把数据刷到磁盘上,这样即使系统崩溃,再恢复后,也可以根据redo日志进行数据恢复。

    1. 当发生数据修改的时候,innodb引擎会先将记录写到redo log中, 并更新内存,此时更新就算是完成了,同时innodb引擎会在合适 的时机将记录操作到磁盘中
    2. redo log 是以组的方式写入,在一个事务中,这些redo log称为一个组redo log, 组redo log具有原子性
    3. Log Buffer 16MB 每个Buffer由Block组成,每个Block块 512byte

    在这里插入图片描述
    在这里插入图片描述

    redo log刷盘时机

    通过参数innodb_flush_log_at_trx_commit控制

    1. commit的时候进行刷盘:这也是最保险的,因为如果这个时候崩溃了代表没有commit成功,因此,也不用恢复什么数据
    2. commit的时候,只是刷新近os的内核缓冲区,具体的刷盘时机不确定
    3. 后台线程,每s刷新一次到磁盘中

    两阶段提交

    通过redo log、和bin log来保证数据一致性,不同阶段断电情况如下

    更改数据:redo log 和bin log都没有持久化,因此数据是一致的

    写redo log(prepare状态):mysql重启后,首先检查redo log状态,如果有并且状态处于prepare状态,查看有没有bin log日志,有的话正常提交,没有则删除处于prepare的redo log

    写binlog:mysql重启后,查看有没有bin log日志,有的话正常提交,没有则删除处于prepare的redo log

    提交事务commit状态:此时走刷盘机制

    事务commit成功

    事务执行commit命令后,mysqld将记录了数据修改的Log Buffer写入磁盘上的redo log,然后将这部分数据的状态修改为commit,写完redo log后才算是事务提交成功,MySQL Server需要保持commit状态的数据的持久性。如果写redo log失败,数据的状态还是prepare,尽管事务执行了commit命令,这依然不算commit成功

    DML完整的执行步骤

    update table set column = x where id = 1;
    
    • 1
    1. 获取数据库连接
    2. 判断id=1的这条记录在不在buffer pool中,在的话undo log备份,执行更新,否则从磁盘中加载到buffer pool中,然后进行undo log备份、更新
    3. 将这个更新操作记录到redo log中,记录的是一个物理日志。此时redo log是一个prepare状态
    4. 记录该操作的binlog,并且将binlog刷盘
    5. 提交事务,对redo log进行提交。

    时redo log是一个prepare状态
    4. 记录该操作的binlog,并且将binlog刷盘
    5. 提交事务,对redo log进行提交。

  • 相关阅读:
    MSSQL渗透测试
    Jmix 如何将外部数据直接显示在界面?
    打造安全的Open RAN
    SpringBoot整合knife 4j
    【Android笔记47】Android中的Broadcast Receiver之有序广播和无序广播
    【科普】RPA技术架构:3大组成部分
    从js和json中引入数据的区别
    vue项目切换页面白屏的解决方案
    StarRocks 2.3.0 安装部署
    [CLickhouse] 学习小计
  • 原文地址:https://blog.csdn.net/m0_37540696/article/details/127869518