MySQL事务

  • Post author:
  • Post category:mysql


  • 事务的四个特性
  • 事务会产生的问题
  • 脏读、不可重复读、幻读如何去解决
  • 四个特性通过什么去保证呢

其中隔离性通过MySQL的锁和MVCC保证,

锁可以保证 写写事务,但是锁就意为着阻塞。

MVCC保证读读事务,还是读写事务,MVCC可以保证读写同步,通过MVCC可以实现提交读和可重复读两种隔离级别。

而原子性、一致性和持久性通过redo和undo来保证。



事务的四个特性

原子性:事务中的语句要么全部执行,要么全部不执行。

一致性:只一种一致性状态,例如100块钱怎么转都是100块,不会变多也不会变少

隔离性:事务之间互不影响

持久性:事务的影响是持久的。



事务会产生的问题

脏读:事务A读取了事务B回滚的事务。

不可重复读:事务A两次读取的数据不同。

幻读:事务A第二次读取的数据增多或减少。

幻读可以通过序列化或者MVCC解决,但是MVCC不完全保证不会出现幻读,如下情况:
事务A                  | 事务B
select ...             
                        insert ...
update新增的那条数据
select ...



隔离级别

隔离级别 可能产生问题 原理
未提交读 脏读、不可重复读、幻读
提交读 不可重复读、幻读 MVCC
可重复读 幻读 MVCC
序列化



Redo日志



为什么要有redo日志

我们都知道,为了更快的从mysql中读数据,mysql大叔为mysql设置了buffer pool这个一个缓冲在内存中,这个buffer pool有两个好处

  1. 它放在内存中读的快
  2. 改buffer pool中的缓冲页就行了,利用率高,由buffer pool统一来把数据存到磁盘中。

我们来讲讲buffer pool不足的地方: buffer pool中的缓冲页刷到磁盘中是随机IO,不是顺序IO,比较慢。为了保证持久性,mysql数据不丢失,mysql大叔创造了redo log,它顺序IO比较快,空间占用少。



redo日志的组成

  • redo log buffer
  • redo log file



redo log buffer

也是采用页的存储方式。log file和buffer的内容大致相同,都是指明哪个表空间,哪个数据页,哪个行修改了什么数据,是物理日志。

redo log block为512字节,redo log buffer16M

redo log file有两个,可复写,通过checkpoint保证



redo log的写入流程

事务执行

写入redo log buffer

写入buffer pool

事务提交

同步到redo log file

事务结束



redo log buffer的写入方式

0:每秒由子线程提交给操作系统同步

1:commit后由主线程同步(默认)

2:commit后交给操作系统的缓冲区,由操作系统同步

1的效率最低但是最安全,鱼和熊掌不可兼得。2只要操作系统不宕机还是可以同步的。



Undo日志

undo可以保证事务的原子性,及失败的事务可以回滚,不会有部分提交的情况。

undo可以分为insert undo和update undo,为啥这么分呢?insert的内容提交以后,insert undo就没啥用了,可以直接删除。而update undo的版本链需要给MVCC支持,所以不能直接删除,所以只是打了个delete_mark,之后由purge线程统一操作。

undo日志是逻辑日志,记录的是数据库变化内容。



MVCC

在这里插入图片描述



版权声明:本文为qq_41606730原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。