日志系列二之二进制日志原理篇

一、写入机制

binlog的写入时机也非常简单,事务执行过程中,先把日志写到 binlog cache ,事务提交的时候,再把binlog cache写到binlog文件中。因为一个事务的binlog不能被拆开,无论这个事务多大,也要确保一次性写入,所以系统会给每个线程分配一个块内存作为binlog cache。

可以通过binlog_cache_size参数控制单个线程binlog cache大小,如果存储内容超过了这个参数,如果存储内容超过这个参数,会存储到磁盘中。

write和fsync的时机,可以由参数 sync_binlog 控制,默认是 0 。

1、sync_binlog为0时

为0的时候,表示每次提交事务都只write,由系统自行判断什么时候执行fsync。虽然性能得到提升,但是机器宕机,page cache里面的binglog 会丢失

2、sync_binlog为1时

表示每次提交事务都会执行fsync,就如同redo log 刷盘流程一样。

3、sync_binlog为n(n>1)时

表示每次提交事务都write,但累积N个事务后才fsync

在出现IO瓶颈的场景里,将sync_binlog设置成一个比较大的值,可以提升性能。同样的,如果机器宕机,会丢失最近N个事务的binlog日志

二、binlog与redolog对比

1、redo log

(1)它是物理日志 ,记录内容是“在某个数据页上做了什么修改”,属于InnoDB 存储引擎层产生的

(2)事务执行中写入

(3)让InnoDB存储引擎拥有了崩溃恢复能力

2、binlog

(1)是逻辑日志 ,记录内容是语句的原始逻辑,属于MySQL Server 层

(2)事务提交时写入

(3)保证mysql集群架构的数据一致性

三、两阶段提交

在执行更新语句过程,会记录redo log与binlog两块日志,以基本的事务为单位,redo log在事务执行过程中可以不断写入,而binlog只有在提交事务时才写入,所以redo log与binlog的 写入时机不一样

1、redo log与binlog两份日志之间的逻辑不一致,带来的问题

以update语句为例,假设id=2的记录,字段c为0,把字段c更新为1,sql为

update T set c=1 where id=2

假设执行过程中写完redo log日志后,binlog日志写期间发生的异常。

 由于binlog没写完就异常,这时候binlog里面没有对应的修改记录。后面用binlog日志恢复数据,就会少这一次的更新,恢复出来的c为0,而master使用redo log日志恢复,此时c为1,最终数据不一致。

 2、两阶段提交

为了解决两份日志之间的逻辑一致问题,InnoDB存储引擎使用两阶段提交方案。

(1)使用两阶段提交后,写入binlog时发生异常也不会有影响

 (2)redo log设置commit阶段发生异常

并不会回滚事务,它会执行上图框住的逻辑,虽然redo log是处于prepare阶段,但是能通过事务id找到对应的binlog日志,所以MySQL认为是完整的,就会提交事务恢复数据 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值