MySQL中的 redo log、undo log、bin log

参考博客:https://qimok.cn/584.html

重做日志(redo log)、回滚日志(undo log)、二进制日志(binlog),redo log 是物理日志,undo log 和 binlog 是逻辑日志,物理日志的恢复速度远快于逻辑日志,这时因为redo log利用了磁盘的顺序读写,mysql使用redo log提升了整体的io性能

redo log

参考博文:https://www.cnblogs.com/hapjin/archive/2019/09/28/11521506.html

概念

redo log在mysql中默认以ib_logfile0,ib_logfile1名称存在,可以手工修改参数,调节开启几组日志来服务于当前mysql数据库,mysql采用顺序,循环写方式,每开启一个事务时,会把一些相关信息记录事务日志中(记录对数据文件数据修改的物理位置或叫做偏移量);这个系列文件个数由参数innodb_log_files_in_group控制,若设置为4,则命名为ib_logfile0~3。这些文件的写入是顺序、循环写的,logfile0写完从logfile1继续,logfile3写完则logfile0继续。他们的作用是在系统崩溃重启时,作事务重做;在系统正常时,每次checkpoint时间点,会将之前写入事务应用到数据文件中。

innodb 事务日志包括 redo log 和 undo log,redo log是物理日志,undo log 是逻辑日志,用来提供回滚操作,redo log保证事务的持久性,undo log保证事务的原子性,两者可以统称为事务日志。而binloh与redo log不同点是:redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

生命周期:

事务开始之后就开始产生 redo log 日志了,在事务执行的过程中,当对应事务的脏页会被记录到redo log中,当 redo log file 大小已经达到某个域值快要"不可用"时(日志文件组轮流写文件),触发 checkpoint,及时将缓冲池的脏页刷新到磁盘,并同时将redo log buffer刷新到磁盘,redo log 的使命就完成了,它所占用的空间也就可以被覆盖了。

存储内容:

redo log 包括两部分:一是内存中的日志缓冲(redo log buffer),默认大小16MB,可经过参数innodb_log_buffer_size动态的调整它的大小,该部分日志是易失性的;二是磁盘上的重做日志文件(redo log file),该部分日志是持久的,redo log 存储的是物理格式的日志,记录的是物理数据页面的修改信息,即所有innodb表数据的变化,它是顺序写入 redo log file 中的。

持久化:

当事务要修改记录时,生成的日志都得先保存起来,但又不能在还没 commit 的时候就直接写到 redo log 文件里。所以,redo log buffer 就是一块内存,用以缓存事务执行过程中的数据,记录的物事务过程产生的修改,redo log buffer中同一个事务可能多次记录,最后一个提交的事务记录会覆盖所有未提交的事务记录。当向MySQL写数据时,先写日志缓冲的redo log,然后根据"某种方式"持久化到磁盘变成redo log file。如果发生宕机,则读取磁盘上的 redo log file 进行数据的恢复。从这个角度来说,MySQL 事务的持久性是通过 redo log 来实现的。

  • 问:redo log buffer中的数据丢失了怎么办?毕竟没有写到磁盘上,MySQL重启后100%没办法将其恢复出来。
  • 答:由于在MySQL的设定中,当你要Commit事务时,redo log才会持久化进磁盘,既然你没有commit,碰巧MySQL又宕机了。那让MySQL正常重启就行了啊,反正你没有commit,MySQL也也没有必要帮你恢复什么。

MySQL支持用户自定义在commit时如何将redo log buffer 中的日志刷 redo log file 中。这种控制通过变量 innodb_flush_log_at_trx_commit 的值来决定。该变量有3种值:0、1、2,默认为1。但注意,这个变量只是控制commit动作是否刷新redo log buffer到磁盘。redo log 可能存在的三种状态说起。这三种状态,对应的就是下图中的三个颜色块:

这三种状态分别是:

  1. 存在 redo log buffer 中,物理上是在 MySQL 进程内存中,就是图中的红色部分;
  2. 写到磁盘 (write),但是没有持久化(fsync),物理上是在文件系统的 page cache 里
    面,也就是图中的黄色部分;
  3. 持久化到磁盘,对应的是 hard disk,也就是图中的绿色部分。

innodb_flush_log_at_trx_commit 的值来决定以下行为:

  1. 设置为 0 的时候,表示每次事务提交时都只是把 redo log 留在 redo log buffer 中 ;
  2. 设置为 1 的时候,表示每次事务提交时都将 redo log 直接持久化到磁盘;
  3. 设置为 2 的时候,表示每次事务提交时都只是把 redo log 写到 page cache。InnoDB 有一个后台线程,每隔 1 秒,就会把 redo log buffer 中的日志,调用 write 写到文件系统的 page cache,然后调用 fsync 持久化到磁盘

