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


http://www.taodudu.cc/news/show-1775508.html

相关文章:

  • Protocol Buffer 序列化原理大揭秘
  • proto3与proto2的区别
  • C++17 Any类
  • C++ 多态与虚函数面试题
  • STL 容器迭代器失效总结(超级详细)
  • C++ 非类型的模板参数
  • csdn 博客添加目录方法
  • C 标准库中输出到字符串、到文件的相关函数
  • 台式机每月性能测试
  • C++11 enable_shared_from_this
  • VS中的多线程(/MT)、多线程调试(/MTd)、多线程DLL(/MD)、多线程调试DLL(/MDd)的区别
  • boost::asio 网络传输错误码的一些实验结果(recv error_code)
  • protoc 生成C++代码
  • Protobuf C++类中成员函数GetCachedSize()与ByteSize()的区别
  • C++ 如何释放std::function中绑定的对象
  • Boost.Asio C++网络编程
  • boost noncopyable实现禁止类拷贝
  • Boost Asio socket 非阻塞/缓冲区大小等属性设置
  • Boost Asio 使用技巧
  • Boost Asio Work类
  • Boost Asio官方Examples
  • Boost Asio run() run_one() poll() poll_one()的区别
  • Boost Asio dispatch()与post()的区别
  • C++11 std::ref()
  • Boost Asio Examples(整理)
  • 最好的5个C++ 网站
  • 面试之Boost
  • libevent源码深度剖析-张亮
  • libevent参考手册 系列文章
  • libevent源码分析系列

MySQL的Binlog与Redolog相关推荐

  1. MySQL三大日志——binlog、redoLog、undoLog详解

    目录跳转电梯 1. redoLog 1.1 为什么需要redo log 1.2 redo log基本概念 1.3 redo log记录形式 2. binlog 2.1 binlog基本概念 2.2 b ...

  2. MySQL的Binlog原理

    什么是二进制日志(binlog) binlog是记录所有数据库表结构变更(例如CREATE.ALTER TABLE-)以及表数据修改(INSERT.UPDATE.DELETE-)的二进制日志. bin ...

  3. mysql的binlog太多太大占用了空间的解决办法

    现象:网站访问越来越慢,最后无法访问了,经过检查发现磁盘满了 分析过程及解决方案:通常出现这种问题都应该登录服务器检查磁盘.内存和进程使用的情况,通过top.df –h和free –m来检查,发现磁盘 ...

  4. mysql开启binlog

    mysql开启binlog,至于为什么要开启binlog,可以google下. ## 设置server_id,一般设置为IP server_id=117## 复制过滤:需要备份的数据库名,多个库以逗号 ...

  5. MySQL的binlog数据如何查看

    binlog介绍 binlog,即二进制日志,它记录了数据库上的所有改变. 改变数据库的SQL语句执行结束时,将在binlog的末尾写入一条记录,同时通知语句解析器,语句执行完毕. binlog格式 ...

  6. 阿里巴巴开源项目: 基于mysql数据库binlog的增量订阅消费

    背景 早期,阿里巴巴B2B公司因为存在杭州和美国双机房部署,存在跨机房同步的业务需求.不过早期的数据库同步业务,主要是基于trigger的方式获取增量变更,不过从2010年开始,阿里系公司开始逐步的尝 ...

  7. Mysql使用binlog恢复数据解决误操作问题的两种方法

    Mysql使用binlog恢复数据解决误操作问题的两种方法 参考文章: (1)Mysql使用binlog恢复数据解决误操作问题的两种方法 (2)https://www.cnblogs.com/Data ...

  8. MySQL的binlog日志

    一:MySQL的4种不同日志 1:error log,错误日志. 记录了系统启动,运行以及停止过程中遇到的一些问题 2:general log,普通日志 记录了MySQL执行的所有语句以及语句开始执行 ...

  9. mysql同步binlog_利用MySQL的Binlog实现数据同步与订阅(下)

    利用MySQL的Binlog实现数据同步与订阅(下)​blog.yuanpei.me 终于到这个系列的最后一篇,在前两篇博客中,我们分别了介绍了Binlog的概念和事件总线(EventBus)的实现, ...

  10. 初探 MySQL 的 Binlog

    花瓣網的搜索架構需要重構,尤其是在索引建立或者更新層面. 目前的一個架構導致的結果就是時間越久,數據本體與搜索引擎索引中的數據越不同步,相差甚大. 新的一個架構打算從 MySQL 的 Binlog 中 ...

最新文章

  1. 怎么理解linux的平均负载及平均负载高后的排查工具
  2. chrome上很棒的爬虫插件,至少爬取博客够用了
  3. [JSOI 2011]分特产
  4. c语言头文件格式图片_c语言中的.h头文件的格式
  5. ctfshow-网络迷踪-新手上路 ( 使用百度搜图收集景点信息)
  6. [转载] ml-8-1-聚类( ( Clustering) )
  7. windows下安装使用WGET
  8. 杰奇1.7--关关采集器使用教程
  9. 最小可分辨温差四杆靶空间频率选择
  10. 关于阿里巴巴编程规范
  11. 国际短信平台怎么找?
  12. JS控制台报错Uncaught TypeError Cannot read properties of null (reading ‘appendChild‘);的解决方法
  13. 【Android 进程保活】应用进程拉活 ( 应用进程拉活简介 | 广播拉活 | 显示广播与隐式广播 | 全家桶拉活 )
  14. ecm、ppp、ndis 拨号
  15. Java基础知识入门级!
  16. Richard Feynman, 挑战者号, 软件工程
  17. C++ 标准库函数与宏定义的名字冲突
  18. 不可思议,作家王小波居然是国内第一代程序员!
  19. js jquery 实现 排班,轮班,日历,日程。使用fullcalendar 插件
  20. 基于GBT28181:SIP协议组件开发-----------第三篇SIP注册流程分析实现

热门文章

  1. 电子邮件.NET控件MailBee.NET Objects v11.1发布丨附下载
  2. 404错误、500错误、异常错误提示页面的拦截和自定义
  3. 百度霸屏技术的源码发布
  4. Atitit. 二进制数据ascii表示法,与base64编码解码api 设计标准化总结java php c#.net...
  5. 15K薪资轻松到手,要低调~
  6. 在centos上安装nginx
  7. 配置 LDAP 服务器
  8. 2010年11月51CTO壁纸点评活动获奖名单【已结束】
  9. 7.这就是搜索引擎:核心技术详解 --- 云存储与云计算
  10. mc服务器天赋系统,[娱乐|经济]GokiStats——全新的天赋系统插件MySQL可用[全版本]...