mysql事务

什么是ACID?

原子性

要保证事务的原子性,事务要么全部成功,要么全部失败。

一致性

根据定义,一致性是指事务执行前后,数据处于一种合法的状态,这种状态是语义上的而不是语法上的。
那什么是合法的数据状态呢?
比如性别约束男or女;人民币面值不能为负数;出生地址不能为null;等等

隔离性

在修改数据库时产生的所并发事务都是隔离,事务与事务之间都是独立的,相互不会造成影响。

持久性

事务完成以后,数据将永远的保存在磁盘上。事务日志可以保证事务的永久性

事务并发执行时数据一致性问题有哪些?

在这里插入图片描述

脏写

就是有两个事务对相同的一条数据进行了修改
1.第一个事务把id=1的值从0修改成了1
2.第二个事务把id=1的值也把0修改成了1
3.这时第一个事务回滚把id=1的值会滚为了0
这样就导致了数据问题这种情况称为脏写

脏读

在这里插入图片描述

不可重复读

在这里插入图片描述

幻读

在这里插入图片描述

mysql的日志介绍

redo log(重做日志)

介绍
  1. redo log是InnoDB存储引擎层的日志,又称重做日志文件,用于记录事务操作的变化,记录的是数据修改之后的值,不管事务是否提交都会记录下来。
  2. 在一条更新语句进行执行的时候,InnoDB引擎会把更新记录写到redo log日志中,然后更新内存,此时算是语句执行完了,然后在空闲的时候或者是按照设定的更新策略将redo log中的内容更新到磁盘中
作用
  1. 确保事务的持久性。防止在发生故障的时间点,尚有脏页未写入磁盘。
  2. 在重启mysql服务的时候,根据redo log进行重做,从而达到事务的持久性这一特性

undo log(回滚日志)

介绍
  1. 一般是逻辑日志,根据每行记录进行记录。
  2. undo用来回滚行记录到某个版本。
  3. 当事务对数据库进行修改的时候,InnoDB会生成对应的undo log ;如果此时事务执行失败或者调动了 rollback,导致事务出现回滚情况,可以利用undo log中的信息将数据回滚到修改前的样子,从而达到了事务的原子性
作用
  1. 保存了事务发生之前的数据的一个版本,可以用于回滚
  2. 同时可以提供多版本并发控制下的读(MVCC),也即非锁定读
  3. 在一条insert语句在回滚时候会执行delete
  4. 在一条delete语句在回滚的时候会执行一条insert语句
  5. 在一条update语句回滚的时候相对应的执行一条update语句。把值修改为原来的久值

binlog(二进制日志)

介绍
  1. binlog记录了数据库当中所有的变更操作。用二进制的数据保存在binlog文件当中
作用
  1. 它可以用来查看数据库变更历史,以及数据量的增量备份和恢复,mysql的主从复制。

MVCC&ReadView

  1. MVCC:多版本并发控制器,利用记录的版本链和ReadView来实现在并发事务在访问相同数据时的行为
  2. ReadView:一致性视图,用来判断当前事务对那个版本链的数据是可见的。

版本链

在这里插入图片描述
在每次更新之后,就会把更新之前的旧值记录在undolog中。随着更新的次数增多,所有的版本都会通过roll-pointer属性连接成为一个链表,这样的链表被称之为版本链。

ReadView包含了什么

在这里插入图片描述

  1. m_ids:在生成ReadView的时候,当前系统中活跃的读写事务ids。
  2. mix_trx_id:在生成ReadView的时候,当前系统活跃的读写事务的最小事务id。
  3. max_trx_id:在生成ReadView的时候,分配给下一个事务的事务id的值.
  4. creator_trx_id:生成ReadView的创建事务id

如何通过ReadView来判断记录的某个版本是否可见?

在这里插入图片描述

  1. 如果 trx_id == creator_trx_id 的时候表明当前的事务在访问自己修改的数据,该版本的数据是可见的
  2. 如果 trx_id < min_trx_id 的时候说明在生成该版本的ReadView的时候当前事务已经提交了,该版本的数据是可见的
  3. 如果 trx_id <= max_trx_id 的时候表明该事务是在当前事务生成ReadView之后在开启的说明不能访问改版本的数据是不可以见的
  4. 如果 trx_id in m_ids 的时候说明在创建ReadView的时候当前事务是活跃的该版本数据是不可见的。
  5. 如果 trx_id not in m_ids 的时候说明在创建ReadView的时候当前事务是已经提交了的该版本的数据是可见的。

实战阶段

问题一:Mysql怎么保证原子性?

mysql是通过undo日志来保证事务的原子性的关键。在mysql对数据库进行修改的时候,会在undo日志里面记录一条数据,在事务回滚的时候,通过记录来实现回滚的。比如:

  1. 当你insert一条数据的时候,事务回滚,那么会根据undo日志执行一条delete的语句把新增的数据给删除掉
  2. 当你delete一条数据的时候,事务回滚,那么会根据undo日志执行一条insert语句把原来的旧值给加上去
  3. 当你upate数据的时候,事务回滚,那么会根据undo日志执行一条对应的update语句吧值修改为原来的值
问题二:Mysql怎么保证一致性?

分两个层面来说:
第一个层面从数据库维度来说:在原子性,一致性,隔离性,持久性当中一致性是最终的目标,原子性,隔离性,持久性是手段。是为了保证一致性,数据库提供的手段。数据库要保证原子性,隔离性,持久性才能保证一致性。
第二个层面是从应用层的维度来说:就是要如何保证分布式事务的一致性?(不再过多的说了不然又是一篇文章)

  • 基于XA协议的强一致性事务方案
  • 基于base原理的最终一致性事务方案
问题三:Mysql怎么保证持久性?

mysql是通过redo日志来实现持久性的。在mysql数据库当中,数据库的数据被修改之后,会先把更新的记录的写入到redo日志里面,然后把数据写入到buff pool里面,最后根据数据库自身的策略把buff pool里面的脏数据写入磁盘。
在数据库宕机重启之后也可以通过redo日志来恢复数据这就保证了持久性。

问题四:Mysql怎么保证隔离性?

是通过MVCC(多版本并发控制器来)和锁机制来实现的

  1. (一个事务)写操作对(另一个事务)写操作的影响:锁机制保证隔离性
  2. (一个事务)写操作对(另一个事务)读操作的影响:MVCC保证隔离性
问题五:InnoDB 如何避免了幻读现象。

InnoDB默认是RR,RR是通过mvcc(多版本并发控制器)+next-key lock机制避免了幻读现象。mvcc是解决了普通读(快照读)的幻读情况,next-key lock是解决了当前读的幻读情况
注意:普通读就是我们平时常用的select语句,当前读的话是select … for update,select…in share mode等等

当前读

next-key lock是由record lock(行记录锁) + gap lock(间隙锁)组成的。其特点是不但可以锁住数据本身(行记录锁的功能)还可以锁定一个范围(间隙锁的功能)。

普通读

上面介绍mvcc和ReadView的时候已经详细的说明如何解决多事务并发来判断记录的某个版本是否可见的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值