当前位置: 首页 > news >正文

谈谈mysql的日志的用途

目录

1、表空间结构

1.1、分类

1.2、物理结构

1. 表空间头(Header)

2. 段(Segment)

3. 区(Extent)

4. 页(Page)

5. 空闲列表(Free List)

1.3、逻辑结构

1. 主键索引(聚簇索引)

2. 二级索引(辅助索引)

3. 事务与 MVCC 机制

2、binlog

2.1. 定义

2.2. 核心作用

2.3. 存储位置

2.4. 格式

2.5、binlog刷盘时机

3、redlog

3.1、原理及流程

3.2、核心作用

3.3、存储位置

3.4、特性

3.5、联系

3.6、应用场景

1. 主从复制

2. 数据恢复

3. 数据一致性

4、undolog

4.1、介绍

4.2、流程

4.3、日志结构

5、常见问题与优化


前言

关于更多mysql的知识可参考:聊聊对Mysql数据库的见解_如何更好的理解mysql-CSDN博客

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

以下是mysql数据库中常用的几种日志类型:

关于每种日志的类型的功能可参考:

关于如何查询日志是否开启,可使用以下命令:

        MySQL 中的 binlog 和 redolog 是两种核心日志机制,它们在数据库的 数据持久化主从复制 和 崩溃恢复 中扮演关键角色。

关于两者如何进行相互联系的,可参考如下:

1、表空间结构

1.1、分类

        MySQL数据表以文件方式存放在磁盘中,默认使用共享表空间(0)存储。

1.对于 InnoDB:

ibdata 文件:

        当使用共享表空间时,所有表的数据和索引会存储在一个共享的 ibdata 文件中。表结构以 .frm 文件的形式存储在与表对应的文件夹中。

.ibd 文件:

        如果使用了独立表空间,InnoDB 会将每个表的结构和数据存储在独立的 .ibd 文件中。每当表的数据或索引被更新时,文件也会随之变化。表的结构仍然以 .frm 文件存储。

2.对于 MyISAM:

        每个表的数据和索引不属于共享空间或独立空间的问题,而是直接通过三个文件来管理的:

MyISAM 数据表通常使用三种文件,分别是:
        .frm:存储表的结构信息。
        .MYD:存储表的数据。
        .MYI:存储表的索引。

3. 设置

  • 使用共享表空间:

    • 只需将 innodb_file_per_table 设置为 0 或不设置(默认值)。
  • 使用独立表空间:

    • 可以在 MySQL 配置文件(my.cnf 或 my.ini)中启用独立表空间,添加如下配置:
[mysqld]
innodb_file_per_table=1

这将允许每个 InnoDB 表都有其独立的 .ibd 文件。

1.2、物理结构

如下图所示:

        独立表空间文件(.ibd),每个独立表在磁盘上对应一个 .ibd 文件( test_table.ibd)

主要包括以下部分:

1. 表空间头(Header)

  • 存储表空间的基本信息,如:
    • 表空间 ID。
    • 区(Extent)的分配状态。
    • 空闲列表(Free List)、碎片列表(Fragment List)等。
  • 用于管理表空间的物理分配和回收。

2. 段(Segment)

InnoDB 的存储结构是分层的:段 → 区 → 页。每个表空间文件包含多个段,主要分为以下几类:

  • 数据段(Data Segment)
    • 存储 B+ 树的 叶子节点(数据页),即实际的行数据。
    • 对于主键索引(聚簇索引),数据段直接存储完整的行数据。
  • 索引段(Index Segment)
    • 存储 B+ 树的 非叶子节点(索引页),即索引键值和子节点指针。
    • 用于加速数据检索。
  • 回滚段(Rollback Segment)
    • 存储事务的 Undo Log(回滚数据),用于实现事务回滚和 MVCC(多版本并发控制)。
    • 每个事务可能关联一个或多个回滚段。

3. 区(Extent)

  • 每个段由多个 (Extent)组成,一个区固定包含 64 个连续页(默认页大小为 16KB,因此一个区大小为 1MB)。
  • 区是 InnoDB 分配存储空间的基本单位,用于提高分配效率。

4. 页(Page)

  • 页是 InnoDB 的最小存储单元,大小默认为 16KB
  • 页的类型取决于其所属的段:
    • 数据页:存储 B+ 树叶子节点的数据(如主键索引的行数据)。
    • 索引页:存储 B+ 树非叶子节点的索引键值和子节点指针。
    • 回滚页:存储 Undo Log(回滚数据)。
    • 系统页:存储表空间的元数据(如空闲列表、区分配信息等)。

5. 空闲列表(Free List)

  • 记录表空间中未被使用的页,供后续分配。
  • 当插入新数据或更新索引时,InnoDB 会从空闲列表中分配页。

小结

        一张表的空间由页节点段、非页节点段、回滚段、和表空间组成。页节点段由多个区(1MB)组成,每个区由64个页(16KB)组成,每个页有多行组成。

如下图所示:

1.3、逻辑结构

        B+ 树索引与数据组织,InnoDB 的表逻辑上通过 B+ 树索引 组织数据。

