数据库系列:MySQL慢查询分析和性能优化

数据库系列:MySQL索引优化总结(综合版)

数据库系列:高并发下的数据字段变更

数据库系列:覆盖索引和规避回表

数据库系列:数据库高可用及无损扩容

数据库系列:使用高区分度索引列提升性能

数据库系列:前缀索引和索引长度的取舍

数据库系列:MySQL引擎MyISAM和InnoDB的比较

数据库系列:InnoDB下实现高并发控制

数据库系列:事务的4种隔离级别

1 介绍

上一篇,我们介绍了 SQL92标准中事务的四种隔离级别,并讨论了每种隔离级别下 脏读、不可重复读、幻读 问题是否可以解决:

隔离级别 脏读 不可重复读 幻读
读未提交:Read Uncommitted ×
读已提交:Read Committed × ×
可重复读:Repeatable Read × ×
串行化:Serializable × × ×

在 读已提交(Read Committed) 和 可重复读(Repeatable Read)两种隔离级别上,数据库底层采用了快照读(Snapshot Read)的模式来实现高并发机制。

那RC 和 RR这两种的隔离级别上的快照读(Snapshot Read)有什么区别呢,咱们往下探索?

2 RC 和 RR下快照读的区别

2.1 啥是快照读?

MySQL中InnoDB存储引擎的快照读(Snapshot Read)是一种读取数据的方式,它可以在事务开始时创建一个数据快照,这个快照是一致性的,即读取在事务开始时或特定时间点之前提交的数据。底层原理是MySQL使用多版本并发控制(MVCC)机制来实现快照读。在MVCC中,每个事务读取的数据都是根据事务开始时间点或快照时间点确定的。MySQL通过为每一行数据添加版本信息(如创建版本、删除版本等),来保留历史数据的多个版本。通过一种不加锁一致性读(Consistent Nonlocking Read)的方式来实现高并发的能力。

2.2 RU和Serializable为啥不采用快照读?

  • Serializable是串行化执行,每个步骤都是顺序的,一项事务执行完成才能执行另一项事务,所以没有MVCC 多版本的必要。
  • RU是读未提交,所有未完成的、未最终提交事务都可以被读取到,所以任何有变化的数据都会被读取到,即使是还没有Commit,也没有多版本的必要了。

2.3 读已提交(Read Committed)

  • 事务隔离级别的一种,简称RC
  • 解决了“脏读”问题,保证读取到的所有都是已提交事务的,并最终落库的
  • 可能存在“读幻影行”问题,同一个事务中,前后连续的select可能读到不同的结果集

2.4 可重复读(Repeated Read)

  • 事务隔离级别的一种,简称RR
  • 它不仅解决“脏读”问题,还解决了“读幻影行”的问题,同一个事务里,前后连续的select读到始终相同的结果集

2.5 不同隔离级别下快照读的区别

2.5.1 案例解析1

事务执行顺序如下:

时间序列 A事务 B事务
T1 开始事务
T2 开始事务
T3 查询xx账户余额(假设默认有500元)
★SELECT balance FROM acount WHERE customer_id=123456;
T4 xx账户存入1000元(未提交)
★UPDATE acount SET balance=balance+1000.00 WHERE customer_id=123456;
T5 查询A账户余额
T6 提交事务
★commit;
T7 查询A账户余额
  • Repeated Read 隔离级别

    • T3读到的结果肯定是500,这是B事务的第一个read
    • T5读到的结果也是500,因为A事务还没有提交
    • T7读到的结果还是500,因为A事务是在时间T5之后提交的,T7读到和T5一样的结果(重复读)
  • Read Committed 隔离级别

    • T3读到的结果肯定是500,这是B事务的第一个read
    • T5读到的结果也是500,因为A事务还没有提交
    • T7读到的结果还是1500,因为A事务已经提交,T7读到Commit后的结果(读已提交)

2.5.2 案例解析2

事务执行顺序如下:

时间序列 A事务 B事务
T1 开始事务(假设默认有500元)
T2 开始事务
T3 xx账户存入1000元(未提交)
★UPDATE acount SET balance=balance+1000.00 WHERE customer_id=123456;
T4 提交事务
★commit;
T5 查询A账户余额
★SELECT balance FROM acount WHERE customer_id=123456;
  • Repeated Read 隔离级别:唯一的一次读是在A事务提交之后的读,所以结果肯定是1500
  • Read Committed 隔离级别:读取已提交之后的数据,所以毫无疑问依然是1500

2.6 区别总结

首先,事务总能够读取到自己写入(update /insert /delete)的行记录。而其他事务的提交,则分情况。

RC模式,快照读总是能读到最新的行数据快照,当然,必须是已提交事务写入的。

RR模式,某个事务首次read记录的时间为T1,之后的操作不会读取到T1时间之后已提交事务写入的记录,以保证连续相同的read读到相同的结果集。

简单点说:

  • RR下,事务在第一个Read操作时,会建立Read View,并贯穿整个事务的过程,保证了可重复读的效果。
  • RC下,事务在每次Read操作时,都会建立Read View,以保证获取到的都是数据库中最新的被Commit的值。

