大家好,我是安小生,本节文章说的是事务的隔离级别IO
1,事物隔离级别类型介绍,
读取未提交,简称:RU。 没有隔离性,所以在隔离级别中的性能是最好ode。
脏读:指的是读到了其他事物提交的数据。即使是未提交
读取已提交,简称:RC。 性能相对而言比读取未提交要低。
不可重复读:一致性。 性能相对而言比读取已提交要低。
可重复读取,简称: RR(默认)。
幻读的问题:mvc 但是对于新增来时候可能依然存在。
串行化:原本是多进程:强行转化为单进程。 在性能方面是最低的。但是解决的问题是最多的。
总结:从上往下依次降低,隔离级别的强度依次增强。
下面我们有一个图来进行解释:
- 读取未提交(READ UNCOMMITTED)
- 读取已提交 (READ COMMITTED)
- 可重复读 (REPEATABLE READ)
-
串行化 (SERIALIZABLE)
隔离级别.png
-
串行化与读取未提交。
读取未提交:不可重复读,幻读问题。
解决问问题:没有使用事物的时候数据不一致的问题,就是做到知行的sql一起成功,一起回滚。
脏读:可以读取到其他事物所知行的sql的结果=》脏读
假设事物1要进行回滚操作,事务
读取未提交以及串行话不在我们权衡以及考虑的范围,。
读取未提交-脏读问题
MySQL 事务隔离其实是依靠锁来实现的,加锁自然会带来性能的损失。而读未提交隔离级别是不加锁的, 所以它的性能是最好的,没有加锁、解锁带来的性能开销。但有利就有弊,这基本上就相当于裸奔啊,所 以它连脏读的问题都没办法解决。任何事务对数据的修改都会第一时间暴露给其他事务,即使事务还没有 提交。
读取已提交-不可重复读问题
既然读未提交没办法解决脏数据问题,那么就有了读提交。读提交就是一个事务只能读到其他事务已经提交过的数据,也就是其他事务调用 commit 命令之后的数据。那脏数据问题迎刃而解了。 读提交事务隔离级别是大多数流行数据库的默认事务隔离界别,比如 Oracle,但是不是 MySQL 的默认隔离界别。
可重复读取与串行化
可重复读取-幻读问题
可重复是对比不可重复而言的,上面说不可重复读是指同一事物不同时刻读到的数据值可能不一致。而可 重复读是指,事务不会读到其他事务对已有数据的修改,及时其他事务已提交,也就是说,事务开始时读 到的已有数据是什么,在事务提交前的任意时刻,这些数据的值都是一样的。但是,对于其他事务新插入 的数据是可以读到的,这也就引发了幻读问题。
串行化
串行化是4种事务隔离级别中隔离效果最好的,解决了脏读、可重复读、幻读的问题,但是效果最差,它将 事务的执行变为顺序执行,与其他三个隔离级别相比,它就相当于单线程,后一个事务的执行必须等待前 一个事务结束。
事务隔离级别的实现
首先说读未提交,它是性能最好,也可以说它是最野蛮的方式,因为它压根儿就不加锁,所以根本谈不上 什么隔离效果,可以理解为没有隔离。
再来说串行化。读的时候加共享锁,也就是其他事务可以并发读,但是不能写。写的时候加排它锁,其他 事务不能并发写也不能并发读。
最后说读提交和可重复读。这两种隔离级别是比较复杂的,既要允许一定的并发,又想要兼顾的解决问
- 实现可重复读取
为了解决不可重复读,或者为了实现可重复读,MySQL 采用了 MVVC (多版本并发控制) 的方式。
我们在数据库表中看到的一行记录可能实际上有多个版本,每个版本的记录除了有数据本身外,还要有一 个表示版本的字段,记为 row trx_id,而这个字段就是使其产生的事务的 id,事务 ID 记为 transaction id, 它在事务开始的时候向事务系统申请,按时间先后顺序递增。
事务与IO的关系

- innodb_flush_log_at_trx_commit=0,innodb中的log thread每隔一秒钟将会log buffer中的数据写入文 件,同时还会通知文件系统进行与文件同步的flush操作,保证数据确实已经写入磁盘。但是,每次事 务的结束(commit或者rollback)并不会触发log thread将log buffer中的数据写入文件。所以当设置为 0时候,在mysql crash或者oscrash或者主机断电的情况,最极端的情况是丢失一秒的数据变更。
- innodb_flush_log_at_trx_commit=1,这也是innodb默认设置,每次事务的结束都会触发log thread将log buffer中的数据写入文件,并通知文件系统同步文件。这个设置是最安全的,能够保证不论是mysql crash,os crash还是主机断电都不会丢失任何已经提交的事务。
- innodb_flush_log_at_trx_commit=2,log thread会在每次事务结束后将数据写入事务日志,但是仅仅是调 用了文件系统的写入操作,而文件系统都是有缓存的,所以log thread的写入并不能保证将文件系统中 缓存写入到物理磁盘进行永久固化。文件系统什么时候将缓存中的数据同步到物理磁盘,log thread 并 不知道。所以当设置为2的时候,mysql 的吵嚷声并不会造成数据的丢失,但是os crash或者主机断电 可能造成事务日志的丢失,各种文件系统对文件缓存的刷新机制各不相同。
总结
从以上的分析得出,当innodb_flush_log_at_trx_commit设置为1时是最安全的,但由于所作的io同步操作最 多,性能也是三种当中最差的;如果设置为0,则每秒同步一次,性能相对高些,如果设置为2,性能可能 是这三种中最好的,但也有可能会出现故障后丢失的数据最多的。至于具体应该如何设置,一般来说,如 果不能完全接受数据的丢失,那可以通过牺牲一定的性能来换取数据的安全性,选择设置为1,如果允许丢 失少量的数据(比如说1秒内),那么设置为0,当然如果操作系统够稳定,主机的硬件设备足够好的话, 而且主机的供电系统也足够安全的话,那么可以将innodb_flush_log_at_trx_commit=2,保证系统的高性能。
网友评论