Mysql 事务的一点总结

事务


事务的概念以及用法这边就不赘述了,事务的ACID特性也不多说了,我们来聊一聊事务的隔离和多版本并发的一点知识


隔离级别


1.Read Uncommited (未提交读)

事务中的修改,即使没有提交,对其他事务也是可见的。事务可以读到未提交的数据,也就是脏读


2.Read Commited (提交读)

一个事务在开始的时候,只能看见已经提交的事务所做的修改。意思也就是,一个事务在正式提交前,所做的修改对其他事务都是不可见的。他所造成的问题是,当执行多个同样的查询时候,可能得到不一样的结果。


3.Repeatable Read (可重复读)

该级别保证了在同一个事务中多次读取同样的记录结果是一致的。但是他无法解决幻读的问题。幻读指当某个事务在读取某个范围内的记录时,另一个事务又插入新的记录,当之前的事务再次读取时会产生幻行。 可重复读是Mysql的默认隔离级别


4.Serizlizable(可串行化)

串行化会对每一行数据加锁,避免了以上说的幻读,但是这是极大消耗mysql性能的一个操作。



多版本并发控制(MVCC)

可重复读的实现是基于MVCC来实现数据一致性的

MVCC是行级锁的一种变种,他通过保存数据在某个时间点的快照来实现的。在我们常用的innoDB中,是通过在每行记录后面保存两个影藏的列来实现的,一个列保存了行的创建时间,一个保存了行的过期时间,他存储的并不是实际时间,而是系统的版本号,这样无论是查询,插入,修改,删除,都需要根据这个版本号来。

而怎么实现所谓的多版本,我们深入MySQL实现,发现他是基于日志来做的,两个关键的日志,redoLog,binLog


redolog binlog


binlog


binlog,是mysql服务层产生的日志,常用来进行数据恢复、数据库复制,常见的mysql主从架构,就是采用slave同步master的binlog实现的, 另外通过解析binlog能够实现mysql到其他数据源的数据复制。


redolog


redolog记录了数据操作在物理层面的修改,mysql中使用了大量缓存,缓存存在于内存中,修改操作时会直接修改内存,而不是立刻修改磁盘,当内存和磁盘的数据不一致时,称内存中的数据为脏页(dirty page)。为了保证数据的安全性,事务进行中时会不断的产生redolog,在事务提交时进行一次flush操作,保存到磁盘中, redolog是按照顺序写入的,磁盘的顺序读写的速度远大于随机读写。当数据库或主机失效重启时,会根据redo log进行数据的恢复,如果redo log中有事务提交,则进行事务提交修改数据。这样实现了事务的原子性、一致性和持久性。


通过以下这张图我们看他们之间是怎么工作的





上图是事务的两阶段提交过程

  1. 事务启动,记录到binlog中,innodb将事务状态修改为准备阶段,并将redoLog刷到磁盘中
  2. 如果所有的修改都成功,将sql语句写入binlog,此时这个事务处于等待提交状态
  3. 最后调用commit完成事务的提交



参考文献 《高性能MySQL》



暂无评论