redo日志的工作就是MySQL意外宕机重启时解析redo log中的事务后重放一遍,将Buffer Pool中的缓存页重作成脏页。后续再在合适的时机将该脏页刷入磁盘便可。redo log 值负责重做缓冲池的脏页数据,但是不参与数据库的落盘工作。数据库的落盘是将缓冲池中的脏页刷到硬盘,而这用到的就checkpoint技术
checkpoint分为两种:
第一种是sharp checkpoint,就是在数据库关闭时将缓冲池的脏页全部刷到硬盘
第二种是fuzzy checkpoint,fuzzy checkpoint又分为了好几种checkpoint,其中包括了master thread checkpoint,它会执行每秒和每十秒的任务按照一定的比例将脏页刷回磁盘中

重做日志缓冲池落盘方式:

1、MySQL master 线程周期性任务 每秒一次,将 redo log buffer 刷新到重作日志中(即使这个事务尚未提交)
2、MySQL master 线程周期性任务 每10秒一次,将 redo log buffer 刷新到重作日志中
3、每个事务提交时会将重做日志缓冲池中相应的数据刷到重作日志中
4、当redo log buffer size 剩余空间小于1/2时,将 redo log buffer 刷新到重作日志中
4、当 redo log file 大小已经达到某个域值快要"不可用"时(日志文件组轮流写文件),触发 async/sync flush checkpoint,及时将缓冲池的一些脏页刷新到磁盘,并同时将redo log buffer刷新到重作日志中。注意:最终落盘是由缓冲池刷到磁盘中,redo log file不参与落盘的工作。redo日志唯一的工作就是在崩溃恢复中,InnoDB 如果判断到一个数据页可能在崩溃恢复的时候丢失了更新,就会将它读到缓冲池,然后让 redo log 更新内存内容

脏页落盘

1、redo log满了
2、缓冲池不够用了,将对应淘汰的脏页写入硬盘
3、mysql在关闭时将脏页刷到磁盘
4、mysql在空闲时启动线程将部分脏页落盘

change buffer 和 redo log

当需要更新一个数据页时,如果数据页在内存中就直接更新,而如果这个数据页还没有在内存中的话,在不影响数据一致性的前提下,InooDB 会将这些更新操作缓存在 change buffer 中,这样就不需要从磁盘中读入这个数据页了。在下次查询需要访问这个数据页的时候,将数据页读入内存,然后执行 change buffer 中与这个页有关的操作。change buffer提升了数据库修改操作的性能,但是在数据写入change buffer时,也需要往redo log中进行写入

为什么要使用redo log持久化,直接写入磁盘不行吗?

1、redo log在宕机时可以用来恢复数据
2、redo log持久化效率高。数据页、索引页的刷盘是不容易的,因为底层是一棵B+树结构。而redo log是顺序写,相比数据页、索引页的直接刷盘要效率高很多

undo log

参考博文:https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html#auto_id_11

概念:

undo用来回滚行记录到某个版本。undo log是逻辑日志,根据每行记录进行记录。undo log有两个作用:提供回滚和多个行版本控制(MVCC)。

生命周期:

事务开始之前,将当前事务版本生成 undo log,undo log 也会产生 redo log 来保证 undo log 的可靠性。当事务提交之后,undo log 并不能立马被删除,而是放入待清理的链表,由 purge 线程判断是否有其它事务在使用 undo 段中表的上一个事务之前的版本信息,从而决定是否可以清理 undo log 的日志空间。

存储内容:

undo log 存储的是逻辑格式的日志,保存了事务发生之前的上一个版本的数据,可以用于回滚。当一个旧的事务需要读取数据时,为了能读取到老版本的数据,需要顺着 undo 链找到满足其可见性的记录。

存储位置:

默认情况下,undo 文件是保存在共享表空间的,也即 ibdatafile 文件中,当数据库中发生一些大的事务性操作的时候,要生成大量的 undo log 信息,这些信息全部保存在共享表空间中,因此共享表空间可能会变得很大,默认情况下,也就是 undo log 使用共享表空间的时候,被“撑大”的共享表空间是不会、也不能自动收缩的。因此,MySQL5.7 之后的“独立 undo 表空间”的配置就显得很有必要了。

binlog

概念:

MySQL 的二进制日志 binlog 可以说是 MySQL 最重要的日志,它记录了所有的 DDL 和 DML 语句(除了数据查询语句select、show等)。bin log 的主要目的是复制和恢复。binlog 用于主从复制中,从库利用主库上的 binlog 进行重播,实现主从同步。用于数据库的基于时间点、位点等的还原操作。binlog 的模式分三种:Statement、Row、Mixed。

