MySQL的Binlog与Redolog

MySQL逻辑架构大致可以分为两层:

  • 服务层:MySQL的核心服务功能,包括查询语句解析,词法语法分析,优化,缓存以及内置函数(日期,时间,数学,加密等),跨存储引擎的功能:存储过程,触发器,视图等。
  • 存储引擎:负责MySQL中数据的存储和提取。

我们知道在MySQL中,server层的日志,成为binlog(归档日志),主要用来做主从复置和恢复时使用的。redo log是InnoDB引擎的日志,来实现crash-safe能力。

为什么会有两份日志呢?
因为MySQL早期版本中没有InnoDB引擎,MySQL自带的引擎是MyISAM,MyISAM是没有crash-safe能力的,直到将InnoDB以插件的形式引入,InnoDB使用Redo Log来实现crash-safe能力。

binlog和Redo Log主要有以下三点不同:

  1. Redo Log是InnoDB引擎特有的;binlog是MySQL的server层实现的,不管哪种引擎,都会有binlog。
  2. Redo Log是物理日志,记录数据是怎么变化的;binlog是逻辑日志,记录的是语句的逻辑操作。
  3. Redo Log是循环写的,空间固定会用完;binlog是追加写入的,文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

InnoDB如何保证crash-safe,MySQL服务器宕机重启后:

  • 所有已经提交的事务的数据仍然存在
  • 所有没有提交的事务的数据自动回滚

InnoDB通过Redo Log和Undo Log保证以上两点。在每个事务提交的时候,将Redo Log写入硬件存储,这样做会牺牲一些性能,但是可靠性最好。为了平衡两者,InnoDB提供了一个innodb_flush_log_at_trx_commit系统变量,用户可以根据应用的需求自行调整。通过redo日志将所有已经提交的事务恢复,已经prepare但是没有commit的事务将会应用undo log做rollback。
在更新数据时,先写日志,再写磁盘,就是所谓的WAL技术(Write-Ahead Logging)。InnoDB引擎先把记录写到Redo Log中,再更新内存,这个时候认为更新就完成了。InnoDB引擎会在适当的时候,将这个记录更新到磁盘里面,一般会在系统比较空闲的时候。

为保证数据的一致性,就必须保证binlog和Redo Log的一致性,MySQL引入两阶段提交(two phase commit or 2pc),来保证数据一致性。具体做法是将Redo log的写入拆成了两个步骤:prepare和commit,这就是所谓的"两阶段提交”。

在主从复制场景下,MySQL内部会自动将普通事务当作一个XA事务(内部分布式事务)来处理:

  • 自动为每个事务分配一个唯一的ID(XID)
  • COMMIT会被自动的分成Prepare和Commit两个阶段
  • Binlog会被当做事务协调者(Transaction Coordinator),Binlog Event会被当做协调者日志

Binlog在2PC中充当了事务的协调者(Transaction Coordinator)。由Binlog来通知InnoDB引擎来执行prepare,commit或者rollback的步骤。事务提交的整个过程如下:

mysql_redo_bin_log.png

分析此图,当事务提交时(执行commit语句),分别对应以下几个阶段:

  1. 协调者准备阶段(Prepare Phase)
    此时SQL已经成功执行了,已经产生了语句的redo和undo内存日志,已经进入了事务commit步骤。然后告诉引擎做Prepare完成第一阶段,Prepare阶段就是写Prepare Log(Prepare Log也是Redo Log),将事务状态设为TRX_PREPARED,写Prepare XID(事务ID号)到Redo Log。写XID到Redo Log的时候会一并把Redo Log刷新到磁盘,这个时候Redo Log的日志量大小取决于执行SQL语句时产生的Redo是否被刷盘,这个刷盘是随机的,后台Master线程每秒钟都会刷新一次。

  2. 协调者提交阶段(Commit Phase)

2.1 记录协调者日志,即Binlog日志
如果事务涉及的所有存储引擎的Prepare都执行成功,则调用TC_LOG_BINLOG::log_xid方法将SQL语句写到Binlog(write()将binary log内存日志数据写入文件系统缓存,fsync()将binary log文件系统缓存日志数据永久写入磁盘),同时也会把XID写入到Binlog。此时,事务已经铁定要提交了。否则,调用ha_rollback_trans方法回滚事务,而SQL语句实际上也不会写到binlog。

2.2 告诉引擎做Commit
最后,调用引擎的Commit完成事务的提交。并且会对事务的undo log从prepare状态设置为提交状态(可清理状态),刷新Commit Log到Redo Log,释放锁,释放mvcc相关的read view等等;将事务设为TRX_NOT_STARTED状态。

记录Binlog是在InnoDB引擎Prepare(即Redo Log写入磁盘)之后,这点至关重要。另外需要注意的一点就是,SQL语句产生的Redo日志会一直刷新到磁盘(master thread每秒fsync redo log),而Binlog是事务commit时才刷新到磁盘,如果binlog太大则commit时会慢。

由上面的二阶段提交流程可以看出,通过两阶段提交方式保证了无论在任何情况下,事务要么同时存在于存储引擎和binlog中,要么两个里面都不存在,可以保证事务的binlog和redo log顺序一致性。一旦阶段2中持久化Binlog完成,就确保了事务的提交。此外需要注意的是,每个阶段都需要进行一次fsync操作才能保证上下两层数据的一致性。阶段1的fsync由参数innodb_flush_log_at_trx_commit=1控制,阶段2的fsync由参数sync_binlog=1控制,俗称“双1”,是保证crash-safe的根本。

参考:
https://en.wikipedia.org/wiki/Two-phase_commit_protocol

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

推荐阅读更多精彩内容