MySQL事务详解(五):持久性的保障——redo

redo的场景

事务的持久性要求对于一个已经提交的事务,无论提交后发生什么情况,对数据库的更改都不能丢失。
但是在MySQL的InnoDB引擎中,无论对于数据的访问还是更新,都是在被称为buffer pool的缓冲池中进行了的。
事务提交,意味着数据被写入内存中缓冲池,还未落地到磁盘,
那么当服务器发生故障或者断电等异常后,会导致缓冲池中的数据丢失,违背了持久性。

那么是否可以在提交事务之前,将修改的数据直接刷新到磁盘来避免?
原则上上述简单粗暴的方法可以解决问题,但是会带来两个问题:

  • buffer pool的引入就是为了缓解引擎与磁盘之间的速度差,减少磁盘IO,提高处理速度。
    剔除掉缓冲池解决掉持久性问题,但是带来更大的性能问题,得不偿失。
  • InnoDB以页(默认16K)来管理存储空间,如果修改的页面的一个字节,也要刷新16K的数据,简直太浪费了。

针对上面的场景,提出了redo来解决:

  • 磁盘随机IO带来的速度问题,通过redo日志文件的顺序写入来解决。
  • redo日志只需要记录表空间ID、页号、偏移量以及需要更新的值等,这些数据所需空间很小

redo的组成

redo log buffer

类似于buffer pool的作用,redo也引入了名为redo log buffer的缓冲区,易失性。
通过参数innodb_log_buffer_size可以修改缓冲区的大小,默认16M。

缓冲区被划分为大小为512字节的redo log block,redo日志被顺序写入到这些block中。


redo log

redo日志是以文件组的形式管理的,默认是在MySQL数据目录下(使用show variables like "datadir"查看)。

目录下ib_logfile0和ib_logfile1即为redo日志文件,写入日志时,首先写入ib_logfile0,如果写满在写入ib_logfile1。
依此类推,当最后一个文件也写满时,再重新写入到ib_logfile0。在这里就会考虑到日志文件中的淘汰机制(checkpoint机制),保证不覆盖掉有用的日志。

可以使用MySQL参数来修改与redo log相关的配置:
innodb_log_file_size:每个redo日志文件的大小,默认48M;
innodb_log_group_home_dir:redo日志文件存储目录,默认数据目录;
innodb_log_files_in_group:redo日志文件数量,默认2。

redo流程

  • 磁盘中的数据经过page cache,读取到buffer pool中;
  • MySQL直接修改buffer pool中的数据,同时产出redo日志;
  • 事务提交时,先将redo日志写入到redo log buffer(WAL机制),是否写入到磁盘取决于刷盘策略的配置。
  • 后台线程将buffer pool中的脏页进行刷盘。

刷盘策略

redo log buffer的redo日志会根据不同情况和配置,刷新到磁盘上,实现真正的持久化。

  • log buffer的容量使用占比大约为一半时,就会触发刷盘
  • 后台线程,每秒一次刷盘(并不保证100%的‘每秒’)
  • 服务器正常关闭时,触发刷盘
  • 事务提交时,根据innodb-flush-log-at-trx-commit参数配置选择不同的刷盘策略:
    • innodb-flush-log-at-trx-commit=1(默认):
      当事务提交时,将log buffer中的数据写入到page cache,并调用fsync进行刷盘,效率最低。不会丢失数据。
    • innodb-flush-log-at-trx-commit=0
      当事务提交时,log buffer中的数据写入到page cache和刷盘都以后后台线程,效率最高。可能会丢失数据。
    • innodb-flush-log-at-trx-commit=2
      当事务提交时,只将log buffer中的数据写入到page cache,刷盘依靠后台线程每秒种刷盘一次。可能会丢失数据。

checkpoint机制

redo log的文件组是按顺序写入,当写完最后一个文件时,会再从第一个文件开始写入。
在这种情况下,如果redo log中日志对应的脏页还未刷到磁盘上,那么在系统崩溃时就会导致数据丢失。
因此,需要记录redo日志中已经刷到磁盘的记录,保证循环写不会覆盖掉有用的数据。这个功能就需要checkpoint机制来实现。
checkpoint_lsn:全局变量,系统中可以被覆盖的redo日志总量。

  1. 当脏页被刷到磁盘时,将当前系统中被最早修改的脏页对应的修改值复制给checkpoint_lsn。
  2. 将checkpoint_lsn与当前redo日志文件偏移量等信息写入到日志文件管理信息中。
    经过上两步,即为一次checkpoint。

崩溃恢复

  • 第一步,确认恢复的起点。
    • checkpoint机制保证checkpoint_lsn之前的脏页已全部刷盘,那么之后的数据就是我们要恢复的。
  • 第二步,确认恢复的终点。
    • 通过日志文件block的header中的信息可以知道每个block使用的字节空间,从而确定终点
  • 第三步,依次扫描日志,将对应的页恢复。
    • 通过hash表加快恢复速度:将表空间ID和页号取hash,这样同样表空间和页下的redo日志就可一次查询并恢复。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容