浅谈mysql事务原理

!!!!!!!!!
本人所有博客只针对自己学习做笔记使用,不保证准确性,如果需要深入探究其原理,建议参考官方文档或者源码
!!!!!!!!!

这里只说innodb,因为myisam和memory不支持事务,mysql还有一些其他的存储引擎这里也不是我们讨论的范畴。
大家去建一个表,你会发现的默认行格式是compact,5.7之后是DYNAMIC,这里所讲的dynamic是默认的行格式,其实他可以支持多种。dynamic和compact的主要区别其实就是页溢出的处理方式不同,dynamic会在第一个页储存更多的数据。加快了查询速度。
以5.6为例。如果innodb没有设置主键,会找唯一列作为主键,如果没有唯一列,会默认生成一个隐式行id作为主键,还有一个事物id trx_id,以及回滚指针 roll_pointer。事物id顾名思义,记录事物的,此外还有两个事物日志,redoundo。innodb支持事物其实就是行格式有这些隐藏列,myisam则没有。所以myisam不支持事物。
undo日志存的就是数据被修改之前的值。这里操作系统修改文件其实都是在内存中进行修改,然后再写回磁盘,数据发生修改的时候,数据是从磁盘读到数据库缓存池,在buffer pool中进行修改。那么这个时候如果数据库挂了,这个在内存的数据并没有持久化,那么会发生数据丢失,这个时候数据库重启会先读这个日志,持久化到磁盘,数据保持一致。
回到主题,当某一个操作发生修改后,此时会记录一个事物id,回滚指针指向undo存的日志。当发生回滚的时候,首先会执行redo,再执行undo,因为undo是这条数据最最最最开始之前的数据,先执行redo再执行undo不会破坏数据的一致性。
下面来讲如何控制事物,这里涉及几个概念,一个是MVCC机制,一个是事物版本控制链,还有个是readview,readview是记录当前活跃的事物id,在读已提交的情况下,readview所存活跃事物的id会随着事物的提交改变而改变。其实你去做一个读操作,其实要根据readview的活跃事物的id去过滤,一直找到底到它不在那个事物id,这就是你要读的数据。这就避免了 在读已提交的情况下不会读取未提交的数据,因为他的readview记录了未提交的事物id,这个时候他并不会去读取他。 可重复读也用到了readview,他的readview不随着事物关闭而会修改,也就是从始至终的都是那个readview所以他重复读的数据是一样的。
前面只说了读怎么去控制事物隔离级别,下面来说一说发生写的事物控制隔离级别。
这里涉及到了X锁,S锁,间隙锁。innodb支持行锁,myisam不支持行锁。
普通的select是不加锁的,不会加读锁。
lock in share mode 加读锁, for update加写锁
读已提交 不管你是索引查还是不是索引查,加写锁只对所查出的行进行加锁。
可重复读,就会加间隙锁。
其实mvcc机制加这个锁解决了大部分的幻读。

参考:https://blog.csdn.net/yu757371316/article/details/81081669
https://baijiahao.baidu.com/s?id=1629409989970483292&wfr=spider&for=pc

你可能感兴趣的:(事物,innodb,索引,mysql)