mysql 原理 ~ 二阶段提交协议通说

一 简介: 今天是第二篇,讲解的是mysql的事务日志

二 具体

   1 WAL技术(先写日志,再写磁盘)

   2 binlog redolog 二阶段提交协议
     目的 保持 redo log和binlog之间的逻辑一致,这样采用binlog方式就能恢复数据
     第一阶段先写redo log,处于prepare状态
    1 redo log记录的是物理日志,数据页的具体修改操作
    2 控制参数与原理

    原理系列 1 mysql写日志过程 log_buff ---mysql写 (write)---> log_file---OS刷新 (flush)---> disk

                   2 mysql内部进行主动sync的函数是 log_buffer_flush_to_disk

    控制参数 
    innodb_flush_log_at_trx_commit=1 控制redo log缓存的刷新方式
     0:log buffer将每秒一次地写入log file中,并且log file的flush(刷到磁盘)操作同时进行。该模式下在事务提交的时候,不会主动触发写入磁盘的操作。
           当mysql崩溃时可能会丢失上1S事务 此时不调用 log_buffer_flush_to_disk
    1:每次事务提交时MySQL都会把log buffer的数据写入log file,并且flush(刷到磁盘)中去,该模式为系统默认。
          当mysql崩溃或者系统崩溃时,最多丢失1个事务 此时调用 log_buffer_flush_to_disk,不依赖linux本身的 sync函数
    2:每次事务提交时MySQL都会把log buffer的数据写入log file,但是flush(刷到磁盘)操作并不会同时进行。该模式下,MySQL会每秒执行一次 flush(刷到磁盘)操作。
         当linux系统崩溃时,上1S事务才可能丢失 此时不调用log_buffer_flush_to_disk

    总结 我们可以发现,从事务提交是否触发相应write and sync 角度来进行控制redo log到磁盘过程的控制
   3 顺序写入
   4 redo log根据checkpoint来控制是否可以覆盖,checkpoint之前的区域都是可以覆盖的,之后的不行,必须得应用完成才能覆盖

   5 实现了组提交技术

   6 redo记录的是数据页改变,那么如何保证数据页的完整性呢,要依靠数据库的双写特性,值的主要的是,如果硬盘本身支持16K原子写,就可以关闭双写服务
   第二阶段再写binlog,处于commit状态
  1 binlog记录的是逻辑日志,row格式下具体记录(DML影响的具体数据,DDL具体的执行语句)
  2 控制参数
  sycn_log=1 控制binlog的刷新方式,1值代表当有1个事务提交时,刷新缓存到文件中
  3 顺序写入

  4 实现了组提交技术
三 总结
1 只有当两阶段完成后才代表整个事务完成,当发生故障时,两阶段完成的事务会重做,没有两阶段完成的事务会回滚
2 innodb_flush_log_at_trx_commit and sycn_log 对mysql数据库tps的性能影响非常大,重要环节推荐设置双1

四 二阶段提交协议与 故障恢复

   1. 准备阶段(Storage Engine(InnoDB) Transaction Prepare Phase)

      此时SQL已经成功执行,并生成xid信息及redo和undo的内存日志。然后调用prepare方法完成第一阶段,papare方法实际上什么也没做,将事务状态设为TRX_PREPARED,并将redo log刷磁盘。

   2. 提交阶段(Storage Engine(InnoDB)Commit Phase)

      2.1 记录协调者日志,即Binlog日志。

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

     2.2 告诉引擎做commit。

      最后,调用引擎的commit完成事务的提交。会清除undo信息,将 xid写入redo日志中 将事务设为TRX_NOT_STARTED状态。

  3 MySQL内部两阶段提交需要开启innodb_support_xa=true,默认开启。这个参数就是支持分布式事务两段式事务提交。redo和binlog数据一致性就是靠这个两段式提交来完成的,如果关闭会造成事务数据的丢失,XID正是由于XA事物生成

当崩溃恢复时
1 如果redo log里的事务是完整的(prepare+commit),则进行提交
2 如果redo log里的事务是不完整的(只有prepare状态),通过获取redo的prepare事务列表和最后一个binlog文件的xid事务列表进行结合
   1 binlog事务完整 进行事务提交
   2 binlog不完整 进行回滚
备注
1 binlog通过checksum和XID进行判断事务是否完整
2 redo log和binlog之间是通过事务XID进行关联的

目的 1 保证主从数据库的一致性,当主库binlog落盘时,才传递到从库上

转载于:https://www.cnblogs.com/danhuangpai/p/9969032.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值