博客
关于我
《架构师36项修炼》Mysql 异常情况下的事务安全 -- 详解 Mysql redolog
阅读量:598 次
发布时间:2019-03-12

本文共 2155 字,大约阅读时间需要 7 分钟。

MySQL InnoDB 引擎的 Crash Safe 能力解析

在之前的文章中,我们探讨了 MySQL 的二进制日志(binlog)及其在数据同步、恢复和回滚中的重要作用。然而,binlog 并不能完全保证 Crash Safe(灾后恢复)能力。Crash Safe 是 MySQL ACID 特性中的关键组成部分——原子性(Atomicity),它确保了在服务器突然断电或宕机时,已提交的数据不会丢失,而未提交的数据能够自动回滚。

尽管 binlog 是事务提交时写入的,但如果在 binlog 缓存持久化到硬盘之前发生断电或宕机,可能会导致部分已提交操作数据丢失。这种情况下,主数据库和从数据库之间可能出现数据不一致,严重影响数据库的可用性。

然而,InnoDB 存储引擎却具有 Crash Safe 能力,其实现机制值得我们深入探讨。


MySQL 执行过程与存储引擎差异

无论使用哪种存储引擎,只要配置允许,MySQL 都会记录 binlog。然而,MyISAM 引擎并不提供 Crash Safe 能力,而 InnoDB 则提供了灾后恢复能力,这背后有着深刻的技术原因。

MySQL 的执行过程主要分为两个层次:客户端与 server 层的交互,以及具体 SQL 语句的执行和处理。binlog 的记录和管理则完全由 server 层完成。

而 InnoDB 作为具体的存储引擎,通过 redolog 实现了 Crash Safe 能力。


Redolog 的写入机制

MySQL 的核心技术理念之一是 WAL(Write-Ahead Logging),即先写日志,再写磁盘,从而保证每一次操作都有据可查。在 InnoDB 中,redolog 则采用了不同的写入方式。

与传统的 binlog 不同,redolog 是预先分配固定大小的磁盘空间,并采用循环写入的方式记录数据。具体而言,binlog 是按条记录操作,而 redolog 则是按数据页进行记录,这意味着一个事务中可能会分多次多条写入 redolog。


Crash Safe 与两阶段提交

InnoDB 的 Crash Safe 能力依赖于两阶段提交机制。每条 redolog 都有两个状态:prepare(准备)和 commit(提交)。

以一个简单的 UPDATE 语句为例:

UPDATE A SET C = C + 1 WHERE ID = 2

在执行此操作时,MySQL 会经历以下步骤(深色部分为 MySQL server 层操作,浅色部分为 InnoDB 存储引擎操作):

  • 准备阶段(prepare):InnoDB 先记录 redolog 并标记为 prepare 状态。
  • 提交阶段(commit):InnoDB 将 redolog 更新为 commit 状态。
  • 在异常情况下,InnoDB 会根据 redolog 的状态采取两种处理策略:

  • 如果 redolog 写入成功但 binlog 写入失败,MySQL 会将事务视为失败,直接回滚。
  • 如果 redolog 写入成功且 binlog 也成功,但 redolog 写入失败,MySQL 会根据 redolog prepare 状态和对应的 binlog 记录重新执行事务提交。
  • 通过这种方式,InnoDB 保证了在异常发生后能够准确恢复已提交的数据。

    此外,每条 redolog 都会记录一个全局唯一的逻辑序列号(LSN),将 binlog、数据页和 redolog 统一关联在一起。LSN 成为了整个系统的版本控制依据。


    Redolog 的组织结构

    redolog 是以“块”为单位存储的,每个块的大小为 512 字节。这种以块为单位的存储方式,既保证了与磁盘扇区对齐的特性,也避免了部分写入成功导致的脏数据问题。


    相关配置

    为了充分发挥 InnoDB 的 Crash Safe 能力,以下配置参数尤为重要。

    1. innodb_log_file_size

    • 默认值为 5M,指定 redo log 磁盘空间大小。
    • 较大的文件大小可能导致较长的恢复时间,但可以提高并发写入能力。

    2. innodb_log_buffer_size

    • 默认值为 8M,指定 redo log 缓存大小。
    • 合理配置缓冲区大小可最大化写入性能,同时保证数据安全。

    3. innodb_flush_log_at_trx_commit

    • 这是最关键的配置参数,用于指定事务提交时是否刷盘。
    • 0:每秒刷一次缓冲区,可能丢失最大 1 秒数据。
    • 1:每次事务提交都刷盘,确保数据安全,但可能影响性能。
    • 2:每次事务提交刷一次缓冲区,但仅在固定间隔刷盘,安全性高于 0。

    4. innodb_flush_log_at_timeout

    • 默认值为 1 秒,指定缓冲区刷新的固定间隔。
    • 如果 redo log 缓冲区占用超过一半,则会立即刷盘。

    总结

    通过上述机制,InnoDB 在面对服务器异常时,能够确保已提交的数据不丢失,未提交的数据自动回滚。这种两阶段提交机制与 binlog 的配合,构成了 MySQL 数据库高可用性的重要基础。

    在实际应用中,合理配置以上参数可以在保证数据安全的同时,最大化数据库性能。

    转载地址:http://qalxz.baihongyu.com/

    你可能感兴趣的文章
    wgcloud运维监控系统错误:防篡改校验错误次数大于10次,不再上报数据
    查看>>
    为什么WGCLOUD安装完后,启动服务端打不开网页
    查看>>
    iOS 开发官方文档链接收集
    查看>>
    linux学习笔记(四)基本用户管理与帮助命令
    查看>>
    小程序:防止父方法被子方法冒泡,使用catchtap
    查看>>
    vue报错 created hook错误
    查看>>
    此主机支持Intel VT-x,但Intel VT-x 处于禁用状态。
    查看>>
    12-面向对象1
    查看>>
    HDU - 4109 Instrction Arrangement
    查看>>
    Java位运算,负数的二进制表示形式,int类型最大值为什么是2的31次方-1
    查看>>
    JQuery--手风琴,留言板
    查看>>
    MFC 自定义消息发送字符串
    查看>>
    goahead 下goaction测试与搭建
    查看>>
    Linux操作系统的安装与使用
    查看>>
    ajax请求出现/[object%20Object]错误的解决办法
    查看>>
    流体运动估计光流算法研究
    查看>>
    如何转载博客
    查看>>
    C++ 继承 详解
    查看>>
    OSPF多区域
    查看>>
    Grafana导入 Promethus node模板
    查看>>