具体如下:

1. 主键索引(聚簇索引)

  • 叶子节点:存储完整的行数据(包括所有列的值)。
  • 非叶子节点:存储主键值和指向子节点的指针。
  • 聚簇索引决定了数据在磁盘上的物理存储顺序,因此主键选择直接影响性能。

2. 二级索引(辅助索引)

  • 叶子节点:存储主键值(而非完整行数据)。
  • 非叶子节点:存储索引键值和子节点指针。
  • 查询时,InnoDB 会先通过二级索引定位到主键值,再通过聚簇索引查找完整行数据。

3. 事务与 MVCC 机制

  • Undo Log(回滚段中的页):
    • 记录事务修改前的数据版本。
    • 支持事务回滚(Rollback)和并发读取(MVCC)。
  • 版本链(Version Chain)
    • 每个行记录通过 Undo Log 构建版本链,供不同事务读取一致性视图。

关于独立表和共享表的区别:


2、binlog

2.1. 定义

        binlog(Binary Log) 是 MySQL 的 服务层日志,属于二进制日志,记录所有对数据库的 增删改操作(不包含查询)。由 MySQL Server 层生成,与存储引擎无关(如 InnoDB、MyISAM)。默认情况下二进制日志是关闭的。

结构如下所示:

2.2. 核心作用

