• Mysql 系列 | 日志模块


    了解了 SQL 执行的流程,知道每一条语句都经过连接器、查询存储、分析器、优化器、执行器最后到存储引擎的过程。查询语句是如此,更新语句也不例外。
    不同的是,更新语句会修改表数据,这里就涉及到两个重要的日志模块 redologbinlog
    本篇还是选用 InnoDB 搜索引擎。

    系统的日志模块

    之一 redolog

    下面引入丁奇的经典比喻。

    《孔乙己》这篇文章中,酒店掌柜有一个粉板,专门用来记录客人的赊账记录。
    如果赊账的人不多,他可以把顾客名和账目写在板上。
    但如果赊账的人多了,粉板总会有记不下的时候,这个时候掌柜一定还有一个专门记录赊账的账本。
    
    如果有人要赊账或者还账的话,掌柜一般有两种做法:
    一是直接把账本翻出来,把这次赊的账加上去或者扣除掉;
    另一种是先在粉板上记下这次的账,等打烊以后再把账本翻出来核算。
    
    在生意红火柜台很忙时,掌柜一定会选择后者,因为前者操作实在是太麻烦了。
    首先,你得找到这个人的赊账总额那条记录。你想想,密密麻麻几十页,掌柜要找到那个名字,可能还得带上老
    花镜慢慢找,找到之后再拿出算盘计算,最后再将结果写回到账本上。
    
    你想想,如果掌柜没有粉板的帮助,每次记账都得翻账本,效率是不是低得让人难以忍受?
    

    上面的比喻非常形象地说明了 Mysql 中的 WAL(Write-Ahead-Logging) 技术。

    先写日志(redolog),再写磁盘。也就是先写粉板再写账本。

    • redolog 是 InnoDB 引擎特有的日志。

    • 当有数据要更新时,InnoDB 会先记录 redolog,同时更新内存,更新操作就结束了。等到合适的时候(空闲或者粉板写满了),再更新磁盘。

    • redolog 有固定大小,就像固定大小的粉板,写满就得回到开头循环写。

      • write pos 是当前记录粉板的位置,一边写一边往后移。

      • check point 是擦除的位置,擦除前会把更新记录到数据文件。

      • redolog 保证了数据库异常重启时数据不丢失,这个能力被称为 crash-safe

    image
    (丁奇原图)

    • redolog 默认在 Mysql 的 data 目录下,ib_logfile0、ib_logfile1、。。。
    mysql> show variables like "innodb_log_group_home_dir";
    +---------------------------+-------+
    | Variable_name             | Value |
    +---------------------------+-------+
    | innodb_log_group_home_dir | ./    |
    +---------------------------+-------+
    1 row in set (0.00 sec)
    
    • 设置 redolog 文件大小及个数,默认 2 个文件(innodb_log_files_in_group),每个文件 32M(innodb_log_file_size)
    mysql> show variables like "innodb_log_file%";
    +---------------------------+----------+
    | Variable_name             | Value    |
    +---------------------------+----------+
    | innodb_log_file_size      | 33554432 |
    | innodb_log_files_in_group | 2        |
    +---------------------------+----------+
    2 rows in set (0.00 sec)
    
    • 设置 redolog 实时直接持久化到磁盘上,保证重启后数据不丢失。
    mysql> show variables like "innodb_flush_log_at_trx_commit";
    +--------------------------------+-------+
    | Variable_name                  | Value |
    +--------------------------------+-------+
    | innodb_flush_log_at_trx_commit | 1     |
    +--------------------------------+-------+
    1 row in set (0.00 sec)
    

    之二 binlog

    • binlog 是 Server 层的日志,叫归档日志。不同于 redolog 只有 InnoDB 有,binlog 任何引擎都可以使用。

    • binlog 是逻辑日志,记录语句的原始逻辑;redolog 是物理日志,记录数据页的修改内容。

    • binlog 不会循环写,一个写完后切换到写一个;redolog 有固定的大小。

    • binlog 在 data 目录下,mysql-bin.xxxxxx。

    • 设置 binlog 每次事务直接持久化到磁盘上,保证重启后数据不丢失。

    mysql> show variables like "sync_binlog";
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | sync_binlog   | 1     |
    +---------------+-------+
    1 row in set (0.00 sec)
    

    update 的执行过程

    update T set c=c+1 where ID=2;
    
    • 执行器调用引擎接口找 ID=2 的数据,如果 ID=2 数据所在的数据页在内存中,则直接返回给执行器。否则先从磁盘读取再返回。

    • 执行器拿到数据,把 c 加 1,得到新的一行数据。然后调用引擎接口,写入这行数据。

    • 引擎将新数据更新到内存中,顺便记录 redolog,此时 redolog 处于 prepare 状态,然后告诉执行器可以提交事务。

    • 执行器把 binlog 写入磁盘,然后调用引擎接口提交事务。redolog 状态变为 commit。更新完成。

    数据恢复

    既然记录了 log,那么当数据误操作后,就可以根据数据库定期备份,加上记录的 log 方便的恢复到误操作之前的状态。

    • 先根据备份恢复到临时表

    • 根据 binlog 找到备份后到误操作前的记录。

    • 把恢复好的临时库按需要同步到正式库中。


    只要有 log,就可以恢复到任何时刻的数据状态。

    再也不用担心误操作无法恢复了。

  • 相关阅读:
    Vue框架总结(三、Vue组件化以及CLI编程)
    前端性能优化:dns-prefetch和preload预加载资源
    Android ColorStateList的基本使用
    代码优化个人经验总结(以代码解耦模块化 减少代码量为目标 提高可维护性降低bug率)
    Linux下查看输入设备、获取输入事件的详细方法
    Spring Boot中Spring MVC的表单标签库与数据绑定讲解与实战(附源码 超详细必看)
    第P4周:猴痘病识别
    QT6中添加串口模块SerialPort最简单方法
    Gateway微服务路由使微服务静态资源加载失败
    小波去噪算法的简易实现及其扩展(小波锐化、高斯拉普拉斯金字塔去噪及锐化)之一。
  • 原文地址:https://www.cnblogs.com/rendd/p/16497514.html