目录

binlog与redo log

李羽秋
李羽秋 2023年10月23日  ·  阅读 1,149

binlog与redo log

1. redo log

redo log叫做重做日志,是保证事务持久性的重要机制。当mysql服务器意外崩溃或者宕机后,保证已经提交的事务,确定持久化到磁盘中的一种措施。

为什么需要redo log

  • 传统的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,这整个过程IO成本、查找成本都很高。而redo log使用了WAL技术,当有一条记录需要更新时,InnoDB就会先把记录写到redo log里,并更新内存,在一定时机时刷到磁盘中,减少了磁盘io读写,提高了访问速度。
  • redo log主要的作用就是用于数据库宕机的恢复工作。

redo log写入机制

img

redo log是固定大小的,每一组4个文件,每个文件的大小是1GB。它有两个指针:

  • write pos:记录当前写的位置,一边写一边往后移
  • checkpoint:当前要擦除的位置,也是往后推移且循环的

write pos 与checkpoint之间空的部分用来记录新的记录,当write pos 与 checkpoint重合的时候,代表redo log满了,需要先进行记录擦除。

redo log刷盘时机

通过一个参数控制:innodb_flush_log_at_trx_commit

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

2. binlog

binlog是二进制日志文件,记录了数据库所有执行的DDL和DML等数据库更新语句。它是Mysql级别的日志,即所有存储引擎都会产生binlog。

binlog作用

  • 数据恢复:如果Mysql数据库意外挂了,可以利用binlog进行数据恢复,因为该日志记录所有数据库所有的变更,保证数据的安全性。
  • 数据复制:利用一定的机制将主节点Mysql的日志数据传递给从节点,实现数据的一致性,所以binlog对于数据备份、主从等都起到关键作用。

刷盘策略

binlog刷盘时机由sync_binlog控制,默认为0。

  • sync_binlog = 0:每次提交事务都只write,由系统自行判断什么时候执行fsync。(这种情况虽然性能得到提升,但是机器宕机,page cache里面的binlog会丢失。
  • sync_binlog = 1:表示每次提交事务都会执行fsync,更加安全。
  • sync_binlog = N:每次提交事务都write,等积累到N个事务后才fsync。

binlog格式

binlog格式分为三种:

  • Statement格式:每一条会修改数据的sql都会记录在bin log
    • 优点:不需要记录每一行的变化,减少了bin log日志量,节约了IO,提高性能。
    • 缺点:比如sql中存在函数如now()等,依赖环境的函数,会导致主从同步、恢复数据不一致
  • Row:为了解决Statement缺点,记录具体哪一个分区中的、哪一个页中的、哪一行数据被修改了
    • 优点:清楚的记录下每一行数据修改的细节,不会出现某些特定情况下 的存储过程,或function无法被正确复制的问题。
    • 缺点:比如对ID<600的所有数据进行了修改操作,那么意味着很多数据发生变化,最终导致同步的log很多,那么磁盘IO、网络带宽开销会很高。
  • Mixed:混合模式,即Statment、Row的结合版

3. redo log 与binlog区别

  • redo log是InnoDB引擎特有的;binlog是Mysql的Server层实现的,所有引擎都可以使用
  • redo log是物理日志,记录的是“在某个数据页上做了什么修改”;binlog是逻辑日志,记录的是这个语句的原始逻辑,比如“给ID=2这一行的c字段加1”。
  • redo log是循环写的,空间固定会用完;binlog是可以追加写入的。“追加写”是指binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

4. 一条更新语句的执行流程

img

  1. 执行器调用引擎接口写入新数据
  2. 引擎把更新操作记录到 redo log中,此时redo log为prepare状态
  3. 执行器生成这个操作的binlog,并写入磁盘
  4. 执行器调用引擎的事务提交接口,引擎把redo log的状态改为commit

5. 两阶段提交

两阶段提交是指将redo log拆成两个步骤:prepare和commit。

为什么需要两阶段提交

我们先来看看如果不使用两阶段提交,即要么先写完redo log再写binlog,要么先写binlog在写redo log这两种方式会有什么问题。

  • 先写redo log,后写binlog:先写redo log后,binlog没写完宕机了。这时可以通过redo log来进行数据恢复。但是由于binlog没有写完就宕机了,等下次通过主从复制的时候,会发现binlog并没有数据,造成主从数据不一致。
  • 先写binlog再写redo log:如果写完binlog后,redo log 没写完就宕机,这个事务就无效了。但是binlog日志有该记录,在通过binlog进行同步后也会造成数据不一致。
分类: mysql
标签: MySQL(new)