当前位置:   article > 正文

MySQL 日志:undo log、redo log、binlog 有什么用?_binlog开启的意义

binlog开启的意义

一、bin log

1.作用

MySQL的bin log日志是用来记录MySQL中增删改时的记录日志。
当你的一条sql操作对数据库中的内容进行了更新,就会增加一条bin log日志。查询操作不会记录到bin log中。
bin log最大的用处就是进行主从复制,以及数据库的恢复。
主从复制:在Master端开启binlog,然后将binlog发送到各个Slave端,Slave端重放binlog从而达到主从数据一致。
数据恢复:通过使用mysqlbinlog工具来恢复数据。

2.刷盘时机

对于InnoDB存储引擎而言,只有在事务提交时才会记录biglog,此时记录还在内存中,那么biglog是什么时候刷到磁盘中的呢?mysql通过sync_binlog参数控制biglog的刷盘时机,取值范围是0-N:

1、sync_binlog=0 的时候,表示每次提交事务binlog不会马上写入到磁盘,而是先写到page cache,相对于磁盘写入来说写page cache要快得多,不过在Mysql 崩溃的时候会有丢失日志的风险。
2、sync_binlog=1 的时候,表示每次提交事务都会执行 fsync 写入到磁盘 ;
3、sync_binlog的值大于1 的时候,表示每次提交事务都 先写到page cach,只有等到积累了N个事务之后才fsync 写入到磁盘,同样在此设置下Mysql 崩溃的时候会有丢失N个事务日志的风险。

很显然三种模式下,sync_binlog=1 是强一致的选择,选择0或者N的情况下在极端情况下就会有丢失日志的风险,具体选择什么模式还是得看系统对于一致性的要求。

3.日志格式

logbin格式:

  • binlog_format=STATEMENT(默认):数据操作的时间,同步时不一致 每一条会修改数据的sql语句会记录到binlog中。优点是并不需要记录每一 条sql语句和每一行的 数据变化,减少了binlog日志量,节约IO,提高性能。缺点是在某些情况下会导致 master-slave 中的数据不一致( 如sleep()函数, last_insert_id(),以及user-defined functions(udf)等会 出 现 问题)
  • binlog_format=ROW:批量数据操作时,效率低 不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了,修改成什么样 了。而且不会出 现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的 问题。缺 点是会产生大量的日志,尤其是alter table的时候会让日志暴涨。
  • binlog_format=MIXED:是以上两种level的混合使用,有函数用ROW,没函数用STATEMENT,但是无法识别系统变量

二、redo log

1.为什么需要redo log

事务的四大特性里面有一个是持久性,具体来说就是只要事务提交成功,那么对数据库做的修改就被永久保存下来了,不可能因为任何原因再回到原来的状态。那么mysql是如何保证持久性的呢?最简单的做法是在每次事务提交的时候,将该事务涉及修改的数据页全部刷新到磁盘中

2.基本概念

redo log包括两部分:一个是内存中的日志缓冲(redo log buffer),另一个是磁盘上的日志文件(redo log file)。mysql每执行一条DML语句,先将记录写入redo log buffer,后续某个时间点再一次性将多个操作记录写到redo log file。这种先写日志,再写磁盘的技术就是MySQL里经常说到的WAL(Write-Ahead Logging)预写日志 技术。

3.作用

redo log是一种基于磁盘的数据结构,用来在MySQL宕机情况下将不完整的事务执行数据纠正,redo日志记录事务执行后的状态。

当事务开始后,redo log就开始产生,并且随着事务的执行不断写入redo log file中。redo log file中记录了xxx页做了xx修改的信息,我们都知道数据库的更新操作会在内存中先执行,最后刷入磁盘。

redo log就是为了恢复更新了内存但是由于宕机等原因没有刷入磁盘中的那部分数据。

3.刷盘时机

mysql支持三种将redo log buffer写入redo log file的时机,可以通过innodb_flush_log_at_trx_commit参数配置,各参数值含义如下:

参数值含义
取值0每秒(一秒钟内提交的事务)写入磁盘 每秒触发一次缓存日志回写磁盘操作,并调用操作系统fsync刷新IO缓存。
取值1有事务提交就立即刷盘 每次提交事务都立即调用操作系统fsync刷新IO缓存。
取值2每次事务提交 都写给操作系统 由系统接管什么时候写入磁盘 每次都把redo log写到系统的page cache中,由系统接管什么时候写入磁盘

innodb_flush_log_at_trx_commit = 1:实时写,实时刷
这种策略会在每次事务提交之前,每次都会将数据从redo log刷到磁盘中去,理论上只要磁盘不出问题,数据就不会丢失。

innodb_flush_log_at_trx_commit = 0:延迟写,延迟刷
每秒(一秒钟内提交的事务)写入磁盘 每秒触发一次缓存日志回写磁盘操作,并调用操作系统fsync刷新IO缓存。当系统崩溃,会丢失1秒钟的数据。

innodb_flush_log_at_trx_commit = 2:实时写,延迟刷
这种策略在事务提交之前会把redo log写到os cache中,但并不会实时地将redo log刷到磁盘,而是会每秒执行一次刷新磁盘操作。
这种情况下如果MySQL进程挂了,操作系统没挂的话,操作系统还是会将os cache刷到磁盘,数据不会丢失
但如果MySQL所在的服务器挂掉了,也就是操作系统都挂了,那么os cache也会被清空,数据还是会丢失。

三、undo log

1.作用

undo log主要用来回滚到某一个版本,是一种逻辑日志。

数据库事务四大特性中有一个是原子性,具体来说就是 原子性是指对数据库的一系列操作,要么全部成功,要么全部失败,不可能出现部分成功的情况。实际上,原子性底层就是通过undo log实现的。undo log主要记录了数据的逻辑变化
undo log记录的是修改之前的数据,比如:当delete一条记录时,undolog中会记录一条对应的insert记录,从而保证能恢复到数据修改之前。在执行事务回滚的时候,就可以通过undo log中的记录内容并以此进行回滚。
undo log还可以提供多版本并发控制下的读取(MVCC)。

四、Mysql的时机顺序

在这里插入图片描述
时机顺序:

  • 1 开启事务

  • 2 查询数据库中需要更新的字段,加载到内存中 形成数据脏页

  • 3 记录undo log到内存缓冲区(用于回滚和mvcc)并关联redo log -> 可刷盘

  • 4 记录 redo log到内存缓冲区 (用于失败重放)准备提交事务 -> 可刷盘

  • 5 修改内存中的脏页数据

  • 6 提交事务触发redolog刷盘

  • 7 undo log 和脏页 刷盘

  • 8 事务成功

五、redo log 与 binlog 的两阶段提交

redo log 的写入拆成了两个步骤:prepare 和 commit

  • prepare:redolog写入log buffer,并fsync持久化到磁盘,在redolog事务中记录2PC的XID,在redolog事务打上prepare标识

  • commit:binlog写入log buffer,并fsync持久化到磁盘,在binlog事务中记录2PC的XID,同时在redolog事务打上commit标识
    在这里插入图片描述

六、总结

1.redo log是InnoDB存储引擎的一种日志,主要作用是崩溃恢复,有三种刷盘策略,有innodb_flush_log_at_trx_commit 参数控制,推荐设置成2。
2.undo log是InnoDB存储引擎的一种日志,主要作用是回滚。
3.binlog是MySQL Server层的一种日志,主要作用是归档。

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/212755
推荐阅读
相关标签
  

闽ICP备14008679号