MySQL事物以及MVCC

一、事物四大特性

  • 原子性:事物是不可分割的,要么都完成,要么都不完成
  • 一致性:事物从一种状态到下一种一致性状态,事物完成前后都不能破坏数据库的完整性约束
  • 隔离性:并发下,存在多个数据对同一数据进行操作,多个事物应该互相隔离,不可见,防止数据混乱。
  • 持久化:当事物提交后,对数据库的操作是永久的,事物提交后数据库崩溃,那么数据库恢复时应恢复到提交后的数据

二、并发下数据读取存在问题

  • 脏读:一个事物可以读取到其他事物未提交的数据
  • 不可重复读:一个事物对同一数据多次读取,读取的结果不一致,其他事物对这一数据进行了修改。
  • 幻读:一个事物多次对一个范围进行查询,后面查询比前一次查询的多了几条数据。

三、事物隔离级别

  • 未提交读:事物可以读取到其他事物未提交的数据,存在脏读、不可重复读、幻读等问题
  • 提交读:事物只能读取到其他事物已经提交的数据,存在不可重复读、幻读的问题。
  • 重复读:事物对同一数据可以重复读取,存在幻读的问题。MVVC中快照读不存在幻读,幻读存在当前读。
  • 串行:one by one的读取,不存在脏读、重复读、幻读的问题

四、什么是MVCC

MVCC是多版本并发控制,一般解决读写冲突,我们采用加锁的形式,MVCC不需要加锁解决读写冲突。
为了实现MVCC,会在每一行的记录加上3个隐藏的字段:

  • 行id(主键存在时,不会创建),
  • 事物id
  • 回滚指针

当我们的隔离级别为RR(可重复读),每开启一个事物,系统会分配一个事物id,当事物第一次调用select语句时会生成ReadView快照。ReadView有几个重要的属性:

  • 事物id列表:记录当前未提交的事物id,顺序列表
  • 高水位:分配给下一个事物的id
  • 低水位:对应事物id列表中最小的事物的id
  • 创建该列表的事物id

undo log记录各个数据版本的事物id,比较时拿到的是最新版本,通过比较事物id判断是否能访问,不能访问通过回滚指针找到前面的版本,如此进行比较:

  • 当访问的事物id小于低水位时,说明该事物已经提交可以访问。
  • 当访问的事物id和自身相同,说明是事物本身修改的数据,可以访问
  • 当访问的事物id大于低水位小于高水位,判断事物id是存在,存在则说明事物还未提交,不能访问,不存在说明事物已经提交可以访问
  • 当访问的事物id大于高水位,说明事物是在之后创建,不能访问。

更新数据时会先加锁,然后写undo log,将原来的数据行写入undo log中,创建新的数据行,记录事物id,回滚指针指向原数据行。写完undo log后会写redo log,事物id以及指针和undo的那部分相同。处理完毕后,解锁。

五、快照读和当前读

  • 快照读:RR隔离级别,事物第一次读取(普通的select语句)时生成ReadView快照,之后的读取都使用该快照。RC级别的每次select都生成一个快照。RR级别下天然无幻读。
  • 当前读:除了普通的select语句读取。其他的像select … for update,select … lock in share mode都是当前读,读取当前最新版本,此外insert/update/delete也会读取最新记录,RR级别下MySQL默认开启临建锁来解决幻读问题。

六、InnoDB二段提交

为什么使用二段提交?

  • 写先redo log后写bin log,如果写完redo log后宕机,那么主库会把写入的数据恢复,从库并未接收到这条数据,导致主从数据不一致
  • 写先bin log 后写redo log,如果写完bin log后宕机了,当么主库会回滚,从库接收的bin log日志比主库多了一条记录,导致主从数据不一致。

二段提交保证了主从数据的一致性,MySQL二段提交是在InnoDB存储引擎上(redo log属于InnoDB,bin log属于server层,每个存储引擎都拥有),当数据刷盘的时候,会先写redo log日志,为prepare(准备)阶段,同时记录事物id,写完redo log日志后,会写bin log日志同时记录事物id,写完后将redo log的状态改为commit。

  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值