binlog的执行过程:

事务执行过程中,先把日志写到 binlog cache,事务提交的时候,再把 binlog cache 写到 binlog 文件中。系统给 binlog cache 分配了一片内存,每个线程一个,参数 binlog_cache_size 用于控制单个线程内 binlog cache 所占内存的大小。如果超过了这个参数规定的大小,就要暂存到磁盘。事务提交的时候,执行器把 binlog cache 里的完整事务写入到 binlog 中,并清空 binlogcache
binlog存在write操作和fsync 操作。write操作是指的就是指把日志写入到文件系统的 page cache,并没有把数据持久化到磁盘,所以速度比较快。fsync 操作才是将数据持久化到磁盘的操作

write 和 fsync 的时机,是由参数 sync_binlog 控制的:

  1. sync_binlog=0 的时候,表示每次提交事务都只 write,不 fsync;
  2. sync_binlog=1 的时候,表示每次提交事务都会执行 fsync;
  3. sync_binlog=N(N>1) 的时候,表示每次提交事务都 write,但累积 N 个事务后才
    fsync。
    因此,在出现 IO 瓶颈的场景里,将 sync_binlog 设置成一个比较大的值,可以提升性能。
    在实际的业务场景中,考虑到丢失日志量的可控性,一般不建议将这个参数设成 0,比较常
    见的是将其设置为 100~1000 中的某个数值。

更新事务要写 binlog,而一旦 binlog 所在磁盘的空间占用率达到 100%,那么所有的更新语句和事务提交的 commit 语句就都会被堵住。但是,系统这时候还是可以正常读数据的

binlog的模式

Row 模式

记录的方式是行,即如果批量修改数据,记录的不是批量修改的SQL语句事件,而是每条记录被更改的SQL语句,因此,ROW模式的binlog日志文件会变得很“重”
优点:row 模式的binlog日志内容会非常清楚的记录下每一行数据被修改的细节。而且不会出现某些特定情况下存储过程或function,以及trigger的调用和触发器无法被正确复制的问题。
缺点:row 模式下,所有执行的语句当记录到日志中的时候,都以每行记录的修改来记录,这样可能会产生大量的日志内容,产生的binlog日志量是惊人的。

Statement 模式(默认)

记录每一条修改数据的SQL语句(批量修改时,记录的不是单条SQL语句,而是批量修改的SQL语句事件)。
优点:statement模式记录的更改的SQ语句事件,并非每条更改记录,所以大大减少了binlog日志量,节约磁盘IO,提高性能。
缺点:statement level下对一些特殊功能的复制效果不是很好,比如:函数、存储过程的复制。由于row level是基于每一行的变化来记录的,所以不会出现类似问题

Row 与Statement 的区别

Mixed 模式

实际上就是Statement与Row的结合。
在Mixed模式下,一般的语句修改使用statment格式保存binlog,如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。

如何选择binlog的模式

1、 如果生产中使用MySQL的特殊功能相对少(存储过程、触发器、函数)。选择默认的语句模式,Statement Level。
2、 如果生产中使用MySQL的特殊功能较多的,可以选择Mixed模式。
3、 如果生产中使用MySQL的特殊功能较多,又希望数据最大化一致,此时最好Row level模式;但是要注意,该模式的binlog非常“沉重”。

查看binlog模式

mysql> show global variables like "%binlog_format%";  
+---------------+-----------+  
| Variable_name | Value    |  
+---------------+-----------+  
| binlog_format | STATEMENT |  
+---------------+-----------+ 

配置binlog日志模式
vim my.cnf

log-bin = /data/3306/mysql-bin  
binlog_format="STATEMENT"  
#binlog_format="ROW"  
#binlog_format="MIXED" 
生命周期:

事务提交的时候,一次性将事务中的 sql 语句(一个事务可能对应多个 sql 语句)按照一定的格式记录到 binlog 中,这里与 redo log 很明显的差异就是 redo log 并不一定是在事务提交的时候才刷新到磁盘,而是在事务开始之后就开始逐步写入磁盘。binlog 的默认保存时间是由参数 expire_logs_days 配置的,对于非活动的日志文件,在生成时间超过 expire_logs_days 配置的天数之后,会被自动删除。

日志文件:

binlog日志包括两类文件:
1、二进制日志索引文件(文件名后缀为.index)用于记录所有有效的的二进制文件

2、二进制日志文件(文件名后缀为.00000*)记录数据库所有的DDL和DML语句事件
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容