1.主从复制(Replication)

            主库将 binlog 发送给从库,从库重放 binlog 实现数据同步。

    2.数据恢复(Point-in-Time Recovery)

            通过 binlog 恢复到某个时间点的数据状态。

    2.3. 存储位置

            默认存储在 MySQL 数据目录下的 mysql-bin.xxxxxx 文件中。

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

    如下图所示:

      mysql> show binary logs;
      +------------------+-----------+
      | Log_name         | File_size |
      +------------------+-----------+
      | mysql-bin.000001 |       201 |
      | mysql-bin.000002 |       154 |
      +------------------+-----------+
      2 rows in set (0.00 sec)
      

      2.4. 格式

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

      可使用以下命令,查看到:

      • Row-based:记录每一行的变更(5.7.7后默认)。
      • Statement-based:记录 SQL 语句(5.7.7之前默认)。
      • Mixed:混合模式。

      三种不同格式的优缺点:

      配置如下:

      [mysqld]
      log-bin=mysql-bin  # 开启 binlog
      server-id=1        # 主库 ID
      

      2.5、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、redlog

              持久性只要事务提交成功,那么对数据库做的修改就被永久保存下来了,不可能因为任何原因再回到原来的状态 。

      那么 mysql是如何保证一致性的呢?

              在每次事务提交的时候,将该事务涉及修改的数据页全部刷新到磁盘中。但是这么做会有严重的性能问题。

      主要体现在两个方面:

      1. 因为 Innodb 是以  为单位进行磁盘交互的,而一个事务很可能只修改一个数据页里面的几个字节,这个时候将完整的数据页刷到磁盘的话,太浪费资源了!

      2. 一个事务可能涉及修改多个数据页,并且这些数据页在物理上并不连续,使用随机IO写入性能太差!

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

      关于流程如下图所示:

      3.1、原理及流程

         redo log 包括两部分:一个是内存中的日志缓冲( redo log buffer ),另一个是磁盘上的日志文件( redo logfile)。

      • redolog(Redo Log) 是 InnoDB 存储引擎 的事务日志,记录 事务对数据页的物理修改
      • 用于保证事务的 持久性(Durability),防止数据丢失。

          mysql 每执行一条 DML 语句,先将记录写入 redo log buffer,后续某个时间点再一次性将多个操作记录写到 redo log file。这种 先写日志,再写磁盘 的技术就是 MySQL里经常说到的 WAL(Write-Ahead Logging) 技术。

              在计算机操作系统中,用户空间( user space )下的缓冲区数据一般情况下是无法直接写入磁盘的,中间必须经过操作系统内核空间( kernel space )缓冲区( OS Buffer )。

              因此, redo log buffer 写入 redo logfile 实际上是先写入 OS Buffer ,然后再通过系统调用 fsync() 将其刷到 redo log file中。

      过程如下:

               可以通过 innodb_flush_log_at_trx_commit 参数配置将 redo log buffer 写入 redo log file 的时机,

      3.2、核心作用

      如下图所示:

      1. 事务持久化
        • 事务提交时,先将修改写入 redolog,再异步刷盘到数据文件。
      2. 崩溃恢复(Crash Recovery)
        • 数据库重启时,通过 redolog 恢复未落盘的数据。

      3.3、存储位置

      • 默认存储在 ib_logfile0 和 ib_logfile1 文件中(InnoDB 专属)。

               

      3.4、特性

      • 固定大小:默认 4GB(可通过 innodb_log_file_size 配置)。
      • 循环写入:当文件写满时,覆盖旧日志。
      • 物理日志:记录的是数据页的物理修改(如某个页的某个偏移量被修改)。

           redo log 实际上记录数据页的变更,而这种变更记录是没必要全部保存,因此 redo log实现上采用了大小固定,循环写入的方式,当写到结尾时,会回到开头循环写日志。

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

      配置如下:

      [mysqld]
      innodb_log_file_size = 1G  # 设置 redolog 大小
      innodb_flush_log_at_trx_commit = 1  # 事务提交时立即刷盘
      

      关于redlog buffer的内存结构如下:

      关于redlog buffer到redo log file持久化的流程如下图:

      关于binlog和redlog的区别联系如图所示:

      3.5、联系

      binlog 与 redolog的联系。

      1. 事务提交流程中的协作

      1. 事务执行:修改数据页(内存中)。
      2. 写入 redolog:事务提交时,将修改写入 redolog(确保持久性)。
      3. 写入 binlog:事务提交后,将修改写入 binlog(用于主从复制和恢复)。

      关键区别

      • redolog 是 InnoDB 的事务日志,确保事务的原子性和持久性。
      • binlog 是 MySQL 的逻辑日志,用于主从复制和数据恢复。

      2. 数据一致性保障

      • redolog:确保事务的修改不会因宕机丢失。
      • binlog:确保主从节点的数据一致性。

      3. 崩溃恢复流程

      1. 恢复 redolog:数据库重启时,通过 redolog 恢复未落盘的事务。
      2. 恢复 binlog:通过 binlog 恢复到某个时间点(需结合 redo log)。

      3.6、应用场景

      1. 主从复制

      • 主库:将 binlog 发送给从库。
      • 从库:重放 binlog 实现数据同步。

      2. 数据恢复

      • 基于 binlog:恢复到某个时间点(如误删数据后回滚)。
      • 基于 redolog:恢复未落盘的事务(数据库崩溃后自动恢复)。

      3. 数据一致性

      • binlog + redolog:共同保证 ACID 中的 D(Durability) 和 主从一致性

      区别如下所示:


      4、undolog

      4.1、介绍

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

              同时, undo log 也是 MVCC(多版本并发控制)实现的关键。

      4.2、流程

      关于undolog的流程如下图所示:

      4.3、日志结构

      关于undolog的日志结构如下图所示:


      5、常见问题与优化

      1. binlog 导致磁盘空间不足

      • 问题:binlog 无限增长,占用磁盘空间。
      • 解决方案:
      -- 查看 binlog 状态
      SHOW VARIABLES LIKE 'expire_logs_days';-- 设置自动清理(单位:天)
      SET GLOBAL expire_logs_days = 7;
      

      2. redolog 刷盘性能问题

      • 问题innodb_flush_log_at_trx_commit=1 会降低性能。
      • 优化建议
        • 生产环境:保持默认值 1(保证数据安全)。
        • 性能优先场景:可设置为 2(每秒刷盘一次,风险略高)。

      总结

              MySQL中的binlog、redolog和undolog日志类型,包括它们的作用、格式和刷盘机制。binlog主要用于主从复制和数据恢复,redolog确保事务的持久性,而undolog则实现了事务的原子性。

              通过理解这些日志机制,可以更好地保障数据库的安全性和性能。

      参考文章:

      1、必须了解的 MySQL 三大日志-CSDN博客

      相关文章:

    • Google精准狙击OpenAI Codex,发布AI编程助手Jules!
    • Kubernetes在线练习平台深度对比:KillerCoda与Play with Kubernetes
    • Rofin PowerLine E Air维护和集成手侧激光Maintenance and Integration Manual
    • 本地ip如何映射到外网?借助端口映射软件把内网地址给别人用
    • Python 包管理工具核心指令uv sync解析
    • 学习STC51单片机08(芯片为STC89C52RC)
    • 五、central cache的设计
    • unity XCharts插件生成曲线图在UICanvas中
    • TrollStore(巨魔商店)的由来介绍
    • 山东大学计算机图形学期末复习完结篇上——24历年题
    • CAU数据库class3 关系型数据库基础
    • 2001-2023年上市公司管理讨论与分析文本数据(MDA文本数据)
    • 【算法】定长滑动窗口5.20
    • 十五、面向对象底层逻辑-BeanDefinitionRegistryPostProcessor接口设计
    • 瀚高安全版4.5.8/4.5.9字符串默认按字节存储导致数据无法写入(APP)
    • Python 包管理工具uv依赖分组概念解析
    • [ 计算机网络 ] 深入理解OSI七层模型
    • 数据库分库分表从理论到实战
    • 现代计算机图形学Games101入门笔记(十七)
    • 深度学习架构快速入门——卷积神经网络CNN、循环神经网络RNN、生成对抗网络GAN、Transformer以及编码器-解码器
    • 财政部:今年将和住建部选拔第二批20个城市,高质量推进城市更新行动
    • 66岁华仁世纪集团有限公司创始人、董事长梁福东逝世
    • 减重人生|吃得越少越好?比体重秤上的数字,更有意义的是什么?
    • 网约车司机猝死,平台和保险公司均拒绝赔偿,法院判了
    • 国新办10时将举行新闻发布会,介绍4月份国民经济运行情况
    • 九江银行落地首单畜牧业转型金融业务,助推传统农业绿色智能