mysql 的ACID底层原理

很久没更新博客了,这次简单聊一下我自己对mysqlACID原理的理解

名词解释

  • A(atomicity):原子性

  • C(consistency) :一致性

  • I(isolation):隔离性

  • D(durability):持久性

ACID的实现原理

  • A(atomicity):使用undo log日志实现,原子性要么都成功,要么都失败,会记录每一次的操作记录的undo log日志,后面发生异常时在从undo log把事物回滚掉
  • C(consistency):一致性是根据原子性+个理性+持久性组合下完成的
  • I(isolation):锁
  • D(durability):redo log日志实现

mysql数据更新的流程

  • 获取到原始数据,首先在执行引擎汇总查找数据,如果是在内存中则直接返回,否则从磁盘汇总load到内存,然后返回
  • 更新数据,从执行引擎获取到数据后对其进行修改,然后调用引擎接口把修改后的数据重新写入到引擎中
  • 重新写入数据,首先把上面的修改后的数据写入到内存,然后写入redo log中这里是二阶段中的一阶段prepare,操作完成后通知执行器完成
  • 写入bin log日志,这里还是二阶段中的一阶段的另一个分支写binlog日志
  • 提交事物,最后执行器调用引擎的提交事物接口,这里也就是二阶段中的二阶段,最后把redo log改为commit状态,最终完成

redo log写入流程(INNODB)

  • 写redo log日志,更新到内存
  • 用户态innodb引擎的log buffer
  • 内核态os buffer
  • 异写调研内核态接口fsync写到磁盘中,也就是redo log磁盘文件
  • 当有一条事物操作数据时,在innodb数据库引擎中会先把数据写到relog中,更新到内存,具体是怎么做的呢,这里分为用户态和内核态,我们的内存操作都是在用户态执行,然后磁盘是在内核态中,首先这里面写的过程分为先在innodb引擎中写relog,然后在写log buffer,内核态的os buffer,最后从os buffer中每秒的调用fasyc异写入到磁盘。
  • 最后写到磁盘的有三种方式,通过参数配置,innodb_flush_log_at_trx_commit,可以使用命令查询这个设置的是什么 
    show variables like 'innodb_flush_log_at_trx_commit';
  1. 先写到log buffer-》os buffer-》每秒调用fsync写入磁盘(性能最高,不安全)-〉参数值:0
  2. 直接写到os-buffer-》每秒调用fsync写入磁盘(性能较高,较安全,推荐)-〉参数值:1
  3. 直接写到os-buffer并且调用fsync写入磁盘(性能低,很安全)-〉参数值:2

附上一张binlog写到磁盘的图

write操作是把日志文件的临时文件先写到内核开辟的一个内存空间中

fsync才是实际的把binlog file在内核的空间中异写到磁盘中

write和fsync都有一个机制控制是怎么样的写,由mysql参数的sync_binlog控制

sync_binlog参数,有3种,0,1,N

0:只是write,不进行fsync(但是不代表不写磁盘的意思,而是有后台线程自己控制时间写到磁盘)

1:每次都进行fsync操作,直接就写到磁盘了,这样做的安全性最高的,不会存在数据丢失的情况,推荐此种,但是如果出现master-slave出现了主从同步延迟的则可以权衡考虑是否调整

N:不是每次进行fsync,而是在write到binlog file中积累了N次事物后在进行fsync异写

 

有时间的话,下一期会讲一下mysql中的MVCC的实现原理

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值