『MySQL 实战 45 讲』20 - 幻读是什么,幻读有什么问题?

news2024/12/24 8:07:27

幻读是什么,幻读有什么问题?

  1. 需求:创建一个小表
CREATE TABLE `t` (
  `id` int(11) NOT NULL,
  `c` int(11) DEFAULT NULL,
  `d` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `c` (`c`)
) ENGINE=InnoDB;

insert into t values(0,0,0),(5,5,5),
(10,10,10),(15,15,15),(20,20,20),(25,25,25);

幻读是什么?

  1. 幻读指的是一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行
  2. 幻读说明:
  • 在可重复读隔离级别下,普通的查询是快照读,是不会看到别的事务插入的数据的。因此,幻读在“当前读”下才会出现

幻读有什么问题?

  1. 语义上会被破坏
  2. 产生数据不一致性

幻读带来的问题分析

  1. 假设需要对 id=5 这一行加锁,其他行不加锁(这个是个假设场景)
    在这里插入图片描述
  • T1 时刻,Q1 只返回 id=5 这一行(因为假设只锁一行)
  • T2 时刻,session B 把 id=0 这一行的 d 值改成了 5,因此 T3 时刻 Q2 查出来的是 id=0 和 id=5 这两行
  • T4 时刻,session C 又插入一行(1,1,5),因此 T5 时刻 Q3 查出来的是 id=0、id=1 和 id=5 的这三行
  1. 其中因为当前读,session C 新插入的行被 session A 看到了,这就是幻读
  2. 问题一:语义被破坏
  • 实际上,session A 在 T1 时刻,就要求锁住 d=5 的行。由于只锁住 id=5 这一行,T2 时刻 session B 是可以执行 2 条 update 语句,破坏了 Q1 的声明(session C 同理)
  1. 问题二:数据一致性问题(数据和日志在逻辑上的一致性)
    在这里插入图片描述
  • 执行逻辑:
    • T1 时刻:id=5 这一行变成 (5,5,100),当然这个结果最终是在 T6 时刻正式提交的
    • T2 时刻,id=0 这一行变成 (0,5,5)
    • T4 时刻,表里面多了一行 (1,5,5)
  • 对应 binlog 里面的内容:
update t set d=5 where id=0; /*(0,0,5)*/
update t set c=5 where id=0; /*(0,5,5)*/

insert into t values(1,1,5); /*(1,1,5)*/
update t set c=5 where id=1; /*(1,5,5)*/

update t set d=100 where d=5;/*所有d=5的行,d改成100*/
  • binlog 语句序列问题
    • 不论是拿到备库去执行,还是以后用 binlog 来克隆一个库,这三行的结果,都变成了 (0,5,100)、(1,5,100) 和 (5,5,100)
    • id=0 和 id=1 这两行,发生了数据不一致
    • 引起该问题的是 for update 只给 d=5 这行加锁
  • 解决 binlog 语句序列问题:
    在这里插入图片描述
  • 执行逻辑:
    • session A 把所有的行都加了写锁,session B 在执行第一个 update 就会被锁住,只有 T6 时刻 session A 提交以后,session B 才能继续执行
    • 新的 binlog 日志执行顺序如下
insert into t values(1,1,5); /*(1,1,5)*/
update t set c=5 where id=1; /*(1,5,5)*/

update t set d=100 where d=5;/*所有d=5的行,d改成100*/

update t set d=5 where id=0; /*(0,0,5)*/
update t set c=5 where id=0; /*(0,5,5)*/
  • 虽然 session B 更新的问题已经解决,但是 session C 插入时,id=1 这一行还不存在,不存在也就加不上锁。也就是说,即使把所有的记录都加上锁,还是阻止不了新插入的记录

如何解决幻读?

  1. 为了解决幻读问题,InnoDB 只好引入新的锁,也就是间隙锁
  2. 实际上,开头的表 t,初始化插入了 6 个记录,这就产生了 7 个间隙

极客时间版权所有: https://time.geekbang.org/column/article/75173
3. 当执行 select * from t where d=5 for update 的时候,6 个记录加上了行锁,还同时加了 7 个间隙锁,这样就确保无法再插入新的记录
4. 注意:跟间隙锁存在冲突关系的,是“往这个间隙中插入一个记录”这个操作
在这里插入图片描述

  • 这里 session B 并不会被堵住,因为表 t 里并没有 c=7 这个记录,因此 session A 加的是间隙锁 (5,10)
  1. 间隙锁和行锁合称 next-key lock,每个 next-key lock 是前开后闭区间
  • 如果用 select * from t for update 要把整个表所有记录锁起来,就形成了 7 个 next-key lock,分别是 (-∞,0]、(0,5]、(5,10]、(10,15]、(15,20]、(20, 25]、(25, +supremum]
  1. 间隙锁和 next-key lock 的引入,解决了幻读的问题,但同时也带来了一些问题
  • 例如下面这个逻辑
