问:事务的隔离级别是如何实现的

MySQL的事务实现原理?(允许你重新组织语言,好好说)

WA: 知道MySQL的事务吧?

HAHA:指的是MySQL中不可拆分的业务单元,具有ACID的属性(接着会问我隔离级别和解决的问题)

WA: 你能说一下是怎么实现的吗?

HAHA:哈哈哈哈哈哈(啥???)不同特性实现的方式各有不同

  • A原子性,一组操作要么全部成功,要么全部失败。D持久性:事务一旦提交,那么数据一定会被持久化到磁盘
    • undo log: MySQL使用undo log实现操作回滚。事务开启后执行的命令都会有一条对应反向的逻辑日志计入undo日志文件中(譬如insert 就会有一条delete)。undo log的持久化会被记录在redo log中(利用redo log 速度快的特性)。一旦发生错误或者回滚的时候,利用undo就可以操作回去
    • 解释一下这个问题的由来?事务都提交了,难道还不会被持久化(数据的修改都是先在内存中操作,然后落盘的,持久性是解决内存操作成功,还没来及落盘的问题)
    • redo log: 事务在提交前对数据的修改会先写到redo log 中。redo log 也有缓冲区,redo log的内存缓冲区大小和磁盘扇区的大小512字节一致,不会出现掉电易失的情况。另外redo log记录的是物理变化,体积很小,且redo log 写磁盘是顺序IO,极快~丝滑
    • redo log 和binlog区别:一个是用于做持久化,另一个用作数据恢复和复制

WA: 那还有一致性和隔离性呢?

HAHA:C一致性和I隔离性可以放在一起说,隔离级别的选择就是一致性和隔离性的权衡

  • 实现多个事务之间的隔离。一种是锁,另一种是mvcc机制。可以认为后者是对前者的一种优化,不需要阻塞事务
  • 当前读 使用的是锁机制
    • 触发:数据的修改操作(insert update delete)和查询时显示加锁 select(查询条件后加上 lock in share mode & for update)
    • 数据会被锁住,等待一个事务处理完毕
  • 快照读 使用的是mvcc机制,就是多版本并发控制
    • 触发: 普通查询select 。 在RR RC两种级别下使用。其他两种不需要
    • 实现原理
      • 简单来说就是,MySQL维护了一个记录活跃事务id的列表readview,通过比较当前事务id和readview中其他事务的id大小来决定自己读取的数据是哪个版本的undo log记录
      • RR级别下利用该机制避免了幻读,当前事务通过对比readview中的事务id查找到自己记录未被修改前的数据
        • 如果当前事务id最大,那就直接读最新数据
        • 如果当前事务id最小,就读取undo log的记录链,找到离自己最近的undo log记录  
      • RC级别下每次都会读取数据的最新记录
    • 该机制使得mysql在RR级别下解决了幻读问题    

部分内容为自己猜想,如有错误,欢迎指正!

参考文章

  • MySql-Undo及Redo详解 https://blog.csdn.net/aaa821/article/details/80645242
  • MySql MVCC 多版本并发控制 https://www.cnblogs.com/paulwang92115/p/12189487.html

猜你喜欢

转载自www.cnblogs.com/nightOfStreet/p/12977291.html