专栏首页赵俊的Java专栏初识 redo log 和 binlog

初识 redo log 和 binlog

redo log

InnoDB 存储引擎是以页为单位来管理存储空间的, 我们的增删改查操作本质上都是在访问页面, 如读取一条数据, 会把这个数据所在的页加载到内存中, 而不仅仅是这条数据本身, 这个页的默认大小是 16KB.

在事务中, 我们有一个特性: 持久性, 指对于一个已提交的事务, 在事务提交后, 即使系统崩溃, 也要保证这个事务对数据库做的更改不会丢失, 那么我们如何保证这一点呢, 有一个简单粗暴的做法就是: 在事务提交之前, 将事务所修改的所有页面都刷新到磁盘, 但这种做法有几个问题:

  • 刷新一个数据页太浪费了, 可能我们只修改了这个数据页中的一个字节, 但 InnoDB 所有操作都是基于页面的, 我们只修改一个字节就要刷新一个 16KB 的页到磁盘上台浪费了.
  • 随机 IO 刷起来比较慢, 一个事务可能包含了很多语句, 即使一条语句, 也可能修改了许多页面, 有可能修改的这些页面并不相邻, 那么这就需要进行很多次随机 IO, 这相对顺序 IO 来说很慢, 尤其对机械硬盘来说.

那么如何解决这个问题呢, InnoDB 采用了 redo log 机制来解决:

redo logInnodb 存储引擎的特性, 即在更新数据时, 先将更新操作的结果放到 redo log 中, 他存储的是物理日志, 如 将第 0 号表空间的 100 号页面的偏移量为 1000 处的值更新为 2。, 然后过一段时间或待系统空闲时, 一起将多个更新操作在硬盘的数据文件上执行.

不过这个文件是有大小限制的, 当这个文件满的时候, 会删除最先写入的数据.

你可能会问, 写到 redo log 不也是写入到磁盘吗, 这效率会更好吗, 是不是多此一举啊. 其实不是的, 首先每次写入 redo log 的数据是非常小的, 他只记录了这次修改的物理操作. 相较于之前要刷新 1 个或多个 16KB 的页面来说操作的数据量小多了, 而且写 redo log 是顺序 IO, 这整体会快很多.

binlog

binlogMySQL 的功能, 所有存储引擎都可以使用. 记录的是逻辑日志, 如 给 ID = 2 的数据行的 C 字段加 1. 他是追加写入的, 当写到一定大小后, 会切换到写一个文件继续写, 不会覆盖原来的文件. 一般用来做数据库的备份和恢复使用.

两阶段提交

不过既然有两个日志, 那么如何保证不会出现写完 read log, 但还没写 binlog 的时候就宕机了呢, 为了解决这个问题, MySQL 采用了两阶段提交的方式:

  1. 先写入 redo log 状态为 prepare 阶段. (存储引擎层 InnoDB)
  2. binlog (MySQL 服务层)
  3. 提交事务, redo log 状态改为 commit 状态. (存储引擎层 InnoDB)

当系统出现异常宕机时:

  • binlog 有记录,redo log 状态 commit: 正常完成的事务,不需要恢复
  • binlog 有记录,redo log 状态 prepare: 在 binlog 写完提交事务之前的 crash, 恢复操作:提交事务
  • binlog 无记录,redo log 状态 prepare: 在 binlog写完之前的 crash, 恢复操作:回滚事务
  • binlog 无记录,redo log 无记录: 在 redo log 写之前 crash, 恢复操作:回滚事务

相关配置

innodb_flush_log_at_trx_commit 参数设置为 1, 表示每次事务的 redo log 都直接持久化到磁盘, 推荐设置为 1, 这样可以保证 MySQL 异常重启后数据不会丢失.

sync_binlog 参数设置为 1, 表示每次事务的 binlog 都持久化到磁盘, 推荐设置为 1, 这样可以保证 MySQL 异常重启后 binlog 不会丢失.

总结

redo logInnoDB 引擎的特性, 只对使用 InnoDB 引擎的表生效, 记录的是 物理日志, 有大小限制, 他的主要目的是为了保证事务的一致性和提升更新操作的效率. binlog 是 MySQL 的功能, 所有存储引擎都可以使用, 记录的是 逻辑日志, 没有大小限制, 他的主要目的是用于备份和恢复数据使用.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • SLF4J MDC ☞ 将用户信息添加到日志信息中

    你是否有过排查某个用户的操作出现 BUG 时, 从茫茫日志中寻找这个用户操作的痛苦经历, SLF4J 为我们提供了一种基于 ThreadLocal 来实现的 M...

    一份执着✘
  • Shiro加密

    安全总是最重要的,对于用户的数据,我们一般都不会以原密码明文保存,而是经过加密后保存。

    一份执着✘
  • VirtualBox 中 Ubuntu 与 Windows 共享文件夹

    一份执着✘
  • redo log和binlog的一些好问题

    那么如果在两阶段提交的过程中,发生了数据库的崩溃,MySQL内部会做什么事情来保证数据的一致性呢?以上述的update操作为例:

    AsiaYe
  • MYSQL 必考面试题10道(多选)

    MySQL偶尔会出现OOM(内存溢出)现象,导致MySQl服务重启,以下哪种方式能有效缓解OOM的情况发生()

    用户1338460
  • MYSQL 必考面试题10道(答案解释)

    MySQL偶尔会出现OOM(内存溢出)现象,导致MySQl服务重启,以下哪种方式能有效缓解OOM的情况发生()

    用户1338460
  • MySQL 的 crash-safe 原理解析

    MySQL作为当下最流行的开源关系型数据库,有一个很关键和基本的能力,就是必须能够保证数据不会丢。那么在这个能力背后,MySQL是如何设计才能保证不管在什么时间...

    2020labs小助手
  • 每个程序员都应该收藏的算法复杂度速查表

    算法复杂度这件事 这篇文章覆盖了计算机科学里面常见算法的时间和空间的大 O(Big-O)复杂度。我之前在参加面试前,经常需要花费很多时间从互联网上查找各种搜索和...

    用户1667431
  • Linux日志管理

    要知道的是,我们的 Linux 主机在背景之下有相当多的 daemons 同时在工作着,这些工作中的程序总是会显示一些讯息,这些显示的讯息最终会被记载到登录文件...

    小柒吃地瓜
  • Android APP测试的日志文件抓取

      实时打印的主要有:logcat main,logcat radio,logcat events,tcpdump,还有高通平台的还会有QXDM日志

    流柯

扫码关注云+社区

领取腾讯云代金券