begin;
select * from t where id=N for update;

/*如果行不存在*/
insert into t values(N,N,N);
/*如果行存在*/
update t set d=N set id=N;

commit;
  • 一旦有并发,就有可能死锁
    在这里插入图片描述
  • 执行逻辑
    • session A 执行 select … for update 语句,由于 id=9 这一行并不存在,因此会加上间隙锁 (5,10)
    • session B 执行 select … for update 语句,同样会加上间隙锁 (5,10),间隙锁之间不会冲突,因此这个语句可以执行成功
    • session B 试图插入一行 (9,9,9),被 session A 的间隙锁挡住了,只好进入等待
    • session A 试图插入一行 (9,9,9),被 session B 的间隙锁挡住了
  • 间隙锁的引入,可能会导致同样的语句锁住更大的范围,这其实是影响了并发度的
  1. 间隙锁是在可重复读隔离级别下才会生效的
  • 如果把隔离级别设置为读提交的话,就没有间隙锁了
  • 解决可能出现的数据和日志不一致问题,需要把 binlog 格式设置为 row
    • binlog row 记录的不是 sql,和 sql 顺序无关,不会导致主从数据不一致

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1653558.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度解析互联网医疗源码:视频问诊APP开发技术剖析

视频问诊APP作为在线医疗其中的重要一环,正在改变人们就医的方式。今天,我将为大家详解互联网医疗源码,探讨视频问诊APP开发技术,揭示其背后的原理和关键技术。 一、视频问诊APP的基本功能 视频问诊APP作为一种新型的医疗服务平台…

栈和队列的4道面试题【详细解析】【代码实现】

栈和队列的面试题 1.有效的括号(栈实现) 题目: 有效的括号 给定一个只包括 (,),{,},[,] 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必…

C++关键字、命名空间、输入输出

一、C C是在C的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式等。 二、C关键字 C关键字有些是C语言中原带的,也有一些是C本身的关键字,对于这些关键字,大家只需在学习过程中去理…

2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷1(私有云)

#需要资源(软件包及镜像)或有问题的,可私聊博主!!! #需要资源(软件包及镜像)或有问题的,可私聊博主!!! #需要资源(软件包…

C++之泛型编程---有限双端队列结构容器

引言 为了解决工业领域代码容器的通用化,可以考虑C里的泛型编程概念。假设一个场景需要实时保存最近的n个数据并按照顺序依次处理时,就需要定义一种新的容器来满足要求。当容器不满时,添加数据直接到队尾,当容器数据已经为n个时&a…

onlyoffice容器打包成镜像

书接上篇,onlyoffice容器已经更改在本地docker环境中了,之后需要部署到测试环境的docker中,采用容器打包成本地镜像 1、本地docker 查看容器:docker ps 生成镜像:docker commit -p blissful_lichterman 重命名镜像&a…

博睿数据将出席ClickHouse Hangzhou User Group第1届 Meetup

2024年5月18日,博睿数据数智能力中心负责人李骅宸将受邀参加ClickHouse Hangzhou User Group第1届 Meetup活动,分享《ClickHouse在可观测性的应用实践和优化》的主题演讲。 在当前数字化浪潮下,数据的规模和复杂性不断攀升,如何高…

Sam Altman 在斯坦福大学演讲的 10 个要点

最近在斯坦福大学举行的问答环节中,OpenAI 富有远见的首席执行官 Sam Altman 分享了关于人工智能的未来及其对社会的潜在影响的宝贵见解。作为 GPT 和 DALL-E 等突破性人工智能模型背后的研究组织的联合创始人,Altman 的观点对于企业家、研究人员以及任何…

uniapp+vue基于移动端的药品进销存系统r275i

最后我们通过需求分析、测试调整,与药品进销存管理系统管理系统的实际需求相结合,设计实现了药品进销存管理系统管理系统。 系统功能需求包含业务需求、功能需求用户需求,系统功能需求分析是在了解用户习惯、开发人员技术和实力等各个因素的前…

蓝鹏在线测宽仪有多少个常用系列?

蓝鹏测控专注几何尺寸智能测量仪的生产,其产品线丰富多样,测量仪涵盖了外径、椭圆度、螺纹钢肋高、直线度、宽度、厚度、边长、长度等各类几何尺寸,在线测宽仪主要应用于板材类产品的宽度尺寸检测。 在线测宽仪硬件技术与软件技术相结合&am…