数据库系列:RR和RC下,快照读的区别的更多相关文章

  1. RR 和RC 幻读问题

    <pre name="code" class="html">显然 RR 支持 gap lock(next-key lock),而RC则没有gap l ...

  2. mysql rr和rc区别

    <pre name="code" class="html">1. 数据库事务ACID特性 数据库事务的4个特性: 原子性(Atomic): 事务中的 ...

  3. mysql RC下不存在则插入

    mysql版本:5.7 目的:在RC下,name列上仅有key索引,并发插入name时不出现重复数据 RC不加gap lock,并且复合select语句是不加锁的快照读,导致两个事务同时进行都可插入, ...

  4. mysql 快照读MVCC

    mysql的读分快照读和当前读 快照读 是指写的同时,读不阻塞,达到并发的作用 这时候的读 是 记录的历史版本,存在于undo里,当然回滚时就的也是这个undo 当执行一条update语句时,记录本身 ...

  5. InnoDB MVCC RR隔离级别下的数据可见性总结

    一.背景 熟悉数据库隔离级别的人都知道,在RR(可重复读)隔离级别下,无论何时多次执行相同的SELECT快照读语句,得到的结果集都是完全一样的,即便两次SELECT语句执行期间,其他事务已经改变了该查 ...

  6. mysql并发控制之快照读和当前读

    上一篇简单的介绍了下MVCC(多版本并发控制)的原理,MVCC会对事物内操作的数据做多版本控制,从而实现并发环境下事物对数据写操作的阻塞不影响读操作的性能.而这个多版本控制的实现是由undo log来 ...

  7. MySQL--事务隔离级别RR和RC的异同

    在MySQL中,事务隔离级别RC(read commit)和RR(repeatable read)两种事务隔离级别基于多版本并发控制MVCC(multi-version concurrency con ...

  8. RR和RC复合语句加锁

    mysql版本:5.7 RR复合语句: insert/update/delete+select,+号左边是影响数据的排他锁,+号右边是查询(当前读,其实相当于lock in share mode)到数 ...

  9. MySQL——一致性非锁定读(快照读)&MVCC

    MySQL--一致性非锁定读(快照读) MySQL数据库中读分为一致性非锁定读.一致性锁定读 一致性非锁定读(快照读),普通的SELECT,通过多版本并发控制(MVCC)实现. 一致性锁定读(当前读) ...

  10. Windows平台下的读写锁

    Windows平台下的读写锁简单介绍Windows平台下的读写锁以及实现.背景介绍Windows在Vista 和 Server2008以后才开始提供读写锁API,即SRW系列函数(Initialize ...

随机推荐

  1. 《深入理解Java虚拟机》读书笔记:垃圾收集器

    垃圾收集器 HotSpot虚拟机包含的所有收集器如图3-5所示.图3-5展示了7种作用于不同分代的收集器,如果两个收集器之间存在连线,就说明它们可以搭配使用. 新生代收集器:Serial.ParNew ...

  2. Linux 网络发包流程

    哈喽大家好,我是咸鱼 之前咸鱼在<Linux 网络收包流程>一文中介绍了 Linux 是如何实现网络接收数据包的 简单回顾一下: 数据到达网卡之后,网卡通过 DMA 将数据放到内存分配好的 ...

  3. Postgresql 批量插入命令COPY使用

    在很多场景下,我们经常会遇到将某个Excel或Csv文件中的数据,插入到Postgresql.对于这个需求,我们常规的处理办法就是将文件中的数据,按照文件表头名称转换成集合对象然后插入到数据库,当然这 ...

  4. DesignPattern-part1

    title: "modern C++ DesignPattern-Part1" date: 2018-04-03T16:06:33+08:00 lastmod: 2018-04-0 ...

  5. 【译】在 Visual Studio 2022 中安全地在 HTTP 请求中使用机密

    在 Visual Studio 2022 的17.8 Preview 1版本中,我们更新了 HTTP 文件编辑器,使您能够外部化变量,从而使跨不同环境的 Web API 测试更容易.此更新还包括以安全 ...

  6. 【火坑】一切从TimeSpan说起

    小编在编写WPF程序时,需要做一个判断:定时使用Modbus协议使用Quartz.net 定时任务读取设备中的数据,同时也使用定时任务判断是否长时间获取不到数据的情况,如果程序中超过一分钟没有获取到数 ...

  7. Ds100p -「数据结构百题」11~20

    11.P3203 [HNOI2010]弹飞绵羊 某天,\(Lostmonkey\) 发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏. 游戏一开始,\(Lostmonkey ...

  8. 【爬虫笔记】Python爬虫简单运用爬取代理IP

    一.前言 近些年来,网络上的爬虫越来越多,很多网站都针对爬虫进行了限制,封禁了一些不规则的请求.为了实现正常的网络爬虫任务,爬虫常用代理IP来隐藏自己的真实IP,避免被服务器封禁.本文将介绍如何使用P ...

  9. DPDK-22.11.2 [四] Virtio_user as Exception Path

    因为dpdk是把网卡操作全部拿到用户层,与原生系统驱动不再兼容,所以被dpdk接管的网卡从系统层面(ip a/ifconfig)无法看到,同样数据也不再经过系统内核. 如果想把数据再发送到系统,就要用 ...

  10. BGP路由协议学习一

    转载请注明出处: 1.BGP的特点: BGP使用TCP作为其传输层协议(端口号为179),使用触发式路由更新,而不是周期性路由更新. BGP能够承载大批量的路由信息,能够支撑大规模网络. BGP提供了 ...