mysql数据库隔离级别

mysql架构

MySQL架构
MySQL从概念上可以分为四层,顶层是接入层,不同语言的客户端通过mysql的协议与mysql服务器进行连接通信,接入层进行权限验证、连接池管理、线程管理等。下面是mysql服务层,包括sql解析器、sql优化器、数据缓冲、缓存等。再下面是mysql中的存储引擎层,mysql中存储引擎是基于表的。最后是系统文件层,保存数据、索引、日志等。
mysql数据库隔离级别

事务的四个属性

ACID,它们分别代表了Atomicity(原子性), Consistency(一致性), Isolation(隔离性), Durability(持久性)
原子性表示一个事务的操作结果要么全部执行要么全部不执行。
一致性表示事务总是从一个一致的状态转换到另一个一致的状态。
隔离性表示一个事务的修改结果在什么时间能够被其他事务看到,
SQL1992规范中对隔离性定义了不同的隔离级别,

四种隔离级别

分为读未提交(READ UNCOMMITED):事务能够看到其他事务没有提及的修改,当另一个事务又回滚了修改后的情况又被称为脏读dirty read。
读已提交(READ COMMITTED):事务能够看到其他事务提交后的修改,这时会出现一个事务内两次读取数据可能因为其他事务提交的修改导致不一致的情况,称为不可重复读。 是sqlserver oracle默认的隔离级别
可重复读(REPEATABLE READ):在两次读取时读取到的数据的状态是一致的。是mysql默认的隔离级别
序列化(SERIALIZABLE):可重复读中可能出现第二次读读到第一次没有读到的数据,也就是被其他事务插入的数据,这种情况称为幻读phantom read, 序列化级别中不能出现幻读。
隔离级别依次增强,但是导致的问题是并发能力的减弱。
MySQL中的InnoDB存储引擎的特性有,默认隔离级别REPEATABLE READ, 行级锁,实现了MVCC, Consistent nonlocking read(默认读不加锁,一致性非锁定读), Insert Buffer, Adaptive Hash Index, DoubleWrite, Cluster Index。
上面列举了这么多,表示InnoDB有很多特性、很快。
InnoDB中通过UndoLog实现了数据的多版本,而并发控制通过锁来实现。
Undo Log除了实现MVCC外,还用于事务的回滚。
Redo log, bin log, Undo log
MySQL Innodb中存在多种日志,除了错误日志、查询日志外,还有很多和数据持久性、一致性有关的日志。
binlog,是mysql服务层产生的日志,常用来进行数据恢复、数据库复制,常见的mysql主从架构,就是采用slave同步master的binlog实现的, 另外通过解析binlog能够实现mysql到其他数据源(如ElasticSearch)的数据复制。
redo log记录了数据操作在物理层面的修改,mysql中使用了大量缓存,缓存存在于内存中,修改操作时会直接修改内存,而不是立刻修改磁盘,当内存和磁盘的数据不一致时,称内存中的数据为脏页(dirty page)。为了保证数据的安全性,事务进行中时会不断的产生redo log,在事务提交时进行一次flush操作,保存到磁盘中, redo log是按照顺序写入的,磁盘的顺序读写的速度远大于随机读写。当数据库或主机失效重启时,会根据redo log进行数据的恢复,如果redo log中有事务提交,则进行事务提交修改数据。这样实现了事务的原子性、一致性和持久性。

Undo Log: 除了记录redo log外,当进行数据修改时还会记录undo log,undo log用于数据的撤回操作,它记录了修改的反向操作,比如,插入对应删除,修改对应修改为原来的数据,通过undo log可以实现事务回滚,并且可以根据undo log回溯到某个特定的版本的数据,实现MVCC。

redo log 和binlog的一致性,为了防止写完binlog但是redo log的事务还没提交导致的不一致,innodb 使用了两阶段提交
大致执行序列为
InnoDB prepare (持有prepare_commit_mutex);
write/sync Binlog;
InnoDB commit (写入COMMIT标记后释放prepare_commit_mutex)。