第1章. STM32单片机入门知识介绍

目录 0. 《STM32单片机自学教程》专栏 1.1 嵌入式系统简介 1.1.1 什么是嵌入式系统 1.1.2 嵌入式系统的特点 1.1.3 嵌入式系统的应用领域 1.2 单片机基本概念 1.3 ARM简介 1.3.1 ARM公司简介 1.3.2 ARM处理器简介 1.4 STM32简介 1.4.1 基于Cortex内核的MCU 1.4.…

解析直播美颜SDK:计算机视觉在实时视频中的应用

今天,小编将带大家深入探讨直播美颜SDK的原理、应用及其在实时视频中的重要性。 一、直播美颜SDK的原理 直播美颜SDK的核心原理是基于计算机视觉技术,通过识别人脸、肤色、眼睛、嘴巴等关键特征点,对视频图像进行实时处理。其主要包括以下几…

【FFmpeg】Filter 过滤器 ① ( FFmpeg 过滤器简介 | 过滤器概念 | 过滤器用法 | 过滤器工作流程 | 过滤器文档 | 过滤器分类 )

文章目录 一、FFmpeg 过滤器 Filter 简介1、FFmpeg 过滤器概念2、FFmpeg 过滤器用法3、FFmpeg 过滤器工作流程4、FFmpeg 过滤器文档 二、FFmpeg 过滤器 分类1、过滤器分类 - 根据处理数据类型分类2、过滤器分类 - 根据编码器位置分类3、过滤器分类 - 根据功能分类 FFmpeg 相关文…

常见C语言基础笔试题

一. 简介 整理一些C语言常见的基础笔试题。 二. 常见C语言基础笔试题 1. 结构体指针加 1 结构体指针加 1操作&#xff1a; #include <stdio.h> #include <stdlib.h>typedef struct tagDev_INFO_S{int a;int b;int c;int d; } DEV_INFO_S;int main(void) { D…

力扣-21. 合并两个有序链表-js实现

/*** Definition for singly-linked list.* function ListNode(val, next) {* this.val (valundefined ? 0 : val)* this.next (nextundefined ? null : next)* }*/ /*** param {ListNode} list1* param {ListNode} list2* return {ListNode}*/ const mergeTwoList…

LeetCode 面试题 17.14 —— 最小 k 个数

阅读目录 1. 题目2. 解题思路一3. 代码实现一4. 解题思路二5. 代码实现二 1. 题目 2. 解题思路一 第一种方法就是利用快速排序&#xff0c;第一次排序后&#xff0c;数组被划分为了左右两个区间 [ 0 , i ] , [ i 1 , a r r . s i z e ( ) − 1 ] [0, i], [i1, arr.size()-1]…

【vue+vue-treeselect】根据指定字段,如isLeaf(是否末级节点),设置只允许末级节点可以选

1、当项目有特殊要求&#xff0c;必须根据某个字段的值去判断&#xff0c;是否节点可以选&#xff0c;即使已经是末级节点了&#xff0c;还是需要根据字段判断是否禁用 &#xff08;1&#xff09; :flat"true"一定要设置 (2)获取数据源的时候&#xff0c;设置下禁用…

制造业为什么需要质量管理系统

质量管理是一个企业最重要的核心竞争力之一。为了确保产品和服务的高质量&#xff0c;企业需要建立一个完善的质量管理体系。而质量管理系统&#xff08;QMS&#xff09;正是指导企业如何规范、组织和管理质量相关活动的框架和流程。 在智能制造时代&#xff0c;广大企业如何结…

数组中两个字符串的最小距离

给定一个字符串数组strs&#xff0c;再给定两个字符串str1和str2&#xff0c;返回在strs中str1和str2的最小距离&#xff0c;如果str1或str2为null&#xff0c;或不在strs中&#xff0c;返回-1。 输入描述&#xff1a; 输入包含有多行&#xff0c;第一输入一个整数n(1 ≤ n ≤…

苹果平板HOME键成历史,全面屏时代到来?2024平板电脑市场趋势分析

近期苹果公司在“放飞吧”发布会上推出了新款iPad Pro和iPad Air平板电脑&#xff0c;并下架了最后一款带有实体Home按键的iPad 9。这一变化标志着Home键在苹果iPad产品线中成为了历史&#xff0c;引起了不少网友的怀念和感慨。 与此同时&#xff0c;今年3月线上平板电脑市场迎…